1
The following changes since commit e5cd695266c5709308aa95b1baae499e4b5d4544:
1
First pullreq for arm of the 4.1 series, since I'm back from
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...
2
6
3
Merge remote-tracking branch 'remotes/cody/tags/block-pull-request' into staging (2018-05-08 17:05:58 +0100)
7
thanks
8
-- PMM
9
10
The following changes since commit 413a99a92c13ec408dcf2adaa87918dc81e890c8:
11
12
Add Nios II semihosting support. (2019-04-29 16:09:51 +0100)
4
13
5
are available in the Git repository at:
14
are available in the Git repository at:
6
15
7
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180510
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190429
8
17
9
for you to fetch changes up to 9a9f1f59521f46e8ff4527d9a2b52f83577e2aa3:
18
for you to fetch changes up to 437cc27ddfded3bbab6afd5ac1761e0e195edba7:
10
19
11
target/arm: Clear SVE high bits for FMOV (2018-05-10 18:10:58 +0100)
20
hw/devices: Move SMSC 91C111 declaration into a new header (2019-04-29 17:57:21 +0100)
12
21
13
----------------------------------------------------------------
22
----------------------------------------------------------------
14
target-arm queue:
23
target-arm queue:
15
* hw/arm/iotkit.c: fix minor memory leak
24
* remove "bag of random stuff" hw/devices.h header
16
* softfloat: fix wrong-exception-flags bug for multiply-add corner case
25
* implement FPU for Cortex-M and enable it for Cortex-M4 and -M33
17
* arm: isolate and clean up DTB generation
26
* hw/dma: Compile the bcm2835_dma device as common object
18
* implement Arm v8.1-Atomics extension
27
* configure: Remove --source-path option
19
* Fix some bugs and missing instructions in the v8.2-FP16 extension
28
* hw/ssi/xilinx_spips: Avoid variable length array
29
* hw/arm/smmuv3: Remove SMMUNotifierNode
20
30
21
----------------------------------------------------------------
31
----------------------------------------------------------------
22
Igor Mammedov (4):
32
Eric Auger (1):
23
pc: simplify MachineClass::get_hotplug_handler handling
33
hw/arm/smmuv3: Remove SMMUNotifierNode
24
platform-bus-device: use device plug callback instead of machine_done notifier
25
arm/boot: split load_dtb() from arm_load_kernel()
26
make sure that we aren't overwriting mc->get_hotplug_handler by accident
27
34
28
Peter Maydell (3):
35
Peter Maydell (28):
29
hw/arm/iotkit.c: fix minor memory leak
36
hw/ssi/xilinx_spips: Avoid variable length array
30
softfloat: Handle default NaN mode after pickNaNMulAdd, not before
37
configure: Remove --source-path option
31
atomic.h: Work around gcc spurious "unused value" warning
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
32
64
33
Richard Henderson (14):
65
Philippe Mathieu-Daudé (13):
34
tcg: Introduce helpers for integer min/max
66
hw/dma: Compile the bcm2835_dma device as common object
35
target/arm: Use new min/max expanders
67
hw/arm/aspeed: Use TYPE_TMP105/TYPE_PCA9552 instead of hardcoded string
36
target/xtensa: Use new min/max expanders
68
hw/arm/nseries: Use TYPE_TMP105 instead of hardcoded string
37
tcg: Introduce atomic helpers for integer min/max
69
hw/display/tc6393xb: Remove unused functions
38
tcg: Use GEN_ATOMIC_HELPER_FN for opposite endian atomic add
70
hw/devices: Move TC6393XB declarations into a new header
39
target/riscv: Use new atomic min/max expanders
71
hw/devices: Move Blizzard declarations into a new header
40
target/arm: Introduce ARM_FEATURE_V8_ATOMICS and initial decode
72
hw/devices: Move CBus declarations into a new header
41
target/arm: Fill in disas_ldst_atomic
73
hw/devices: Move Gamepad declarations into a new header
42
target/arm: Implement CAS and CASP
74
hw/devices: Move TI touchscreen declarations into a new header
43
target/arm: Enable ARM_FEATURE_V8_ATOMICS for user-only
75
hw/devices: Move LAN9118 declarations into a new header
44
target/arm: Implement vector shifted SCVF/UCVF for fp16
76
hw/net/ne2000-isa: Add guards to the header
45
target/arm: Implement vector shifted FCVT for fp16
77
hw/net/lan9118: Export TYPE_LAN9118 and use it instead of hardcoded string
46
target/arm: Fix float16 to/from int16
78
hw/devices: Move SMSC 91C111 declaration into a new header
47
target/arm: Clear SVE high bits for FMOV
48
79
49
accel/tcg/atomic_template.h | 112 ++++++----
80
configure | 10 +-
50
accel/tcg/tcg-runtime.h | 8 +
81
hw/dma/Makefile.objs | 2 +-
51
hw/ppc/e500.h | 5 +
82
include/hw/arm/omap.h | 6 +-
52
include/hw/arm/arm.h | 45 +++-
83
include/hw/arm/smmu-common.h | 8 +-
53
include/hw/arm/sysbus-fdt.h | 37 +---
84
include/hw/devices.h | 62 ---
54
include/hw/arm/virt.h | 1 +
85
include/hw/display/blizzard.h | 22 ++
55
include/hw/i386/pc.h | 8 -
86
include/hw/display/tc6393xb.h | 24 ++
56
include/hw/platform-bus.h | 4 +-
87
include/hw/input/gamepad.h | 19 +
57
include/qemu/atomic.h | 2 +-
88
include/hw/input/tsc2xxx.h | 36 ++
58
target/arm/cpu.h | 1 +
89
include/hw/misc/cbus.h | 32 ++
59
target/arm/helper-a64.h | 2 +
90
include/hw/net/lan9118.h | 21 +
60
target/arm/helper.h | 4 +-
91
include/hw/net/ne2000-isa.h | 6 +
61
tcg/tcg-op.h | 50 +++++
92
include/hw/net/smc91c111.h | 19 +
62
tcg/tcg.h | 8 +
93
include/qemu/typedefs.h | 1 -
63
fpu/softfloat.c | 52 +++--
94
target/arm/cpu.h | 95 ++++-
64
hw/arm/boot.c | 72 ++-----
95
target/arm/helper.h | 5 +
65
hw/arm/iotkit.c | 1 +
96
target/arm/translate.h | 3 +
66
hw/arm/sysbus-fdt.c | 64 +-----
97
hw/arm/aspeed.c | 13 +-
67
hw/arm/virt.c | 96 ++++++---
98
hw/arm/exynos4_boards.c | 3 +-
68
hw/core/platform-bus.c | 29 +--
99
hw/arm/gumstix.c | 2 +-
69
hw/i386/pc.c | 7 +-
100
hw/arm/integratorcp.c | 2 +-
70
hw/ppc/e500.c | 38 ++--
101
hw/arm/kzm.c | 2 +-
71
hw/ppc/e500plat.c | 32 +++
102
hw/arm/mainstone.c | 2 +-
72
hw/ppc/spapr.c | 1 +
103
hw/arm/mps2-tz.c | 3 +-
73
hw/s390x/s390-virtio-ccw.c | 1 +
104
hw/arm/mps2.c | 2 +-
74
linux-user/elfload.c | 1 +
105
hw/arm/nseries.c | 7 +-
75
target/arm/cpu64.c | 1 +
106
hw/arm/palm.c | 2 +-
76
target/arm/helper-a64.c | 43 ++++
107
hw/arm/realview.c | 3 +-
77
target/arm/helper.c | 53 ++++-
108
hw/arm/smmu-common.c | 6 +-
78
target/arm/translate-a64.c | 490 +++++++++++++++++++++++++++++++++-----------
109
hw/arm/smmuv3.c | 28 +-
79
target/riscv/translate.c | 72 ++-----
110
hw/arm/stellaris.c | 2 +-
80
target/xtensa/translate.c | 50 +++--
111
hw/arm/tosa.c | 2 +-
81
tcg/tcg-op.c | 48 +++++
112
hw/arm/versatilepb.c | 2 +-
82
33 files changed, 934 insertions(+), 504 deletions(-)
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
83
139
diff view generated by jsdifflib
1
From: Igor Mammedov <imammedo@redhat.com>
1
From: Eric Auger <eric.auger@redhat.com>
2
2
3
platform-bus were using machine_done notifier to get and map
3
The SMMUNotifierNode struct is not necessary and brings extra
4
(assign irq/mmio resources) dynamically added sysbus devices
4
complexity so let's remove it. We now directly track the SMMUDevices
5
after all '-device' options had been processed.
5
which have registered IOMMU MR notifiers.
6
That however creates non obvious dependencies on ordering of
7
machine_done notifiers and requires carefull line juggling
8
to keep it working. For example see comment above
9
create_platform_bus() and 'straitforward' arm_load_kernel()
10
had to converted to machine_done notifier and that lead to
11
yet another machine_done notifier to keep it working
12
arm_register_platform_bus_fdt_creator().
13
6
14
Instead of hiding resource assignment in platform-bus-device
7
This is inspired from the same transformation on intel-iommu
15
to magically initialize sysbus devices, use device plug
8
done in commit b4a4ba0d68f50f218ee3957b6638dbee32a5eeef
16
callback and assign resources explicitly at board level
9
("intel-iommu: remove IntelIOMMUNotifierNode")
17
at the moment each -device option is being processed.
18
10
19
That adds a bunch of machine declaration boiler plate to
11
Signed-off-by: Eric Auger <eric.auger@redhat.com>
20
e500plat board, similar to ARM/x86 but gets rid of hidden
12
Reviewed-by: Peter Xu <peterx@redhat.com>
21
machine_done notifier and would allow to remove the dependent
13
Message-id: 20190409160219.19026-1-eric.auger@redhat.com
22
notifiers in ARM code simplifying it and making code flow
23
easier to follow.
24
25
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
26
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
27
Acked-by: David Gibson <david@gibson.dropbear.id.au>
28
Message-id: 1525691524-32265-3-git-send-email-imammedo@redhat.com
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
---
15
---
31
hw/ppc/e500.h | 5 +++++
16
include/hw/arm/smmu-common.h | 8 ++------
32
include/hw/arm/virt.h | 1 +
17
hw/arm/smmu-common.c | 6 +++---
33
include/hw/platform-bus.h | 4 ++--
18
hw/arm/smmuv3.c | 28 +++++++---------------------
34
hw/arm/sysbus-fdt.c | 3 ---
19
3 files changed, 12 insertions(+), 30 deletions(-)
35
hw/arm/virt.c | 31 +++++++++++++++++++++++++++++++
36
hw/core/platform-bus.c | 29 +++++------------------------
37
hw/ppc/e500.c | 38 +++++++++++++++++---------------------
38
hw/ppc/e500plat.c | 31 +++++++++++++++++++++++++++++++
39
8 files changed, 92 insertions(+), 50 deletions(-)
40
20
41
diff --git a/hw/ppc/e500.h b/hw/ppc/e500.h
21
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
42
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/ppc/e500.h
23
--- a/include/hw/arm/smmu-common.h
44
+++ b/hw/ppc/e500.h
24
+++ b/include/hw/arm/smmu-common.h
45
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUDevice {
46
#define PPCE500_H
26
AddressSpace as;
47
27
uint32_t cfg_cache_hits;
48
#include "hw/boards.h"
28
uint32_t cfg_cache_misses;
49
+#include "hw/platform-bus.h"
29
+ QLIST_ENTRY(SMMUDevice) next;
50
30
} SMMUDevice;
51
typedef struct PPCE500MachineState {
31
52
/*< private >*/
32
-typedef struct SMMUNotifierNode {
53
MachineState parent_obj;
33
- SMMUDevice *sdev;
54
34
- QLIST_ENTRY(SMMUNotifierNode) next;
55
+ /* points to instance of TYPE_PLATFORM_BUS_DEVICE if
35
-} SMMUNotifierNode;
56
+ * board supports dynamic sysbus devices
36
-
57
+ */
37
typedef struct SMMUPciBus {
58
+ PlatformBusDevice *pbus_dev;
38
PCIBus *bus;
59
} PPCE500MachineState;
39
SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
60
40
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUState {
61
typedef struct PPCE500MachineClass {
41
GHashTable *iotlb;
62
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
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
63
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
64
--- a/include/hw/arm/virt.h
51
--- a/hw/arm/smmu-common.c
65
+++ b/include/hw/arm/virt.h
52
+++ b/hw/arm/smmu-common.c
66
@@ -XXX,XX +XXX,XX @@ typedef struct {
53
@@ -XXX,XX +XXX,XX @@ inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
67
typedef struct {
54
/* Unmap all notifiers of all mr's */
68
MachineState parent;
55
void smmu_inv_notifiers_all(SMMUState *s)
69
Notifier machine_done;
70
+ DeviceState *platform_bus_dev;
71
FWCfgState *fw_cfg;
72
bool secure;
73
bool highmem;
74
diff --git a/include/hw/platform-bus.h b/include/hw/platform-bus.h
75
index XXXXXXX..XXXXXXX 100644
76
--- a/include/hw/platform-bus.h
77
+++ b/include/hw/platform-bus.h
78
@@ -XXX,XX +XXX,XX @@ typedef struct PlatformBusDevice PlatformBusDevice;
79
struct PlatformBusDevice {
80
/*< private >*/
81
SysBusDevice parent_obj;
82
- Notifier notifier;
83
- bool done_gathering;
84
85
/*< public >*/
86
uint32_t mmio_size;
87
@@ -XXX,XX +XXX,XX @@ int platform_bus_get_irqn(PlatformBusDevice *platform_bus, SysBusDevice *sbdev,
88
hwaddr platform_bus_get_mmio_addr(PlatformBusDevice *pbus, SysBusDevice *sbdev,
89
int n);
90
91
+void platform_bus_link_device(PlatformBusDevice *pbus, SysBusDevice *sbdev);
92
+
93
#endif /* HW_PLATFORM_BUS_H */
94
diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/hw/arm/sysbus-fdt.c
97
+++ b/hw/arm/sysbus-fdt.c
98
@@ -XXX,XX +XXX,XX @@ static void add_all_platform_bus_fdt_nodes(ARMPlatformBusFDTParams *fdt_params)
99
dev = qdev_find_recursive(sysbus_get_default(), TYPE_PLATFORM_BUS_DEVICE);
100
pbus = PLATFORM_BUS_DEVICE(dev);
101
102
- /* We can only create dt nodes for dynamic devices when they're ready */
103
- assert(pbus->done_gathering);
104
-
105
PlatformBusFDTData data = {
106
.fdt = fdt,
107
.irq_start = irq_start,
108
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/arm/virt.c
111
+++ b/hw/arm/virt.c
112
@@ -XXX,XX +XXX,XX @@ static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic)
113
qdev_prop_set_uint32(dev, "mmio_size",
114
platform_bus_params.platform_bus_size);
115
qdev_init_nofail(dev);
116
+ vms->platform_bus_dev = dev;
117
s = SYS_BUS_DEVICE(dev);
118
119
for (i = 0; i < platform_bus_params.platform_bus_num_irqs; i++) {
120
@@ -XXX,XX +XXX,XX @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
121
return ms->possible_cpus;
122
}
123
124
+static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
125
+ DeviceState *dev, Error **errp)
126
+{
127
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
128
+
129
+ if (vms->platform_bus_dev) {
130
+ if (object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE)) {
131
+ platform_bus_link_device(PLATFORM_BUS_DEVICE(vms->platform_bus_dev),
132
+ SYS_BUS_DEVICE(dev));
133
+ }
134
+ }
135
+}
136
+
137
+static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
138
+ DeviceState *dev)
139
+{
140
+ if (object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE)) {
141
+ return HOTPLUG_HANDLER(machine);
142
+ }
143
+
144
+ return NULL;
145
+}
146
+
147
static void virt_machine_class_init(ObjectClass *oc, void *data)
148
{
56
{
149
MachineClass *mc = MACHINE_CLASS(oc);
57
- SMMUNotifierNode *node;
150
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
58
+ SMMUDevice *sdev;
151
59
152
mc->init = machvirt_init;
60
- QLIST_FOREACH(node, &s->notifiers_list, next) {
153
/* Start max_cpus at the maximum QEMU supports. We'll further restrict
61
- smmu_inv_notifiers_mr(&node->sdev->iommu);
154
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
62
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
155
mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
63
+ smmu_inv_notifiers_mr(&sdev->iommu);
156
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
157
mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
158
+ mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
159
+ hc->plug = virt_machine_device_plug_cb;
160
}
161
162
static const TypeInfo virt_machine_info = {
163
@@ -XXX,XX +XXX,XX @@ static const TypeInfo virt_machine_info = {
164
.instance_size = sizeof(VirtMachineState),
165
.class_size = sizeof(VirtMachineClass),
166
.class_init = virt_machine_class_init,
167
+ .interfaces = (InterfaceInfo[]) {
168
+ { TYPE_HOTPLUG_HANDLER },
169
+ { }
170
+ },
171
};
172
173
static void machvirt_machine_init(void)
174
diff --git a/hw/core/platform-bus.c b/hw/core/platform-bus.c
175
index XXXXXXX..XXXXXXX 100644
176
--- a/hw/core/platform-bus.c
177
+++ b/hw/core/platform-bus.c
178
@@ -XXX,XX +XXX,XX @@ static void plaform_bus_refresh_irqs(PlatformBusDevice *pbus)
179
{
180
bitmap_zero(pbus->used_irqs, pbus->num_irqs);
181
foreach_dynamic_sysbus_device(platform_bus_count_irqs, pbus);
182
- pbus->done_gathering = true;
183
}
184
185
static void platform_bus_map_irq(PlatformBusDevice *pbus, SysBusDevice *sbdev,
186
@@ -XXX,XX +XXX,XX @@ static void platform_bus_map_mmio(PlatformBusDevice *pbus, SysBusDevice *sbdev,
187
}
188
189
/*
190
- * For each sysbus device, look for unassigned IRQ lines as well as
191
- * unassociated MMIO regions. Connect them to the platform bus if available.
192
+ * Look for unassigned IRQ lines as well as unassociated MMIO regions.
193
+ * Connect them to the platform bus if available.
194
*/
195
-static void link_sysbus_device(SysBusDevice *sbdev, void *opaque)
196
+void platform_bus_link_device(PlatformBusDevice *pbus, SysBusDevice *sbdev)
197
{
198
- PlatformBusDevice *pbus = opaque;
199
int i;
200
201
for (i = 0; sysbus_has_irq(sbdev, i); i++) {
202
@@ -XXX,XX +XXX,XX @@ static void link_sysbus_device(SysBusDevice *sbdev, void *opaque)
203
}
64
}
204
}
65
}
205
66
206
-static void platform_bus_init_notify(Notifier *notifier, void *data)
67
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
207
-{
68
index XXXXXXX..XXXXXXX 100644
208
- PlatformBusDevice *pb = container_of(notifier, PlatformBusDevice, notifier);
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
- }
209
-
103
-
210
- /*
104
- /* update notifier node with new flags */
211
- * Generate a bitmap of used IRQ lines, as the user might have specified
105
- QLIST_FOREACH_SAFE(node, &s->notifiers_list, next, next_node) {
212
- * them on the command line.
106
- if (node->sdev == sdev) {
213
- */
107
- if (new == IOMMU_NOTIFIER_NONE) {
214
- plaform_bus_refresh_irqs(pb);
108
- trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
215
-
109
- QLIST_REMOVE(node, next);
216
- foreach_dynamic_sysbus_device(link_sysbus_device, pb);
110
- g_free(node);
217
-}
111
- }
218
-
112
- return;
219
static void platform_bus_realize(DeviceState *dev, Error **errp)
113
- }
220
{
114
+ QLIST_INSERT_HEAD(&s->devices_with_notifiers, sdev, next);
221
PlatformBusDevice *pbus;
115
+ } else if (new == IOMMU_NOTIFIER_NONE) {
222
@@ -XXX,XX +XXX,XX @@ static void platform_bus_realize(DeviceState *dev, Error **errp)
116
+ trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
223
sysbus_init_irq(d, &pbus->irqs[i]);
117
+ QLIST_REMOVE(sdev, next);
224
}
225
226
- /*
227
- * Register notifier that allows us to gather dangling devices once the
228
- * machine is completely assembled
229
- */
230
- pbus->notifier.notify = platform_bus_init_notify;
231
- qemu_add_machine_init_done_notifier(&pbus->notifier);
232
+ /* some devices might be initialized before so update used IRQs map */
233
+ plaform_bus_refresh_irqs(pbus);
234
}
235
236
static Property platform_bus_properties[] = {
237
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
238
index XXXXXXX..XXXXXXX 100644
239
--- a/hw/ppc/e500.c
240
+++ b/hw/ppc/e500.c
241
@@ -XXX,XX +XXX,XX @@ static void sysbus_device_create_devtree(SysBusDevice *sbdev, void *opaque)
242
}
118
}
243
}
119
}
244
120
245
-static void platform_bus_create_devtree(const PPCE500MachineClass *pmc,
246
+static void platform_bus_create_devtree(PPCE500MachineState *pms,
247
void *fdt, const char *mpic)
248
{
249
+ const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(pms);
250
gchar *node = g_strdup_printf("/platform@%"PRIx64, pmc->platform_bus_base);
251
const char platcomp[] = "qemu,platform\0simple-bus";
252
uint64_t addr = pmc->platform_bus_base;
253
uint64_t size = pmc->platform_bus_size;
254
int irq_start = pmc->platform_bus_first_irq;
255
- PlatformBusDevice *pbus;
256
- DeviceState *dev;
257
258
/* Create a /platform node that we can put all devices into */
259
260
@@ -XXX,XX +XXX,XX @@ static void platform_bus_create_devtree(const PPCE500MachineClass *pmc,
261
262
qemu_fdt_setprop_phandle(fdt, node, "interrupt-parent", mpic);
263
264
- dev = qdev_find_recursive(sysbus_get_default(), TYPE_PLATFORM_BUS_DEVICE);
265
- pbus = PLATFORM_BUS_DEVICE(dev);
266
+ /* Create dt nodes for dynamic devices */
267
+ PlatformDevtreeData data = {
268
+ .fdt = fdt,
269
+ .mpic = mpic,
270
+ .irq_start = irq_start,
271
+ .node = node,
272
+ .pbus = pms->pbus_dev,
273
+ };
274
275
- /* We can only create dt nodes for dynamic devices when they're ready */
276
- if (pbus->done_gathering) {
277
- PlatformDevtreeData data = {
278
- .fdt = fdt,
279
- .mpic = mpic,
280
- .irq_start = irq_start,
281
- .node = node,
282
- .pbus = pbus,
283
- };
284
-
285
- /* Loop through all dynamic sysbus devices and create nodes for them */
286
- foreach_dynamic_sysbus_device(sysbus_device_create_devtree, &data);
287
- }
288
+ /* Loop through all dynamic sysbus devices and create nodes for them */
289
+ foreach_dynamic_sysbus_device(sysbus_device_create_devtree, &data);
290
291
g_free(node);
292
}
293
@@ -XXX,XX +XXX,XX @@ static int ppce500_load_device_tree(PPCE500MachineState *pms,
294
}
295
g_free(soc);
296
297
- if (pmc->has_platform_bus) {
298
- platform_bus_create_devtree(pmc, fdt, mpic);
299
+ if (pms->pbus_dev) {
300
+ platform_bus_create_devtree(pms, fdt, mpic);
301
}
302
g_free(mpic);
303
304
@@ -XXX,XX +XXX,XX @@ void ppce500_init(MachineState *machine)
305
qdev_prop_set_uint32(dev, "num_irqs", pmc->platform_bus_num_irqs);
306
qdev_prop_set_uint32(dev, "mmio_size", pmc->platform_bus_size);
307
qdev_init_nofail(dev);
308
- s = SYS_BUS_DEVICE(dev);
309
+ pms->pbus_dev = PLATFORM_BUS_DEVICE(dev);
310
311
+ s = SYS_BUS_DEVICE(pms->pbus_dev);
312
for (i = 0; i < pmc->platform_bus_num_irqs; i++) {
313
int irqn = pmc->platform_bus_first_irq + i;
314
sysbus_connect_irq(s, i, qdev_get_gpio_in(mpicdev, irqn));
315
@@ -XXX,XX +XXX,XX @@ static const TypeInfo ppce500_info = {
316
.name = TYPE_PPCE500_MACHINE,
317
.parent = TYPE_MACHINE,
318
.abstract = true,
319
+ .instance_size = sizeof(PPCE500MachineState),
320
.class_size = sizeof(PPCE500MachineClass),
321
};
322
323
diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c
324
index XXXXXXX..XXXXXXX 100644
325
--- a/hw/ppc/e500plat.c
326
+++ b/hw/ppc/e500plat.c
327
@@ -XXX,XX +XXX,XX @@ static void e500plat_init(MachineState *machine)
328
ppce500_init(machine);
329
}
330
331
+static void e500plat_machine_device_plug_cb(HotplugHandler *hotplug_dev,
332
+ DeviceState *dev, Error **errp)
333
+{
334
+ PPCE500MachineState *pms = PPCE500_MACHINE(hotplug_dev);
335
+
336
+ if (pms->pbus_dev) {
337
+ if (object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE)) {
338
+ platform_bus_link_device(pms->pbus_dev, SYS_BUS_DEVICE(dev));
339
+ }
340
+ }
341
+}
342
+
343
+static
344
+HotplugHandler *e500plat_machine_get_hotpug_handler(MachineState *machine,
345
+ DeviceState *dev)
346
+{
347
+ if (object_dynamic_cast(OBJECT(dev), TYPE_SYS_BUS_DEVICE)) {
348
+ return HOTPLUG_HANDLER(machine);
349
+ }
350
+
351
+ return NULL;
352
+}
353
+
354
#define TYPE_E500PLAT_MACHINE MACHINE_TYPE_NAME("ppce500")
355
356
static void e500plat_machine_class_init(ObjectClass *oc, void *data)
357
{
358
PPCE500MachineClass *pmc = PPCE500_MACHINE_CLASS(oc);
359
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
360
MachineClass *mc = MACHINE_CLASS(oc);
361
362
+ mc->get_hotplug_handler = e500plat_machine_get_hotpug_handler;
363
+ hc->plug = e500plat_machine_device_plug_cb;
364
+
365
pmc->pci_first_slot = 0x1;
366
pmc->pci_nr_slots = PCI_SLOT_MAX - 1;
367
pmc->fixup_devtree = e500plat_fixup_devtree;
368
@@ -XXX,XX +XXX,XX @@ static const TypeInfo e500plat_info = {
369
.name = TYPE_E500PLAT_MACHINE,
370
.parent = TYPE_PPCE500_MACHINE,
371
.class_init = e500plat_machine_class_init,
372
+ .interfaces = (InterfaceInfo[]) {
373
+ { TYPE_HOTPLUG_HANDLER },
374
+ { }
375
+ }
376
};
377
378
static void e500plat_register_types(void)
379
--
121
--
380
2.17.0
122
2.20.1
381
123
382
124
diff view generated by jsdifflib
New 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.
1
4
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
New 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.
1
5
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
New 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.
1
5
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
New 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.)
1
4
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
New patch
1
1
The M-profile floating point support has three associated config
2
registers: FPCAR, FPCCR and FPDSCR. It also makes the registers
3
CPACR and NSACR have behaviour other than reads-as-zero.
4
Add support for all of these as simple reads-as-written registers.
5
We will hook up actual functionality later.
6
7
The main complexity here is handling the FPCCR register, which
8
has a mix of banked and unbanked bits.
9
10
Note that we don't share storage with the A-profile
11
cpu->cp15.nsacr and cpu->cp15.cpacr_el1, though the behaviour
12
is quite similar, for two reasons:
13
* the M profile CPACR is banked between security states
14
* it preserves the invariant that M profile uses no state
15
inside the cp15 substruct
16
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20190416125744.27770-4-peter.maydell@linaro.org
20
---
21
target/arm/cpu.h | 34 ++++++++++++
22
hw/intc/armv7m_nvic.c | 125 ++++++++++++++++++++++++++++++++++++++++++
23
target/arm/cpu.c | 5 ++
24
target/arm/machine.c | 16 ++++++
25
4 files changed, 180 insertions(+)
26
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu.h
30
+++ b/target/arm/cpu.h
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
32
uint32_t scr[M_REG_NUM_BANKS];
33
uint32_t msplim[M_REG_NUM_BANKS];
34
uint32_t psplim[M_REG_NUM_BANKS];
35
+ uint32_t fpcar[M_REG_NUM_BANKS];
36
+ uint32_t fpccr[M_REG_NUM_BANKS];
37
+ uint32_t fpdscr[M_REG_NUM_BANKS];
38
+ uint32_t cpacr[M_REG_NUM_BANKS];
39
+ uint32_t nsacr;
40
} v7m;
41
42
/* Information associated with an exception about to be taken:
43
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_CSSELR, LEVEL, 1, 3)
44
*/
45
FIELD(V7M_CSSELR, INDEX, 0, 4)
46
47
+/* v7M FPCCR bits */
48
+FIELD(V7M_FPCCR, LSPACT, 0, 1)
49
+FIELD(V7M_FPCCR, USER, 1, 1)
50
+FIELD(V7M_FPCCR, S, 2, 1)
51
+FIELD(V7M_FPCCR, THREAD, 3, 1)
52
+FIELD(V7M_FPCCR, HFRDY, 4, 1)
53
+FIELD(V7M_FPCCR, MMRDY, 5, 1)
54
+FIELD(V7M_FPCCR, BFRDY, 6, 1)
55
+FIELD(V7M_FPCCR, SFRDY, 7, 1)
56
+FIELD(V7M_FPCCR, MONRDY, 8, 1)
57
+FIELD(V7M_FPCCR, SPLIMVIOL, 9, 1)
58
+FIELD(V7M_FPCCR, UFRDY, 10, 1)
59
+FIELD(V7M_FPCCR, RES0, 11, 15)
60
+FIELD(V7M_FPCCR, TS, 26, 1)
61
+FIELD(V7M_FPCCR, CLRONRETS, 27, 1)
62
+FIELD(V7M_FPCCR, CLRONRET, 28, 1)
63
+FIELD(V7M_FPCCR, LSPENS, 29, 1)
64
+FIELD(V7M_FPCCR, LSPEN, 30, 1)
65
+FIELD(V7M_FPCCR, ASPEN, 31, 1)
66
+/* These bits are banked. Others are non-banked and live in the M_REG_S bank */
67
+#define R_V7M_FPCCR_BANKED_MASK \
68
+ (R_V7M_FPCCR_LSPACT_MASK | \
69
+ R_V7M_FPCCR_USER_MASK | \
70
+ R_V7M_FPCCR_THREAD_MASK | \
71
+ R_V7M_FPCCR_MMRDY_MASK | \
72
+ R_V7M_FPCCR_SPLIMVIOL_MASK | \
73
+ R_V7M_FPCCR_UFRDY_MASK | \
74
+ R_V7M_FPCCR_ASPEN_MASK)
75
+
76
/*
77
* System register ID fields.
78
*/
79
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/intc/armv7m_nvic.c
82
+++ b/hw/intc/armv7m_nvic.c
83
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
84
}
85
case 0xd84: /* CSSELR */
86
return cpu->env.v7m.csselr[attrs.secure];
87
+ case 0xd88: /* CPACR */
88
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
89
+ return 0;
90
+ }
91
+ return cpu->env.v7m.cpacr[attrs.secure];
92
+ case 0xd8c: /* NSACR */
93
+ if (!attrs.secure || !arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
94
+ return 0;
95
+ }
96
+ return cpu->env.v7m.nsacr;
97
/* TODO: Implement debug registers. */
98
case 0xd90: /* MPU_TYPE */
99
/* Unified MPU; if the MPU is not present this value is zero */
100
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
101
return 0;
102
}
103
return cpu->env.v7m.sfar;
104
+ case 0xf34: /* FPCCR */
105
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
106
+ return 0;
107
+ }
108
+ if (attrs.secure) {
109
+ return cpu->env.v7m.fpccr[M_REG_S];
110
+ } else {
111
+ /*
112
+ * NS can read LSPEN, CLRONRET and MONRDY. It can read
113
+ * BFRDY and HFRDY if AIRCR.BFHFNMINS != 0;
114
+ * other non-banked bits RAZ.
115
+ * TODO: MONRDY should RAZ/WI if DEMCR.SDME is set.
116
+ */
117
+ uint32_t value = cpu->env.v7m.fpccr[M_REG_S];
118
+ uint32_t mask = R_V7M_FPCCR_LSPEN_MASK |
119
+ R_V7M_FPCCR_CLRONRET_MASK |
120
+ R_V7M_FPCCR_MONRDY_MASK;
121
+
122
+ if (s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
123
+ mask |= R_V7M_FPCCR_BFRDY_MASK | R_V7M_FPCCR_HFRDY_MASK;
124
+ }
125
+
126
+ value &= mask;
127
+
128
+ value |= cpu->env.v7m.fpccr[M_REG_NS];
129
+ return value;
130
+ }
131
+ case 0xf38: /* FPCAR */
132
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
133
+ return 0;
134
+ }
135
+ return cpu->env.v7m.fpcar[attrs.secure];
136
+ case 0xf3c: /* FPDSCR */
137
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
138
+ return 0;
139
+ }
140
+ return cpu->env.v7m.fpdscr[attrs.secure];
141
case 0xf40: /* MVFR0 */
142
return cpu->isar.mvfr0;
143
case 0xf44: /* MVFR1 */
144
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
145
cpu->env.v7m.csselr[attrs.secure] = value & R_V7M_CSSELR_INDEX_MASK;
146
}
147
break;
148
+ case 0xd88: /* CPACR */
149
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
150
+ /* We implement only the Floating Point extension's CP10/CP11 */
151
+ cpu->env.v7m.cpacr[attrs.secure] = value & (0xf << 20);
152
+ }
153
+ break;
154
+ case 0xd8c: /* NSACR */
155
+ if (attrs.secure && arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
156
+ /* We implement only the Floating Point extension's CP10/CP11 */
157
+ cpu->env.v7m.nsacr = value & (3 << 10);
158
+ }
159
+ break;
160
case 0xd90: /* MPU_TYPE */
161
return; /* RO */
162
case 0xd94: /* MPU_CTRL */
163
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
164
}
165
break;
166
}
167
+ case 0xf34: /* FPCCR */
168
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
169
+ /* Not all bits here are banked. */
170
+ uint32_t fpccr_s;
171
+
172
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
173
+ /* Don't allow setting of bits not present in v7M */
174
+ value &= (R_V7M_FPCCR_LSPACT_MASK |
175
+ R_V7M_FPCCR_USER_MASK |
176
+ R_V7M_FPCCR_THREAD_MASK |
177
+ R_V7M_FPCCR_HFRDY_MASK |
178
+ R_V7M_FPCCR_MMRDY_MASK |
179
+ R_V7M_FPCCR_BFRDY_MASK |
180
+ R_V7M_FPCCR_MONRDY_MASK |
181
+ R_V7M_FPCCR_LSPEN_MASK |
182
+ R_V7M_FPCCR_ASPEN_MASK);
183
+ }
184
+ value &= ~R_V7M_FPCCR_RES0_MASK;
185
+
186
+ if (!attrs.secure) {
187
+ /* Some non-banked bits are configurably writable by NS */
188
+ fpccr_s = cpu->env.v7m.fpccr[M_REG_S];
189
+ if (!(fpccr_s & R_V7M_FPCCR_LSPENS_MASK)) {
190
+ uint32_t lspen = FIELD_EX32(value, V7M_FPCCR, LSPEN);
191
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, LSPEN, lspen);
192
+ }
193
+ if (!(fpccr_s & R_V7M_FPCCR_CLRONRETS_MASK)) {
194
+ uint32_t cor = FIELD_EX32(value, V7M_FPCCR, CLRONRET);
195
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, CLRONRET, cor);
196
+ }
197
+ if ((s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
198
+ uint32_t hfrdy = FIELD_EX32(value, V7M_FPCCR, HFRDY);
199
+ uint32_t bfrdy = FIELD_EX32(value, V7M_FPCCR, BFRDY);
200
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
201
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
202
+ }
203
+ /* TODO MONRDY should RAZ/WI if DEMCR.SDME is set */
204
+ {
205
+ uint32_t monrdy = FIELD_EX32(value, V7M_FPCCR, MONRDY);
206
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, MONRDY, monrdy);
207
+ }
208
+
209
+ /*
210
+ * All other non-banked bits are RAZ/WI from NS; write
211
+ * just the banked bits to fpccr[M_REG_NS].
212
+ */
213
+ value &= R_V7M_FPCCR_BANKED_MASK;
214
+ cpu->env.v7m.fpccr[M_REG_NS] = value;
215
+ } else {
216
+ fpccr_s = value;
217
+ }
218
+ cpu->env.v7m.fpccr[M_REG_S] = fpccr_s;
219
+ }
220
+ break;
221
+ case 0xf38: /* FPCAR */
222
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
223
+ value &= ~7;
224
+ cpu->env.v7m.fpcar[attrs.secure] = value;
225
+ }
226
+ break;
227
+ case 0xf3c: /* FPDSCR */
228
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
229
+ value &= 0x07c00000;
230
+ cpu->env.v7m.fpdscr[attrs.secure] = value;
231
+ }
232
+ break;
233
case 0xf50: /* ICIALLU */
234
case 0xf58: /* ICIMVAU */
235
case 0xf5c: /* DCIMVAC */
236
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
237
index XXXXXXX..XXXXXXX 100644
238
--- a/target/arm/cpu.c
239
+++ b/target/arm/cpu.c
240
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
241
env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK;
242
}
243
244
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
245
+ env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK;
246
+ env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
247
+ R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
248
+ }
249
/* Unlike A/R profile, M profile defines the reset LR value */
250
env->regs[14] = 0xffffffff;
251
252
diff --git a/target/arm/machine.c b/target/arm/machine.c
253
index XXXXXXX..XXXXXXX 100644
254
--- a/target/arm/machine.c
255
+++ b/target/arm/machine.c
256
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_v8m = {
257
}
258
};
259
260
+static const VMStateDescription vmstate_m_fp = {
261
+ .name = "cpu/m/fp",
262
+ .version_id = 1,
263
+ .minimum_version_id = 1,
264
+ .needed = vfp_needed,
265
+ .fields = (VMStateField[]) {
266
+ VMSTATE_UINT32_ARRAY(env.v7m.fpcar, ARMCPU, M_REG_NUM_BANKS),
267
+ VMSTATE_UINT32_ARRAY(env.v7m.fpccr, ARMCPU, M_REG_NUM_BANKS),
268
+ VMSTATE_UINT32_ARRAY(env.v7m.fpdscr, ARMCPU, M_REG_NUM_BANKS),
269
+ VMSTATE_UINT32_ARRAY(env.v7m.cpacr, ARMCPU, M_REG_NUM_BANKS),
270
+ VMSTATE_UINT32(env.v7m.nsacr, ARMCPU),
271
+ VMSTATE_END_OF_LIST()
272
+ }
273
+};
274
+
275
static const VMStateDescription vmstate_m = {
276
.name = "cpu/m",
277
.version_id = 4,
278
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
279
&vmstate_m_scr,
280
&vmstate_m_other_sp,
281
&vmstate_m_v8m,
282
+ &vmstate_m_fp,
283
NULL
284
}
285
};
286
--
287
2.20.1
288
289
diff view generated by jsdifflib
New patch
1
The only "system register" that M-profile floating point exposes
2
via the VMRS/VMRS instructions is FPSCR, and it does not have
3
the odd special case for rd==15. Add a check to ensure we only
4
expose FPSCR.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-5-peter.maydell@linaro.org
9
---
10
target/arm/translate.c | 19 +++++++++++++++++--
11
1 file changed, 17 insertions(+), 2 deletions(-)
12
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
16
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
18
}
19
}
20
} else { /* !dp */
21
+ bool is_sysreg;
22
+
23
if ((insn & 0x6f) != 0x00)
24
return 1;
25
rn = VFP_SREG_N(insn);
26
+
27
+ is_sysreg = extract32(insn, 21, 1);
28
+
29
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
30
+ /*
31
+ * The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
32
+ * Writes to R15 are UNPREDICTABLE; we choose to undef.
33
+ */
34
+ if (is_sysreg && (rd == 15 || (rn >> 1) != ARM_VFP_FPSCR)) {
35
+ return 1;
36
+ }
37
+ }
38
+
39
if (insn & ARM_CP_RW_BIT) {
40
/* vfp->arm */
41
- if (insn & (1 << 21)) {
42
+ if (is_sysreg) {
43
/* system register */
44
rn >>= 1;
45
46
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
47
}
48
} else {
49
/* arm->vfp */
50
- if (insn & (1 << 21)) {
51
+ if (is_sysreg) {
52
rn >>= 1;
53
/* system register */
54
switch (rn) {
55
--
56
2.20.1
57
58
diff view generated by jsdifflib
1
It is implementation defined whether a multiply-add of
1
Like AArch64, M-profile floating point has no FPEXC enable
2
(0,inf,qnan) or (inf,0,qnan) raises InvalidaOperation or
2
bit to gate floating point; so always set the VFPEN TB flag.
3
not, so we let the target-specific pickNaNMulAdd function
4
handle this. This means that we must do the "return the
5
default NaN in default NaN mode" check after the call,
6
not before. Correct the ordering, and restore the comment
7
from the old propagateFloat64MulAddNaN() that warned about
8
this corner case.
9
3
10
This fixes a regression from 2.11 for Arm guests where we would
4
M-profile also has CPACR and NSACR similar to A-profile;
11
incorrectly fail to set the Invalid flag for these cases.
5
they behave slightly differently:
6
* the CPACR is banked between Secure and Non-Secure
7
* if the NSACR forces a trap then this is taken to
8
the Secure state, not the Non-Secure state
12
9
13
Cc: qemu-stable@nongnu.org
10
Honour the CPACR and NSACR settings. The NSACR handling
11
requires us to borrow the exception.target_el field
12
(usually meaningless for M profile) to distinguish the
13
NOCP UsageFault taken to Secure state from the more
14
usual fault taken to the current security state.
15
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
18
Message-id: 20190416125744.27770-6-peter.maydell@linaro.org
17
Tested-by: Alex Bennée <alex.bennee@linaro.org>
18
Message-id: 20180504100547.14621-1-peter.maydell@linaro.org
19
---
19
---
20
fpu/softfloat.c | 52 ++++++++++++++++++++++++++++---------------------
20
target/arm/helper.c | 55 +++++++++++++++++++++++++++++++++++++++---
21
1 file changed, 30 insertions(+), 22 deletions(-)
21
target/arm/translate.c | 10 ++++++--
22
2 files changed, 60 insertions(+), 5 deletions(-)
22
23
23
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
25
--- a/fpu/softfloat.c
26
--- a/target/arm/helper.c
26
+++ b/fpu/softfloat.c
27
+++ b/target/arm/helper.c
27
@@ -XXX,XX +XXX,XX @@ static FloatParts pick_nan(FloatParts a, FloatParts b, float_status *s)
28
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
28
static FloatParts pick_nan_muladd(FloatParts a, FloatParts b, FloatParts c,
29
return target_el;
29
bool inf_zero, float_status *s)
30
}
30
{
31
31
+ int which;
32
+/*
32
+
33
+ * Return true if the v7M CPACR permits access to the FPU for the specified
33
if (is_snan(a.cls) || is_snan(b.cls) || is_snan(c.cls)) {
34
+ * security state and privilege level.
34
s->float_exception_flags |= float_flag_invalid;
35
+ */
35
}
36
+static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
36
37
+{
37
- if (s->default_nan_mode) {
38
+ switch (extract32(env->v7m.cpacr[is_secure], 20, 2)) {
38
- a.cls = float_class_dnan;
39
- } else {
40
- switch (pickNaNMulAdd(is_qnan(a.cls), is_snan(a.cls),
41
- is_qnan(b.cls), is_snan(b.cls),
42
- is_qnan(c.cls), is_snan(c.cls),
43
- inf_zero, s)) {
44
- case 0:
45
- break;
46
- case 1:
47
- a = b;
48
- break;
49
- case 2:
50
- a = c;
51
- break;
52
- case 3:
53
- a.cls = float_class_dnan;
54
- return a;
55
- default:
56
- g_assert_not_reached();
57
- }
58
+ which = pickNaNMulAdd(is_qnan(a.cls), is_snan(a.cls),
59
+ is_qnan(b.cls), is_snan(b.cls),
60
+ is_qnan(c.cls), is_snan(c.cls),
61
+ inf_zero, s);
62
63
- a.cls = float_class_msnan;
64
+ if (s->default_nan_mode) {
65
+ /* Note that this check is after pickNaNMulAdd so that function
66
+ * has an opportunity to set the Invalid flag.
67
+ */
68
+ a.cls = float_class_dnan;
69
+ return a;
70
}
71
+
72
+ switch (which) {
73
+ case 0:
39
+ case 0:
74
+ break;
40
+ case 2: /* UNPREDICTABLE: we treat like 0 */
41
+ return false;
75
+ case 1:
42
+ case 1:
76
+ a = b;
43
+ return is_priv;
77
+ break;
78
+ case 2:
79
+ a = c;
80
+ break;
81
+ case 3:
44
+ case 3:
82
+ a.cls = float_class_dnan;
45
+ return true;
83
+ return a;
84
+ default:
46
+ default:
85
+ g_assert_not_reached();
47
+ g_assert_not_reached();
86
+ }
48
+ }
87
+ a.cls = float_class_msnan;
49
+}
88
+
50
+
89
return a;
51
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
90
}
52
ARMMMUIdx mmu_idx, bool ignfault)
53
{
54
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
55
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNDEFINSTR_MASK;
56
break;
57
case EXCP_NOCP:
58
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
59
- env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
60
+ {
61
+ /*
62
+ * NOCP might be directed to something other than the current
63
+ * security state if this fault is because of NSACR; we indicate
64
+ * the target security state using exception.target_el.
65
+ */
66
+ int target_secstate;
67
+
68
+ if (env->exception.target_el == 3) {
69
+ target_secstate = M_REG_S;
70
+ } else {
71
+ target_secstate = env->v7m.secure;
72
+ }
73
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, target_secstate);
74
+ env->v7m.cfsr[target_secstate] |= R_V7M_CFSR_NOCP_MASK;
75
break;
76
+ }
77
case EXCP_INVSTATE:
78
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
79
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVSTATE_MASK;
80
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
81
return 0;
82
}
83
84
+ if (arm_feature(env, ARM_FEATURE_M)) {
85
+ /* CPACR can cause a NOCP UsageFault taken to current security state */
86
+ if (!v7m_cpacr_pass(env, env->v7m.secure, cur_el != 0)) {
87
+ return 1;
88
+ }
89
+
90
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && !env->v7m.secure) {
91
+ if (!extract32(env->v7m.nsacr, 10, 1)) {
92
+ /* FP insns cause a NOCP UsageFault taken to Secure */
93
+ return 3;
94
+ }
95
+ }
96
+
97
+ return 0;
98
+ }
99
+
100
/* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
101
* 0, 2 : trap EL0 and EL1/PL1 accesses
102
* 1 : trap only EL0 accesses
103
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
104
flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
105
flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
106
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
107
- || arm_el_is_aa64(env, 1)) {
108
+ || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
109
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
110
}
111
flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
112
diff --git a/target/arm/translate.c b/target/arm/translate.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/translate.c
115
+++ b/target/arm/translate.c
116
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
117
* for attempts to execute invalid vfp/neon encodings with FP disabled.
118
*/
119
if (s->fp_excp_el) {
120
- gen_exception_insn(s, 4, EXCP_UDEF,
121
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
122
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
123
+ gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
124
+ s->fp_excp_el);
125
+ } else {
126
+ gen_exception_insn(s, 4, EXCP_UDEF,
127
+ syn_fp_access_trap(1, 0xe, false),
128
+ s->fp_excp_el);
129
+ }
130
return 0;
131
}
91
132
92
--
133
--
93
2.17.0
134
2.20.1
94
135
95
136
diff view generated by jsdifflib
New patch
1
Correct the decode of the M-profile "coprocessor and
2
floating-point instructions" space:
3
* op0 == 0b11 is always unallocated
4
* if the CPU has an FPU then all insns with op1 == 0b101
5
are floating point and go to disas_vfp_insn()
1
6
7
For the moment we leave VLLDM and VLSTM as NOPs; in
8
a later commit we will fill in the proper implementation
9
for the case where an FPU is present.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190416125744.27770-7-peter.maydell@linaro.org
14
---
15
target/arm/translate.c | 26 ++++++++++++++++++++++----
16
1 file changed, 22 insertions(+), 4 deletions(-)
17
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.c
21
+++ b/target/arm/translate.c
22
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
23
case 6: case 7: case 14: case 15:
24
/* Coprocessor. */
25
if (arm_dc_feature(s, ARM_FEATURE_M)) {
26
- /* We don't currently implement M profile FP support,
27
- * so this entire space should give a NOCP fault, with
28
- * the exception of the v8M VLLDM and VLSTM insns, which
29
- * must be NOPs in Secure state and UNDEF in Nonsecure state.
30
+ /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
31
+ if (extract32(insn, 24, 2) == 3) {
32
+ goto illegal_op; /* op0 = 0b11 : unallocated */
33
+ }
34
+
35
+ /*
36
+ * Decode VLLDM and VLSTM first: these are nonstandard because:
37
+ * * if there is no FPU then these insns must NOP in
38
+ * Secure state and UNDEF in Nonsecure state
39
+ * * if there is an FPU then these insns do not have
40
+ * the usual behaviour that disas_vfp_insn() provides of
41
+ * being controlled by CPACR/NSACR enable bits or the
42
+ * lazy-stacking logic.
43
*/
44
if (arm_dc_feature(s, ARM_FEATURE_V8) &&
45
(insn & 0xffa00f00) == 0xec200a00) {
46
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
47
/* Just NOP since FP support is not implemented */
48
break;
49
}
50
+ if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
51
+ ((insn >> 8) & 0xe) == 10) {
52
+ /* FP, and the CPU supports it */
53
+ if (disas_vfp_insn(s, insn)) {
54
+ goto illegal_op;
55
+ }
56
+ break;
57
+ }
58
+
59
/* All other insns: NOCP */
60
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
61
default_exception_el(s));
62
--
63
2.20.1
64
65
diff view generated by jsdifflib
New patch
1
If the floating point extension is present, then the SG instruction
2
must clear the CONTROL_S.SFPA bit. Implement this.
1
3
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: Richard Henderson <richard.henderson@linaro.org>
1
The M-profile CONTROL register has two bits -- SFPA and FPCA --
2
which relate to floating-point support, and should be RES0 otherwise.
3
Handle them correctly in the MSR/MRS register access code.
4
Neither is banked between security states, so they are stored
5
in v7m.control[M_REG_S] regardless of current security state.
2
6
3
This implements all of the v8.1-Atomics instructions except
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
for compare-and-swap, which is decoded elsewhere.
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-9-peter.maydell@linaro.org
10
---
11
target/arm/helper.c | 57 ++++++++++++++++++++++++++++++++++++++-------
12
1 file changed, 49 insertions(+), 8 deletions(-)
5
13
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180508151437.4232-9-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-a64.c | 38 ++++++++++++++++++++++++++++++++++++--
12
1 file changed, 36 insertions(+), 2 deletions(-)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
16
--- a/target/arm/helper.c
17
+++ b/target/arm/translate-a64.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
18
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
19
typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
19
return xpsr_read(env) & mask;
20
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
20
break;
21
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
21
case 20: /* CONTROL */
22
+typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, TCGMemOp);
22
- return env->v7m.control[env->v7m.secure];
23
23
+ {
24
/* Note that the gvec expanders operate on offsets + sizes. */
24
+ uint32_t value = env->v7m.control[env->v7m.secure];
25
typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
25
+ if (!env->v7m.secure) {
26
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
26
+ /* SFPA is RAZ/WI from NS; FPCA is stored in the M_REG_S bank */
27
int rn = extract32(insn, 5, 5);
27
+ value |= env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK;
28
int o3_opc = extract32(insn, 12, 4);
28
+ }
29
int feature = ARM_FEATURE_V8_ATOMICS;
29
+ return value;
30
+ TCGv_i64 tcg_rn, tcg_rs;
30
+ }
31
+ AtomicThreeOpFn *fn;
31
case 0x94: /* CONTROL_NS */
32
32
/* We have to handle this here because unprivileged Secure code
33
if (is_vector) {
33
* can read the NS CONTROL register.
34
unallocated_encoding(s);
34
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
35
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
35
if (!env->v7m.secure) {
36
return 0;
37
}
38
- return env->v7m.control[M_REG_NS];
39
+ return env->v7m.control[M_REG_NS] |
40
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK);
36
}
41
}
37
switch (o3_opc) {
42
38
case 000: /* LDADD */
43
if (el == 0) {
39
+ fn = tcg_gen_atomic_fetch_add_i64;
44
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
40
+ break;
45
*/
41
case 001: /* LDCLR */
46
uint32_t mask = extract32(maskreg, 8, 4);
42
+ fn = tcg_gen_atomic_fetch_and_i64;
47
uint32_t reg = extract32(maskreg, 0, 8);
43
+ break;
48
+ int cur_el = arm_current_el(env);
44
case 002: /* LDEOR */
49
45
+ fn = tcg_gen_atomic_fetch_xor_i64;
50
- if (arm_current_el(env) == 0 && reg > 7) {
46
+ break;
51
- /* only xPSR sub-fields may be written by unprivileged */
47
case 003: /* LDSET */
52
+ if (cur_el == 0 && reg > 7 && reg != 20) {
48
+ fn = tcg_gen_atomic_fetch_or_i64;
53
+ /*
49
+ break;
54
+ * only xPSR sub-fields and CONTROL.SFPA may be written by
50
case 004: /* LDSMAX */
55
+ * unprivileged code
51
+ fn = tcg_gen_atomic_fetch_smax_i64;
56
+ */
52
+ break;
53
case 005: /* LDSMIN */
54
+ fn = tcg_gen_atomic_fetch_smin_i64;
55
+ break;
56
case 006: /* LDUMAX */
57
+ fn = tcg_gen_atomic_fetch_umax_i64;
58
+ break;
59
case 007: /* LDUMIN */
60
+ fn = tcg_gen_atomic_fetch_umin_i64;
61
+ break;
62
case 010: /* SWP */
63
+ fn = tcg_gen_atomic_xchg_i64;
64
+ break;
65
default:
66
unallocated_encoding(s);
67
return;
68
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
69
return;
57
return;
70
}
58
}
71
59
72
- (void)rs;
60
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
73
- (void)rn;
61
env->v7m.control[M_REG_NS] &= ~R_V7M_CONTROL_NPRIV_MASK;
74
+ if (rn == 31) {
62
env->v7m.control[M_REG_NS] |= val & R_V7M_CONTROL_NPRIV_MASK;
75
+ gen_check_sp_alignment(s);
63
}
76
+ }
64
+ /*
77
+ tcg_rn = cpu_reg_sp(s, rn);
65
+ * SFPA is RAZ/WI from NS. FPCA is RO if NSACR.CP10 == 0,
78
+ tcg_rs = read_cpu_reg(s, rs, true);
66
+ * RES0 if the FPU is not present, and is stored in the S bank
79
+
67
+ */
80
+ if (o3_opc == 1) { /* LDCLR */
68
+ if (arm_feature(env, ARM_FEATURE_VFP) &&
81
+ tcg_gen_not_i64(tcg_rs, tcg_rs);
69
+ extract32(env->v7m.nsacr, 10, 1)) {
82
+ }
70
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
83
+
71
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
84
+ /* The tcg atomic primitives are all full barriers. Therefore we
72
+ }
85
+ * can ignore the Acquire and Release bits of this instruction.
73
return;
86
+ */
74
case 0x98: /* SP_NS */
87
+ fn(cpu_reg(s, rt), tcg_rn, tcg_rs, get_mem_index(s),
75
{
88
+ s->be_data | size | MO_ALIGN);
76
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
89
}
77
env->v7m.faultmask[env->v7m.secure] = val & 1;
90
78
break;
91
/* Load/store register (all forms) */
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:
92
--
122
--
93
2.17.0
123
2.20.1
94
124
95
125
diff view generated by jsdifflib
New 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.
1
9
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
New patch
1
Handle floating point registers in exception entry.
2
This corresponds to the FP-specific parts of the pseudocode
3
functions ActivateException() and PushStack().
1
4
5
We defer the code corresponding to UpdateFPCCR() to a later patch.
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-11-peter.maydell@linaro.org
10
---
11
target/arm/helper.c | 98 +++++++++++++++++++++++++++++++++++++++++++--
12
1 file changed, 95 insertions(+), 3 deletions(-)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
19
switch_v7m_security_state(env, targets_secure);
20
write_v7m_control_spsel(env, 0);
21
arm_clear_exclusive(env);
22
+ /* Clear SFPA and FPCA (has no effect if no FPU) */
23
+ env->v7m.control[M_REG_S] &=
24
+ ~(R_V7M_CONTROL_FPCA_MASK | R_V7M_CONTROL_SFPA_MASK);
25
/* Clear IT bits */
26
env->condexec_bits = 0;
27
env->regs[14] = lr;
28
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
29
uint32_t xpsr = xpsr_read(env);
30
uint32_t frameptr = env->regs[13];
31
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
32
+ uint32_t framesize;
33
+ bool nsacr_cp10 = extract32(env->v7m.nsacr, 10, 1);
34
+
35
+ if ((env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) &&
36
+ (env->v7m.secure || nsacr_cp10)) {
37
+ if (env->v7m.secure &&
38
+ env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK) {
39
+ framesize = 0xa8;
40
+ } else {
41
+ framesize = 0x68;
42
+ }
43
+ } else {
44
+ framesize = 0x20;
45
+ }
46
47
/* Align stack pointer if the guest wants that */
48
if ((frameptr & 4) &&
49
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
50
xpsr |= XPSR_SPREALIGN;
51
}
52
53
- frameptr -= 0x20;
54
+ xpsr &= ~XPSR_SFPA;
55
+ if (env->v7m.secure &&
56
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
57
+ xpsr |= XPSR_SFPA;
58
+ }
59
+
60
+ frameptr -= framesize;
61
62
if (arm_feature(env, ARM_FEATURE_V8)) {
63
uint32_t limit = v7m_sp_limit(env);
64
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
65
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
66
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
67
68
+ if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
69
+ /* FPU is active, try to save its registers */
70
+ bool fpccr_s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
71
+ bool lspact = env->v7m.fpccr[fpccr_s] & R_V7M_FPCCR_LSPACT_MASK;
72
+
73
+ if (lspact && arm_feature(env, ARM_FEATURE_M_SECURITY)) {
74
+ qemu_log_mask(CPU_LOG_INT,
75
+ "...SecureFault because LSPACT and FPCA both set\n");
76
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
77
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
78
+ } else if (!env->v7m.secure && !nsacr_cp10) {
79
+ qemu_log_mask(CPU_LOG_INT,
80
+ "...Secure UsageFault with CFSR.NOCP because "
81
+ "NSACR.CP10 prevents stacking FP regs\n");
82
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
83
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
84
+ } else {
85
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
86
+ /* Lazy stacking disabled, save registers now */
87
+ int i;
88
+ bool cpacr_pass = v7m_cpacr_pass(env, env->v7m.secure,
89
+ arm_current_el(env) != 0);
90
+
91
+ if (stacked_ok && !cpacr_pass) {
92
+ /*
93
+ * Take UsageFault if CPACR forbids access. The pseudocode
94
+ * here does a full CheckCPEnabled() but we know the NSACR
95
+ * check can never fail as we have already handled that.
96
+ */
97
+ qemu_log_mask(CPU_LOG_INT,
98
+ "...UsageFault with CFSR.NOCP because "
99
+ "CPACR.CP10 prevents stacking FP regs\n");
100
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
101
+ env->v7m.secure);
102
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
103
+ stacked_ok = false;
104
+ }
105
+
106
+ for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
107
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
108
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
109
+ uint32_t slo = extract64(dn, 0, 32);
110
+ uint32_t shi = extract64(dn, 32, 32);
111
+
112
+ if (i >= 16) {
113
+ faddr += 8; /* skip the slot for the FPSCR */
114
+ }
115
+ stacked_ok = stacked_ok &&
116
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, false) &&
117
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, false);
118
+ }
119
+ stacked_ok = stacked_ok &&
120
+ v7m_stack_write(cpu, frameptr + 0x60,
121
+ vfp_get_fpscr(env), mmu_idx, false);
122
+ if (cpacr_pass) {
123
+ for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
124
+ *aa32_vfp_dreg(env, i / 2) = 0;
125
+ }
126
+ vfp_set_fpscr(env, 0);
127
+ }
128
+ } else {
129
+ /* Lazy stacking enabled, save necessary info to stack later */
130
+ /* TODO : equivalent of UpdateFPCCR() pseudocode */
131
+ }
132
+ }
133
+ }
134
+
135
/*
136
* If we broke a stack limit then SP was already updated earlier;
137
* otherwise we update SP regardless of whether any of the stack
138
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
139
140
if (arm_feature(env, ARM_FEATURE_V8)) {
141
lr = R_V7M_EXCRET_RES1_MASK |
142
- R_V7M_EXCRET_DCRS_MASK |
143
- R_V7M_EXCRET_FTYPE_MASK;
144
+ R_V7M_EXCRET_DCRS_MASK;
145
/* The S bit indicates whether we should return to Secure
146
* or NonSecure (ie our current state).
147
* The ES bit indicates whether we're taking this exception
148
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
149
if (env->v7m.secure) {
150
lr |= R_V7M_EXCRET_S_MASK;
151
}
152
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
153
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
154
+ }
155
} else {
156
lr = R_V7M_EXCRET_RES1_MASK |
157
R_V7M_EXCRET_S_MASK |
158
--
159
2.20.1
160
161
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the code which updates the FPCCR register on an
2
exception entry where we are going to use lazy FP stacking.
3
We have to defer to the NVIC to determine whether the
4
various exceptions are currently ready or not.
2
5
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180508151437.4232-10-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190416125744.27770-12-peter.maydell@linaro.org
7
---
8
---
8
target/arm/helper-a64.h | 2 +
9
target/arm/cpu.h | 14 +++++++++
9
target/arm/helper-a64.c | 43 ++++++++++++++
10
hw/intc/armv7m_nvic.c | 34 ++++++++++++++++++++++
10
target/arm/translate-a64.c | 119 ++++++++++++++++++++++++++++++++++++-
11
target/arm/helper.c | 67 ++++++++++++++++++++++++++++++++++++++++++-
11
3 files changed, 161 insertions(+), 3 deletions(-)
12
3 files changed, 114 insertions(+), 1 deletion(-)
12
13
13
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper-a64.h
16
--- a/target/arm/cpu.h
16
+++ b/target/arm/helper-a64.h
17
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(paired_cmpxchg64_le_parallel, TCG_CALL_NO_WG,
18
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
18
DEF_HELPER_FLAGS_4(paired_cmpxchg64_be, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
19
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
19
DEF_HELPER_FLAGS_4(paired_cmpxchg64_be_parallel, TCG_CALL_NO_WG,
20
*/
20
i64, env, i64, i64, i64)
21
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
21
+DEF_HELPER_5(casp_le_parallel, void, env, i32, i64, i64, i64)
22
+/**
22
+DEF_HELPER_5(casp_be_parallel, void, env, i32, i64, i64, i64)
23
+ * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
23
DEF_HELPER_FLAGS_3(advsimd_maxh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
24
+ * @opaque: the NVIC
24
DEF_HELPER_FLAGS_3(advsimd_minh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
25
+ * @irq: the exception number to mark pending
25
DEF_HELPER_FLAGS_3(advsimd_maxnumh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
26
+ * @secure: false for non-banked exceptions or for the nonsecure
26
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
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
27
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/helper-a64.c
41
--- a/hw/intc/armv7m_nvic.c
29
+++ b/target/arm/helper-a64.c
42
+++ b/hw/intc/armv7m_nvic.c
30
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_be_parallel)(CPUARMState *env, uint64_t addr,
43
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
31
return do_paired_cmpxchg64_be(env, addr, new_lo, new_hi, true, GETPC());
44
return ret;
32
}
45
}
33
46
34
+/* Writes back the old data into Rs. */
47
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
35
+void HELPER(casp_le_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
36
+ uint64_t new_lo, uint64_t new_hi)
37
+{
48
+{
38
+ uintptr_t ra = GETPC();
49
+ /*
39
+#ifndef CONFIG_ATOMIC128
50
+ * Return whether an exception is "ready", i.e. it is enabled and is
40
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
51
+ * configured at a priority which would allow it to interrupt the
41
+#else
52
+ * current execution priority.
42
+ Int128 oldv, cmpv, newv;
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);
43
+
62
+
44
+ cmpv = int128_make128(env->xregs[rs], env->xregs[rs + 1]);
63
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
45
+ newv = int128_make128(new_lo, new_hi);
64
+ assert(!secure || banked);
46
+
65
+
47
+ int mem_idx = cpu_mmu_index(env, false);
66
+ /*
48
+ TCGMemOpIdx oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
67
+ * HardFault is an odd special case: we always check against -1,
49
+ oldv = helper_atomic_cmpxchgo_le_mmu(env, addr, cmpv, newv, oi, ra);
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
+ }
50
+
74
+
51
+ env->xregs[rs] = int128_getlo(oldv);
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
52
+ env->xregs[rs + 1] = int128_gethi(oldv);
76
+
53
+#endif
77
+ return vec->enabled &&
78
+ exc_group_prio(s, vec->prio, secure) < running;
54
+}
79
+}
55
+
80
+
56
+void HELPER(casp_be_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
81
/* callback when external interrupt line is changed */
57
+ uint64_t new_hi, uint64_t new_lo)
82
static void set_irq_level(void *opaque, int n, int level)
83
{
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/helper.c
87
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
89
env->thumb = addr & 1;
90
}
91
92
+static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
93
+ bool apply_splim)
58
+{
94
+{
59
+ uintptr_t ra = GETPC();
95
+ /*
60
+#ifndef CONFIG_ATOMIC128
96
+ * Like the pseudocode UpdateFPCCR: save state in FPCAR and FPCCR
61
+ cpu_loop_exit_atomic(ENV_GET_CPU(env), ra);
97
+ * that we will need later in order to do lazy FP reg stacking.
62
+#else
98
+ */
63
+ Int128 oldv, cmpv, newv;
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;
64
+
111
+
65
+ cmpv = int128_make128(env->xregs[rs + 1], env->xregs[rs]);
112
+ env->v7m.fpcar[is_secure] = frameptr & ~0x7;
66
+ newv = int128_make128(new_lo, new_hi);
67
+
113
+
68
+ int mem_idx = cpu_mmu_index(env, false);
114
+ if (apply_splim && arm_feature(env, ARM_FEATURE_V8)) {
69
+ TCGMemOpIdx oi = make_memop_idx(MO_LEQ | MO_ALIGN_16, mem_idx);
115
+ bool splimviol;
70
+ oldv = helper_atomic_cmpxchgo_be_mmu(env, addr, cmpv, newv, oi, ra);
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);
71
+
119
+
72
+ env->xregs[rs + 1] = int128_getlo(oldv);
120
+ splimviol = !ign && frameptr < splim;
73
+ env->xregs[rs] = int128_gethi(oldv);
121
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, SPLIMVIOL, splimviol);
74
+#endif
75
+}
76
+
77
/*
78
* AdvSIMD half-precision
79
*/
80
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/translate-a64.c
83
+++ b/target/arm/translate-a64.c
84
@@ -XXX,XX +XXX,XX @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
85
tcg_gen_movi_i64(cpu_exclusive_addr, -1);
86
}
87
88
+static void gen_compare_and_swap(DisasContext *s, int rs, int rt,
89
+ int rn, int size)
90
+{
91
+ TCGv_i64 tcg_rs = cpu_reg(s, rs);
92
+ TCGv_i64 tcg_rt = cpu_reg(s, rt);
93
+ int memidx = get_mem_index(s);
94
+ TCGv_i64 addr = cpu_reg_sp(s, rn);
95
+
96
+ if (rn == 31) {
97
+ gen_check_sp_alignment(s);
98
+ }
99
+ tcg_gen_atomic_cmpxchg_i64(tcg_rs, addr, tcg_rs, tcg_rt, memidx,
100
+ size | MO_ALIGN | s->be_data);
101
+}
102
+
103
+static void gen_compare_and_swap_pair(DisasContext *s, int rs, int rt,
104
+ int rn, int size)
105
+{
106
+ TCGv_i64 s1 = cpu_reg(s, rs);
107
+ TCGv_i64 s2 = cpu_reg(s, rs + 1);
108
+ TCGv_i64 t1 = cpu_reg(s, rt);
109
+ TCGv_i64 t2 = cpu_reg(s, rt + 1);
110
+ TCGv_i64 addr = cpu_reg_sp(s, rn);
111
+ int memidx = get_mem_index(s);
112
+
113
+ if (rn == 31) {
114
+ gen_check_sp_alignment(s);
115
+ }
122
+ }
116
+
123
+
117
+ if (size == 2) {
124
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, LSPACT, 1);
118
+ TCGv_i64 cmp = tcg_temp_new_i64();
119
+ TCGv_i64 val = tcg_temp_new_i64();
120
+
125
+
121
+ if (s->be_data == MO_LE) {
126
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, S, is_secure);
122
+ tcg_gen_concat32_i64(val, t1, t2);
123
+ tcg_gen_concat32_i64(cmp, s1, s2);
124
+ } else {
125
+ tcg_gen_concat32_i64(val, t2, t1);
126
+ tcg_gen_concat32_i64(cmp, s2, s1);
127
+ }
128
+
127
+
129
+ tcg_gen_atomic_cmpxchg_i64(cmp, addr, cmp, val, memidx,
128
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, USER, arm_current_el(env) == 0);
130
+ MO_64 | MO_ALIGN | s->be_data);
131
+ tcg_temp_free_i64(val);
132
+
129
+
133
+ if (s->be_data == MO_LE) {
130
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, THREAD,
134
+ tcg_gen_extr32_i64(s1, s2, cmp);
131
+ !arm_v7m_is_handler_mode(env));
135
+ } else {
136
+ tcg_gen_extr32_i64(s2, s1, cmp);
137
+ }
138
+ tcg_temp_free_i64(cmp);
139
+ } else if (tb_cflags(s->base.tb) & CF_PARALLEL) {
140
+ TCGv_i32 tcg_rs = tcg_const_i32(rs);
141
+
132
+
142
+ if (s->be_data == MO_LE) {
133
+ hfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_HARD, false);
143
+ gen_helper_casp_le_parallel(cpu_env, tcg_rs, addr, t1, t2);
134
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
144
+ } else {
145
+ gen_helper_casp_be_parallel(cpu_env, tcg_rs, addr, t1, t2);
146
+ }
147
+ tcg_temp_free_i32(tcg_rs);
148
+ } else {
149
+ TCGv_i64 d1 = tcg_temp_new_i64();
150
+ TCGv_i64 d2 = tcg_temp_new_i64();
151
+ TCGv_i64 a2 = tcg_temp_new_i64();
152
+ TCGv_i64 c1 = tcg_temp_new_i64();
153
+ TCGv_i64 c2 = tcg_temp_new_i64();
154
+ TCGv_i64 zero = tcg_const_i64(0);
155
+
135
+
156
+ /* Load the two words, in memory order. */
136
+ bfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_BUS, false);
157
+ tcg_gen_qemu_ld_i64(d1, addr, memidx,
137
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
158
+ MO_64 | MO_ALIGN_16 | s->be_data);
159
+ tcg_gen_addi_i64(a2, addr, 8);
160
+ tcg_gen_qemu_ld_i64(d2, addr, memidx, MO_64 | s->be_data);
161
+
138
+
162
+ /* Compare the two words, also in memory order. */
139
+ mmrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_MEM, is_secure);
163
+ tcg_gen_setcond_i64(TCG_COND_EQ, c1, d1, s1);
140
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, MMRDY, mmrdy);
164
+ tcg_gen_setcond_i64(TCG_COND_EQ, c2, d2, s2);
165
+ tcg_gen_and_i64(c2, c2, c1);
166
+
141
+
167
+ /* If compare equal, write back new data, else write back old data. */
142
+ ns_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, false);
168
+ tcg_gen_movcond_i64(TCG_COND_NE, c1, c2, zero, t1, d1);
143
+ *fpccr_ns = FIELD_DP32(*fpccr_ns, V7M_FPCCR, UFRDY, ns_ufrdy);
169
+ tcg_gen_movcond_i64(TCG_COND_NE, c2, c2, zero, t2, d2);
170
+ tcg_gen_qemu_st_i64(c1, addr, memidx, MO_64 | s->be_data);
171
+ tcg_gen_qemu_st_i64(c2, a2, memidx, MO_64 | s->be_data);
172
+ tcg_temp_free_i64(a2);
173
+ tcg_temp_free_i64(c1);
174
+ tcg_temp_free_i64(c2);
175
+ tcg_temp_free_i64(zero);
176
+
144
+
177
+ /* Write back the data from memory to Rs. */
145
+ monrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_DEBUG, false);
178
+ tcg_gen_mov_i64(s1, d1);
146
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, MONRDY, monrdy);
179
+ tcg_gen_mov_i64(s2, d2);
147
+
180
+ tcg_temp_free_i64(d1);
148
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
181
+ tcg_temp_free_i64(d2);
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);
182
+ }
154
+ }
183
+}
155
+}
184
+
156
+
185
/* Update the Sixty-Four bit (SF) registersize. This logic is derived
157
static bool v7m_push_stack(ARMCPU *cpu)
186
* from the ARMv8 specs for LDR (Shared decode for all encodings).
158
{
187
*/
159
/* Do the "set up stack frame" part of exception entry,
188
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
160
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
189
gen_store_exclusive(s, rs, rt, rt2, tcg_addr, size, true);
161
}
190
return;
162
} else {
163
/* Lazy stacking enabled, save necessary info to stack later */
164
- /* TODO : equivalent of UpdateFPCCR() pseudocode */
165
+ v7m_update_fpccr(env, frameptr + 0x20, true);
166
}
191
}
167
}
192
- /* CASP / CASPL */
193
+ if (rt2 == 31
194
+ && ((rt | rs) & 1) == 0
195
+ && arm_dc_feature(s, ARM_FEATURE_V8_ATOMICS)) {
196
+ /* CASP / CASPL */
197
+ gen_compare_and_swap_pair(s, rs, rt, rn, size | 2);
198
+ return;
199
+ }
200
break;
201
202
- case 0x6: case 0x7: /* CASP / LDXP */
203
+ case 0x6: case 0x7: /* CASPA / LDXP */
204
if (size & 2) { /* LDXP / LDAXP */
205
if (rn == 31) {
206
gen_check_sp_alignment(s);
207
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
208
}
209
return;
210
}
211
- /* CASPA / CASPAL */
212
+ if (rt2 == 31
213
+ && ((rt | rs) & 1) == 0
214
+ && arm_dc_feature(s, ARM_FEATURE_V8_ATOMICS)) {
215
+ /* CASPA / CASPAL */
216
+ gen_compare_and_swap_pair(s, rs, rt, rn, size | 2);
217
+ return;
218
+ }
219
break;
220
221
case 0xa: /* CAS */
222
case 0xb: /* CASL */
223
case 0xe: /* CASA */
224
case 0xf: /* CASAL */
225
+ if (rt2 == 31 && arm_dc_feature(s, ARM_FEATURE_V8_ATOMICS)) {
226
+ gen_compare_and_swap(s, rs, rt, rn, size);
227
+ return;
228
+ }
229
break;
230
}
168
}
231
unallocated_encoding(s);
232
--
169
--
233
2.17.0
170
2.20.1
234
171
235
172
diff view generated by jsdifflib
New 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.)
1
5
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
New 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.
1
5
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
New patch
1
The magic value pushed onto the callee stack as an integrity
2
check is different if floating point is present.
1
3
4
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
---
8
target/arm/helper.c | 22 +++++++++++++++++++---
9
1 file changed, 19 insertions(+), 3 deletions(-)
10
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
14
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@ load_fail:
16
return false;
17
}
18
19
+static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
20
+{
21
+ /*
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
+}
33
+
34
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
35
bool ignore_faults)
36
{
37
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
38
bool stacked_ok;
39
uint32_t limit;
40
bool want_psp;
41
+ uint32_t sig;
42
43
if (dotailchain) {
44
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
45
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
46
/* Write as much of the stack frame as we can. A write failure may
47
* cause us to pend a derived exception.
48
*/
49
+ sig = v7m_integrity_sig(env, lr);
50
stacked_ok =
51
- v7m_stack_write(cpu, frameptr, 0xfefa125b, mmu_idx, ignore_faults) &&
52
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
53
v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
54
ignore_faults) &&
55
v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
56
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
57
if (return_to_secure &&
58
((excret & R_V7M_EXCRET_ES_MASK) == 0 ||
59
(excret & R_V7M_EXCRET_DCRS_MASK) == 0)) {
60
- uint32_t expected_sig = 0xfefa125b;
61
uint32_t actual_sig;
62
63
pop_ok = v7m_stack_read(cpu, &actual_sig, frameptr, mmu_idx);
64
65
- if (pop_ok && expected_sig != actual_sig) {
66
+ if (pop_ok && v7m_integrity_sig(env, excret) != actual_sig) {
67
/* Take a SecureFault on the current stack */
68
env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK;
69
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
70
--
71
2.20.1
72
73
diff view generated by jsdifflib
New patch
1
Handle floating point registers in exception return.
2
This corresponds to pseudocode functions ValidateExceptionReturn(),
3
ExceptionReturn(), PopStack() and ConsumeExcStackFrame().
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190416125744.27770-16-peter.maydell@linaro.org
8
---
9
target/arm/helper.c | 142 +++++++++++++++++++++++++++++++++++++++++++-
10
1 file changed, 141 insertions(+), 1 deletion(-)
11
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
17
bool rettobase = false;
18
bool exc_secure = false;
19
bool return_to_secure;
20
+ bool ftype;
21
+ bool restore_s16_s31;
22
23
/* If we're not in Handler mode then jumps to magic exception-exit
24
* addresses don't have magic behaviour. However for the v8M
25
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
26
excret);
27
}
28
29
+ ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
30
+
31
+ if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
32
+ qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
33
+ "exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
34
+ "if FPU not present\n",
35
+ excret);
36
+ ftype = true;
37
+ }
38
+
39
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
40
/* EXC_RETURN.ES validation check (R_SMFL). We must do this before
41
* we pick which FAULTMASK to clear.
42
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
43
*/
44
write_v7m_control_spsel_for_secstate(env, return_to_sp_process, exc_secure);
45
46
+ /*
47
+ * Clear scratch FP values left in caller saved registers; this
48
+ * must happen before any kind of tail chaining.
49
+ */
50
+ if ((env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_CLRONRET_MASK) &&
51
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
52
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
53
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
54
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
55
+ qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
56
+ "stackframe: error during lazy state deactivation\n");
57
+ v7m_exception_taken(cpu, excret, true, false);
58
+ return;
59
+ } else {
60
+ /* Clear s0..s15 and FPSCR */
61
+ int i;
62
+
63
+ for (i = 0; i < 16; i += 2) {
64
+ *aa32_vfp_dreg(env, i / 2) = 0;
65
+ }
66
+ vfp_set_fpscr(env, 0);
67
+ }
68
+ }
69
+
70
if (sfault) {
71
env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
72
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
73
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
74
}
75
}
76
77
+ if (!ftype) {
78
+ /* FP present and we need to handle it */
79
+ if (!return_to_secure &&
80
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK)) {
81
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
82
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
83
+ qemu_log_mask(CPU_LOG_INT,
84
+ "...taking SecureFault on existing stackframe: "
85
+ "Secure LSPACT set but exception return is "
86
+ "not to secure state\n");
87
+ v7m_exception_taken(cpu, excret, true, false);
88
+ return;
89
+ }
90
+
91
+ restore_s16_s31 = return_to_secure &&
92
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
93
+
94
+ if (env->v7m.fpccr[return_to_secure] & R_V7M_FPCCR_LSPACT_MASK) {
95
+ /* State in FPU is still valid, just clear LSPACT */
96
+ env->v7m.fpccr[return_to_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
97
+ } else {
98
+ int i;
99
+ uint32_t fpscr;
100
+ bool cpacr_pass, nsacr_pass;
101
+
102
+ cpacr_pass = v7m_cpacr_pass(env, return_to_secure,
103
+ return_to_priv);
104
+ nsacr_pass = return_to_secure ||
105
+ extract32(env->v7m.nsacr, 10, 1);
106
+
107
+ if (!cpacr_pass) {
108
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
109
+ return_to_secure);
110
+ env->v7m.cfsr[return_to_secure] |= R_V7M_CFSR_NOCP_MASK;
111
+ qemu_log_mask(CPU_LOG_INT,
112
+ "...taking UsageFault on existing "
113
+ "stackframe: CPACR.CP10 prevents unstacking "
114
+ "FP regs\n");
115
+ v7m_exception_taken(cpu, excret, true, false);
116
+ return;
117
+ } else if (!nsacr_pass) {
118
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, true);
119
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_INVPC_MASK;
120
+ qemu_log_mask(CPU_LOG_INT,
121
+ "...taking Secure UsageFault on existing "
122
+ "stackframe: NSACR.CP10 prevents unstacking "
123
+ "FP regs\n");
124
+ v7m_exception_taken(cpu, excret, true, false);
125
+ return;
126
+ }
127
+
128
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
129
+ uint32_t slo, shi;
130
+ uint64_t dn;
131
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
132
+
133
+ if (i >= 16) {
134
+ faddr += 8; /* Skip the slot for the FPSCR */
135
+ }
136
+
137
+ pop_ok = pop_ok &&
138
+ v7m_stack_read(cpu, &slo, faddr, mmu_idx) &&
139
+ v7m_stack_read(cpu, &shi, faddr + 4, mmu_idx);
140
+
141
+ if (!pop_ok) {
142
+ break;
143
+ }
144
+
145
+ dn = (uint64_t)shi << 32 | slo;
146
+ *aa32_vfp_dreg(env, i / 2) = dn;
147
+ }
148
+ pop_ok = pop_ok &&
149
+ v7m_stack_read(cpu, &fpscr, frameptr + 0x60, mmu_idx);
150
+ if (pop_ok) {
151
+ vfp_set_fpscr(env, fpscr);
152
+ }
153
+ if (!pop_ok) {
154
+ /*
155
+ * These regs are 0 if security extension present;
156
+ * otherwise merely UNKNOWN. We zero always.
157
+ */
158
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
159
+ *aa32_vfp_dreg(env, i / 2) = 0;
160
+ }
161
+ vfp_set_fpscr(env, 0);
162
+ }
163
+ }
164
+ }
165
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
166
+ V7M_CONTROL, FPCA, !ftype);
167
+
168
/* Commit to consuming the stack frame */
169
frameptr += 0x20;
170
+ if (!ftype) {
171
+ frameptr += 0x48;
172
+ if (restore_s16_s31) {
173
+ frameptr += 0x40;
174
+ }
175
+ }
176
/* Undo stack alignment (the SPREALIGN bit indicates that the original
177
* pre-exception SP was not 8-aligned and we added a padding word to
178
* align it, so we undo this by ORing in the bit that increases it
179
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
180
*frame_sp_p = frameptr;
181
}
182
/* This xpsr_write() will invalidate frame_sp_p as it may switch stack */
183
- xpsr_write(env, xpsr, ~XPSR_SPREALIGN);
184
+ xpsr_write(env, xpsr, ~(XPSR_SPREALIGN | XPSR_SFPA));
185
+
186
+ if (env->v7m.secure) {
187
+ bool sfpa = xpsr & XPSR_SFPA;
188
+
189
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
190
+ V7M_CONTROL, SFPA, sfpa);
191
+ }
192
193
/* The restored xPSR exception field will be zero if we're
194
* resuming in Thread mode. If that doesn't match what the
195
--
196
2.20.1
197
198
diff view generated by jsdifflib
New patch
1
Move the NS TBFLAG down from bit 19 to bit 6, which has not
2
been used since commit c1e3781090b9d36c60 in 2015, when we
3
started passing the entire MMU index in the TB flags rather
4
than just a 'privilege level' bit.
1
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
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190416125744.27770-17-peter.maydell@linaro.org
13
---
14
target/arm/cpu.h | 11 ++++++-----
15
1 file changed, 6 insertions(+), 5 deletions(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
25
+/*
26
+ * Indicates whether cp register reads and writes by guest code should access
27
+ * the secure or nonsecure bank of banked registers; note that this is not
28
+ * the same thing as the current security state of the processor!
29
+ */
30
+FIELD(TBFLAG_A32, NS, 6, 1)
31
FIELD(TBFLAG_A32, VFPEN, 7, 1)
32
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
33
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
* checks on the other bits at runtime
36
*/
37
FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
38
-/* Indicates whether cp register reads and writes by guest code should access
39
- * the secure or nonsecure bank of banked registers; note that this is not
40
- * the same thing as the current security state of the processor!
41
- */
42
-FIELD(TBFLAG_A32, NS, 19, 1)
43
/* For M profile only, Handler (ie not Thread) mode */
44
FIELD(TBFLAG_A32, HANDLER, 21, 1)
45
/* For M profile only, whether we should generate stack-limit checks */
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
New patch
1
We are close to running out of TB flags for AArch32; we could
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.
1
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-18-peter.maydell@linaro.org
10
---
11
target/arm/cpu.h | 10 ++++++----
12
target/arm/cpu.c | 7 +++++++
13
target/arm/helper.c | 6 +++++-
14
target/arm/translate.c | 9 +++++++--
15
4 files changed, 25 insertions(+), 7 deletions(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
25
+/*
26
+ * We store the bottom two bits of the CPAR as TB flags and handle
27
+ * checks on the other bits at runtime. This shares the same bits as
28
+ * VECSTRIDE, which is OK as no XScale CPU has VFP.
29
+ */
30
+FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
31
/*
32
* Indicates whether cp register reads and writes by guest code should access
33
* the secure or nonsecure bank of banked registers; note that this is not
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
35
FIELD(TBFLAG_A32, VFPEN, 7, 1)
36
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
37
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
38
-/* We store the bottom two bits of the CPAR as TB flags and handle
39
- * checks on the other bits at runtime
40
- */
41
-FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
42
/* For M profile only, Handler (ie not Thread) mode */
43
FIELD(TBFLAG_A32, HANDLER, 21, 1)
44
/* For M profile only, whether we should generate stack-limit checks */
45
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/cpu.c
48
+++ b/target/arm/cpu.c
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
50
set_feature(env, ARM_FEATURE_THUMB_DSP);
51
}
52
53
+ /*
54
+ * We rely on no XScale CPU having VFP so we can use the same bits in the
55
+ * TB flags field for VECSTRIDE and XSCALE_CPAR.
56
+ */
57
+ assert(!(arm_feature(env, ARM_FEATURE_VFP) &&
58
+ arm_feature(env, ARM_FEATURE_XSCALE)));
59
+
60
if (arm_feature(env, ARM_FEATURE_V7) &&
61
!arm_feature(env, ARM_FEATURE_M) &&
62
!arm_feature(env, ARM_FEATURE_PMSA)) {
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/helper.c
66
+++ b/target/arm/helper.c
67
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
68
|| arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
69
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
70
}
71
- flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
72
+ /* Note that XSCALE_CPAR shares bits with VECSTRIDE */
73
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
74
+ flags = FIELD_DP32(flags, TBFLAG_A32,
75
+ XSCALE_CPAR, env->cp15.c15_cpar);
76
+ }
77
}
78
79
flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
80
diff --git a/target/arm/translate.c b/target/arm/translate.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/translate.c
83
+++ b/target/arm/translate.c
84
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
85
dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
86
dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
87
dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
88
- dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
89
- dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
90
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
91
+ dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
92
+ dc->vec_stride = 0;
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
--
101
2.20.1
102
103
diff view generated by jsdifflib
1
From: Igor Mammedov <imammedo@redhat.com>
1
The M-profile FPCCR.S bit indicates the security status of
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.
2
6
3
load_dtb() depends on arm_load_kernel() to figure out place
7
Implement this by adding a new TB flag which tracks whether
4
in RAM where it should be loaded, but it's not required for
8
FPCCR.S is different from the current security state, so
5
arm_load_kernel() to work. Sometimes it's neccesary for
9
that we only need to emit the code to update it in the
6
devices added with -device/device_add to be enumerated in
10
less-common case when it is not already set correctly.
7
DTB as well, which's lead to [1] and surrounding commits to
8
add 2 more machine_done notifiers with non obvious ordering
9
to make dynamic sysbus devices initialization happen in
10
the right order.
11
11
12
However instead of moving whole arm_load_kernel() in to
12
Note that we will add the handling for the other work done
13
machine_done, it's sufficient to move only load_dtb() into
13
by ExecuteFPCheck() in later commits.
14
virt_machine_done() notifier and remove ArmLoadKernelNotifier/
15
/PlatformBusFDTNotifierParams notifiers, which saves us ~90LOC
16
and simplifies code flow quite a bit.
17
Later would allow to consolidate DTB generation within one
18
function for 'mach-virt' board and make it reentrant so it
19
could generate updated DTB in device hotplug secenarios.
20
14
21
While at it rename load_dtb() to arm_load_dtb() since it's
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
public now.
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(+)
23
24
24
Add additional field skip_dtb_autoload to struct arm_boot_info
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
25
to allow manual DTB load later in mach-virt and to avoid touching
26
all other boards to explicitly call arm_load_dtb().
27
28
1) (ac9d32e hw/arm/boot: arm_load_kernel implemented as a machine init done notifier)
29
30
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
31
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
32
Reviewed-by: Andrew Jones <drjones@redhat.com>
33
Message-id: 1525691524-32265-4-git-send-email-imammedo@redhat.com
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
---
36
include/hw/arm/arm.h | 45 +++++++++++++++++------
37
include/hw/arm/sysbus-fdt.h | 37 ++++---------------
38
hw/arm/boot.c | 72 ++++++++++---------------------------
39
hw/arm/sysbus-fdt.c | 61 +++----------------------------
40
hw/arm/virt.c | 64 ++++++++++++++++-----------------
41
5 files changed, 94 insertions(+), 185 deletions(-)
42
43
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
44
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
45
--- a/include/hw/arm/arm.h
27
--- a/target/arm/cpu.h
46
+++ b/include/hw/arm/arm.h
28
+++ b/target/arm/cpu.h
47
@@ -XXX,XX +XXX,XX @@ DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
29
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
48
*/
30
FIELD(TBFLAG_A32, VFPEN, 7, 1)
49
void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size);
31
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
50
32
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
51
-/*
33
+/* For M profile only, set if FPCCR.S does not match current security state */
52
- * struct used as a parameter of the arm_load_kernel machine init
34
+FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
53
- * done notifier
35
/* For M profile only, Handler (ie not Thread) mode */
54
- */
36
FIELD(TBFLAG_A32, HANDLER, 21, 1)
55
-typedef struct {
37
/* For M profile only, whether we should generate stack-limit checks */
56
- Notifier notifier; /* actual notifier */
38
diff --git a/target/arm/translate.h b/target/arm/translate.h
57
- ARMCPU *cpu; /* handle to the first cpu object */
39
index XXXXXXX..XXXXXXX 100644
58
-} ArmLoadKernelNotifier;
40
--- a/target/arm/translate.h
59
-
41
+++ b/target/arm/translate.h
60
/* arm_boot.c */
42
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
61
struct arm_boot_info {
43
bool v7m_handler_mode;
62
uint64_t ram_size;
44
bool v8m_secure; /* true if v8M and we're in Secure mode */
63
@@ -XXX,XX +XXX,XX @@ struct arm_boot_info {
45
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
64
const char *initrd_filename;
46
+ bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
65
const char *dtb_filename;
47
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
66
hwaddr loader_start;
48
* so that top level loop can generate correct syndrome information.
67
+ hwaddr dtb_start;
68
+ hwaddr dtb_limit;
69
+ /* If set to True, arm_load_kernel() will not load DTB.
70
+ * It allows board to load DTB manually later.
71
+ * (default: False)
72
+ */
73
+ bool skip_dtb_autoload;
74
/* multicore boards that use the default secondary core boot functions
75
* need to put the address of the secondary boot code, the boot reg,
76
* and the GIC address in the next 3 values, respectively. boards that
77
@@ -XXX,XX +XXX,XX @@ struct arm_boot_info {
78
* the user it should implement this hook.
79
*/
49
*/
80
void (*modify_dtb)(const struct arm_boot_info *info, void *fdt);
50
diff --git a/target/arm/helper.c b/target/arm/helper.c
81
- /* machine init done notifier executing arm_load_dtb */
51
index XXXXXXX..XXXXXXX 100644
82
- ArmLoadKernelNotifier load_kernel_notifier;
52
--- a/target/arm/helper.c
83
/* Used internally by arm_boot.c */
53
+++ b/target/arm/helper.c
84
int is_linux;
54
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
85
hwaddr initrd_start;
55
flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
86
@@ -XXX,XX +XXX,XX @@ struct arm_boot_info {
56
}
87
*/
57
88
void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info);
58
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
89
59
+ FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
90
+AddressSpace *arm_boot_address_space(ARMCPU *cpu,
60
+ flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
91
+ const struct arm_boot_info *info);
61
+ }
92
+
62
+
93
+/**
63
*pflags = flags;
94
+ * arm_load_dtb() - load a device tree binary image into memory
64
*cs_base = 0;
95
+ * @addr: the address to load the image at
65
}
96
+ * @binfo: struct describing the boot environment
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
+ * @addr_limit: upper limit of the available memory area at @addr
98
+ * @as: address space to load image to
99
+ *
100
+ * Load a device tree supplied by the machine or by the user with the
101
+ * '-dtb' command line option, and put it at offset @addr in target
102
+ * memory.
103
+ *
104
+ * If @addr_limit contains a meaningful value (i.e., it is strictly greater
105
+ * than @addr), the device tree is only loaded if its size does not exceed
106
+ * the limit.
107
+ *
108
+ * Returns: the size of the device tree image on success,
109
+ * 0 if the image size exceeds the limit,
110
+ * -1 on errors.
111
+ *
112
+ * Note: Must not be called unless have_dtb(binfo) is true.
113
+ */
114
+int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
115
+ hwaddr addr_limit, AddressSpace *as);
116
+
117
/* Write a secure board setup routine with a dummy handler for SMCs */
118
void arm_write_secure_board_setup_dummy_smc(ARMCPU *cpu,
119
const struct arm_boot_info *info,
120
diff --git a/include/hw/arm/sysbus-fdt.h b/include/hw/arm/sysbus-fdt.h
121
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
122
--- a/include/hw/arm/sysbus-fdt.h
68
--- a/target/arm/translate.c
123
+++ b/include/hw/arm/sysbus-fdt.h
69
+++ b/target/arm/translate.c
124
@@ -XXX,XX +XXX,XX @@
70
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
125
#ifndef HW_ARM_SYSBUS_FDT_H
126
#define HW_ARM_SYSBUS_FDT_H
127
128
-#include "hw/arm/arm.h"
129
-#include "qemu-common.h"
130
-#include "hw/sysbus.h"
131
-
132
-/*
133
- * struct that contains dimensioning parameters of the platform bus
134
- */
135
-typedef struct {
136
- hwaddr platform_bus_base; /* start address of the bus */
137
- hwaddr platform_bus_size; /* size of the bus */
138
- int platform_bus_first_irq; /* first hwirq assigned to the bus */
139
- int platform_bus_num_irqs; /* number of hwirq assigned to the bus */
140
-} ARMPlatformBusSystemParams;
141
-
142
-/*
143
- * struct that contains all relevant info to build the fdt nodes of
144
- * platform bus and attached dynamic sysbus devices
145
- * in the future might be augmented with additional info
146
- * such as PHY, CLK handles ...
147
- */
148
-typedef struct {
149
- const ARMPlatformBusSystemParams *system_params;
150
- struct arm_boot_info *binfo;
151
- const char *intc; /* parent interrupt controller name */
152
-} ARMPlatformBusFDTParams;
153
+#include "exec/hwaddr.h"
154
155
/**
156
- * arm_register_platform_bus_fdt_creator - register a machine init done
157
- * notifier that creates the device tree nodes of the platform bus and
158
- * associated dynamic sysbus devices
159
+ * platform_bus_add_all_fdt_nodes - create all the platform bus nodes
160
+ *
161
+ * builds the parent platform bus node and all the nodes of dynamic
162
+ * sysbus devices attached to it.
163
*/
164
-void arm_register_platform_bus_fdt_creator(ARMPlatformBusFDTParams *fdt_params);
165
-
166
+void platform_bus_add_all_fdt_nodes(void *fdt, const char *intc, hwaddr addr,
167
+ hwaddr bus_size, int irq_start);
168
#endif
169
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
170
index XXXXXXX..XXXXXXX 100644
171
--- a/hw/arm/boot.c
172
+++ b/hw/arm/boot.c
173
@@ -XXX,XX +XXX,XX @@
174
#define ARM64_TEXT_OFFSET_OFFSET 8
175
#define ARM64_MAGIC_OFFSET 56
176
177
-static AddressSpace *arm_boot_address_space(ARMCPU *cpu,
178
- const struct arm_boot_info *info)
179
+AddressSpace *arm_boot_address_space(ARMCPU *cpu,
180
+ const struct arm_boot_info *info)
181
{
182
/* Return the address space to use for bootloader reads and writes.
183
* We prefer the secure address space if the CPU has it and we're
184
@@ -XXX,XX +XXX,XX @@ static void fdt_add_psci_node(void *fdt)
185
qemu_fdt_setprop_cell(fdt, "/psci", "migrate", migrate_fn);
186
}
187
188
-/**
189
- * load_dtb() - load a device tree binary image into memory
190
- * @addr: the address to load the image at
191
- * @binfo: struct describing the boot environment
192
- * @addr_limit: upper limit of the available memory area at @addr
193
- * @as: address space to load image to
194
- *
195
- * Load a device tree supplied by the machine or by the user with the
196
- * '-dtb' command line option, and put it at offset @addr in target
197
- * memory.
198
- *
199
- * If @addr_limit contains a meaningful value (i.e., it is strictly greater
200
- * than @addr), the device tree is only loaded if its size does not exceed
201
- * the limit.
202
- *
203
- * Returns: the size of the device tree image on success,
204
- * 0 if the image size exceeds the limit,
205
- * -1 on errors.
206
- *
207
- * Note: Must not be called unless have_dtb(binfo) is true.
208
- */
209
-static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
210
- hwaddr addr_limit, AddressSpace *as)
211
+int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
212
+ hwaddr addr_limit, AddressSpace *as)
213
{
214
void *fdt = NULL;
215
int size, rc;
216
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
217
return size;
218
}
219
220
-static void arm_load_kernel_notify(Notifier *notifier, void *data)
221
+void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
222
{
223
CPUState *cs;
224
int kernel_size;
225
@@ -XXX,XX +XXX,XX @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
226
int elf_machine;
227
hwaddr entry;
228
static const ARMInsnFixup *primary_loader;
229
- ArmLoadKernelNotifier *n = DO_UPCAST(ArmLoadKernelNotifier,
230
- notifier, notifier);
231
- ARMCPU *cpu = n->cpu;
232
- struct arm_boot_info *info =
233
- container_of(n, struct arm_boot_info, load_kernel_notifier);
234
AddressSpace *as = arm_boot_address_space(cpu, info);
235
236
/* The board code is not supposed to set secure_board_setup unless
237
@@ -XXX,XX +XXX,XX @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
238
assert(!(info->secure_board_setup && kvm_enabled()));
239
240
info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
241
+ info->dtb_limit = 0;
242
243
/* Load the kernel. */
244
if (!info->kernel_filename || info->firmware_loaded) {
245
@@ -XXX,XX +XXX,XX @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
246
* the kernel is supposed to be loaded by the bootloader), copy the
247
* DTB to the base of RAM for the bootloader to pick up.
248
*/
249
- if (load_dtb(info->loader_start, info, 0, as) < 0) {
250
- exit(1);
251
- }
252
+ info->dtb_start = info->loader_start;
253
}
254
255
if (info->kernel_filename) {
256
@@ -XXX,XX +XXX,XX @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
257
*/
258
if (elf_low_addr > info->loader_start
259
|| elf_high_addr < info->loader_start) {
260
- /* Pass elf_low_addr as address limit to load_dtb if it may be
261
+ /* Set elf_low_addr as address limit for arm_load_dtb if it may be
262
* pointing into RAM, otherwise pass '0' (no limit)
263
*/
264
if (elf_low_addr < info->loader_start) {
265
elf_low_addr = 0;
266
}
267
- if (load_dtb(info->loader_start, info, elf_low_addr, as) < 0) {
268
- exit(1);
269
- }
270
+ info->dtb_start = info->loader_start;
271
+ info->dtb_limit = elf_low_addr;
272
}
71
}
273
}
72
}
274
entry = elf_entry;
73
275
@@ -XXX,XX +XXX,XX @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
74
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
276
*/
75
+ /* Handle M-profile lazy FP state mechanics */
277
if (have_dtb(info)) {
278
hwaddr align;
279
- hwaddr dtb_start;
280
281
if (elf_machine == EM_AARCH64) {
282
/*
283
@@ -XXX,XX +XXX,XX @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
284
}
285
286
/* Place the DTB after the initrd in memory with alignment. */
287
- dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size, align);
288
- if (load_dtb(dtb_start, info, 0, as) < 0) {
289
- exit(1);
290
- }
291
- fixupcontext[FIXUP_ARGPTR] = dtb_start;
292
+ info->dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size,
293
+ align);
294
+ fixupcontext[FIXUP_ARGPTR] = info->dtb_start;
295
} else {
296
fixupcontext[FIXUP_ARGPTR] = info->loader_start + KERNEL_ARGS_ADDR;
297
if (info->ram_size >= (1ULL << 32)) {
298
@@ -XXX,XX +XXX,XX @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
299
for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
300
ARM_CPU(cs)->env.boot_info = info;
301
}
302
-}
303
-
304
-void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
305
-{
306
- CPUState *cs;
307
-
308
- info->load_kernel_notifier.cpu = cpu;
309
- info->load_kernel_notifier.notifier.notify = arm_load_kernel_notify;
310
- qemu_add_machine_init_done_notifier(&info->load_kernel_notifier.notifier);
311
312
/* CPU objects (unlike devices) are not automatically reset on system
313
* reset, so we must always register a handler to do so. If we're
314
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
315
for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
316
qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
317
}
318
+
76
+
319
+ if (!info->skip_dtb_autoload && have_dtb(info)) {
77
+ /* Update ownership of FP context: set FPCCR.S to match current state */
320
+ if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as) < 0) {
78
+ if (s->v8m_fpccr_s_wrong) {
321
+ exit(1);
79
+ TCGv_i32 tmp;
80
+
81
+ tmp = load_cpu_field(v7m.fpccr[M_REG_S]);
82
+ if (s->v8m_secure) {
83
+ tcg_gen_ori_i32(tmp, tmp, R_V7M_FPCCR_S_MASK);
84
+ } else {
85
+ tcg_gen_andi_i32(tmp, tmp, ~R_V7M_FPCCR_S_MASK);
86
+ }
87
+ store_cpu_field(tmp, v7m.fpccr[M_REG_S]);
88
+ /* Don't need to do this for any further FP insns in this TB */
89
+ s->v8m_fpccr_s_wrong = false;
322
+ }
90
+ }
323
+ }
91
+ }
324
}
325
326
static const TypeInfo arm_linux_boot_if_info = {
327
diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
328
index XXXXXXX..XXXXXXX 100644
329
--- a/hw/arm/sysbus-fdt.c
330
+++ b/hw/arm/sysbus-fdt.c
331
@@ -XXX,XX +XXX,XX @@ typedef struct PlatformBusFDTData {
332
PlatformBusDevice *pbus;
333
} PlatformBusFDTData;
334
335
-/*
336
- * struct used when calling the machine init done notifier
337
- * that constructs the fdt nodes of platform bus devices
338
- */
339
-typedef struct PlatformBusFDTNotifierParams {
340
- Notifier notifier;
341
- ARMPlatformBusFDTParams *fdt_params;
342
-} PlatformBusFDTNotifierParams;
343
-
344
/* struct that associates a device type name and a node creation function */
345
typedef struct NodeCreationPair {
346
const char *typename;
347
@@ -XXX,XX +XXX,XX @@ static void add_fdt_node(SysBusDevice *sbdev, void *opaque)
348
exit(1);
349
}
350
351
-/**
352
- * add_all_platform_bus_fdt_nodes - create all the platform bus nodes
353
- *
354
- * builds the parent platform bus node and all the nodes of dynamic
355
- * sysbus devices attached to it.
356
- */
357
-static void add_all_platform_bus_fdt_nodes(ARMPlatformBusFDTParams *fdt_params)
358
+void platform_bus_add_all_fdt_nodes(void *fdt, const char *intc, hwaddr addr,
359
+ hwaddr bus_size, int irq_start)
360
{
361
const char platcomp[] = "qemu,platform\0simple-bus";
362
PlatformBusDevice *pbus;
363
DeviceState *dev;
364
gchar *node;
365
- uint64_t addr, size;
366
- int irq_start, dtb_size;
367
- struct arm_boot_info *info = fdt_params->binfo;
368
- const ARMPlatformBusSystemParams *params = fdt_params->system_params;
369
- const char *intc = fdt_params->intc;
370
- void *fdt = info->get_dtb(info, &dtb_size);
371
-
372
- /*
373
- * If the user provided a dtb, we assume the dynamic sysbus nodes
374
- * already are integrated there. This corresponds to a use case where
375
- * the dynamic sysbus nodes are complex and their generation is not yet
376
- * supported. In that case the user can take charge of the guest dt
377
- * while qemu takes charge of the qom stuff.
378
- */
379
- if (info->dtb_filename) {
380
- return;
381
- }
382
383
assert(fdt);
384
385
- node = g_strdup_printf("/platform@%"PRIx64, params->platform_bus_base);
386
- addr = params->platform_bus_base;
387
- size = params->platform_bus_size;
388
- irq_start = params->platform_bus_first_irq;
389
+ node = g_strdup_printf("/platform@%"PRIx64, addr);
390
391
/* Create a /platform node that we can put all devices into */
392
qemu_fdt_add_subnode(fdt, node);
393
@@ -XXX,XX +XXX,XX @@ static void add_all_platform_bus_fdt_nodes(ARMPlatformBusFDTParams *fdt_params)
394
*/
395
qemu_fdt_setprop_cells(fdt, node, "#size-cells", 1);
396
qemu_fdt_setprop_cells(fdt, node, "#address-cells", 1);
397
- qemu_fdt_setprop_cells(fdt, node, "ranges", 0, addr >> 32, addr, size);
398
+ qemu_fdt_setprop_cells(fdt, node, "ranges", 0, addr >> 32, addr, bus_size);
399
400
qemu_fdt_setprop_phandle(fdt, node, "interrupt-parent", intc);
401
402
@@ -XXX,XX +XXX,XX @@ static void add_all_platform_bus_fdt_nodes(ARMPlatformBusFDTParams *fdt_params)
403
404
g_free(node);
405
}
406
-
407
-static void platform_bus_fdt_notify(Notifier *notifier, void *data)
408
-{
409
- PlatformBusFDTNotifierParams *p = DO_UPCAST(PlatformBusFDTNotifierParams,
410
- notifier, notifier);
411
-
412
- add_all_platform_bus_fdt_nodes(p->fdt_params);
413
- g_free(p->fdt_params);
414
- g_free(p);
415
-}
416
-
417
-void arm_register_platform_bus_fdt_creator(ARMPlatformBusFDTParams *fdt_params)
418
-{
419
- PlatformBusFDTNotifierParams *p = g_new(PlatformBusFDTNotifierParams, 1);
420
-
421
- p->fdt_params = fdt_params;
422
- p->notifier.notify = platform_bus_fdt_notify;
423
- qemu_add_machine_init_done_notifier(&p->notifier);
424
-}
425
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
426
index XXXXXXX..XXXXXXX 100644
427
--- a/hw/arm/virt.c
428
+++ b/hw/arm/virt.c
429
@@ -XXX,XX +XXX,XX @@
430
431
#define PLATFORM_BUS_NUM_IRQS 64
432
433
-static ARMPlatformBusSystemParams platform_bus_params;
434
-
435
/* RAM limit in GB. Since VIRT_MEM starts at the 1GB mark, this means
436
* RAM can go up to the 256GB mark, leaving 256GB of the physical
437
* address space unallocated and free for future use between 256G and 512G.
438
@@ -XXX,XX +XXX,XX @@ static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic)
439
DeviceState *dev;
440
SysBusDevice *s;
441
int i;
442
- ARMPlatformBusFDTParams *fdt_params = g_new(ARMPlatformBusFDTParams, 1);
443
MemoryRegion *sysmem = get_system_memory();
444
445
- platform_bus_params.platform_bus_base = vms->memmap[VIRT_PLATFORM_BUS].base;
446
- platform_bus_params.platform_bus_size = vms->memmap[VIRT_PLATFORM_BUS].size;
447
- platform_bus_params.platform_bus_first_irq = vms->irqmap[VIRT_PLATFORM_BUS];
448
- platform_bus_params.platform_bus_num_irqs = PLATFORM_BUS_NUM_IRQS;
449
-
450
- fdt_params->system_params = &platform_bus_params;
451
- fdt_params->binfo = &vms->bootinfo;
452
- fdt_params->intc = "/intc";
453
- /*
454
- * register a machine init done notifier that creates the device tree
455
- * nodes of the platform bus and its children dynamic sysbus devices
456
- */
457
- arm_register_platform_bus_fdt_creator(fdt_params);
458
-
459
dev = qdev_create(NULL, TYPE_PLATFORM_BUS_DEVICE);
460
dev->id = TYPE_PLATFORM_BUS_DEVICE;
461
- qdev_prop_set_uint32(dev, "num_irqs",
462
- platform_bus_params.platform_bus_num_irqs);
463
- qdev_prop_set_uint32(dev, "mmio_size",
464
- platform_bus_params.platform_bus_size);
465
+ qdev_prop_set_uint32(dev, "num_irqs", PLATFORM_BUS_NUM_IRQS);
466
+ qdev_prop_set_uint32(dev, "mmio_size", vms->memmap[VIRT_PLATFORM_BUS].size);
467
qdev_init_nofail(dev);
468
vms->platform_bus_dev = dev;
469
- s = SYS_BUS_DEVICE(dev);
470
471
- for (i = 0; i < platform_bus_params.platform_bus_num_irqs; i++) {
472
- int irqn = platform_bus_params.platform_bus_first_irq + i;
473
+ s = SYS_BUS_DEVICE(dev);
474
+ for (i = 0; i < PLATFORM_BUS_NUM_IRQS; i++) {
475
+ int irqn = vms->irqmap[VIRT_PLATFORM_BUS] + i;
476
sysbus_connect_irq(s, i, pic[irqn]);
477
}
478
479
memory_region_add_subregion(sysmem,
480
- platform_bus_params.platform_bus_base,
481
+ vms->memmap[VIRT_PLATFORM_BUS].base,
482
sysbus_mmio_get_region(s, 0));
483
}
484
485
@@ -XXX,XX +XXX,XX @@ void virt_machine_done(Notifier *notifier, void *data)
486
{
487
VirtMachineState *vms = container_of(notifier, VirtMachineState,
488
machine_done);
489
+ ARMCPU *cpu = ARM_CPU(first_cpu);
490
+ struct arm_boot_info *info = &vms->bootinfo;
491
+ AddressSpace *as = arm_boot_address_space(cpu, info);
492
+
92
+
493
+ /*
93
if (extract32(insn, 28, 4) == 0xf) {
494
+ * If the user provided a dtb, we assume the dynamic sysbus nodes
94
/*
495
+ * already are integrated there. This corresponds to a use case where
95
* Encodings with T=1 (Thumb) or unconditional (ARM):
496
+ * the dynamic sysbus nodes are complex and their generation is not yet
96
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
497
+ * supported. In that case the user can take charge of the guest dt
97
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
498
+ * while qemu takes charge of the qom stuff.
98
regime_is_secure(env, dc->mmu_idx);
499
+ */
99
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
500
+ if (info->dtb_filename == NULL) {
100
+ dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
501
+ platform_bus_add_all_fdt_nodes(vms->fdt, "/intc",
101
dc->cp_regs = cpu->cp_regs;
502
+ vms->memmap[VIRT_PLATFORM_BUS].base,
102
dc->features = env->features;
503
+ vms->memmap[VIRT_PLATFORM_BUS].size,
103
504
+ vms->irqmap[VIRT_PLATFORM_BUS]);
505
+ }
506
+ if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as) < 0) {
507
+ exit(1);
508
+ }
509
510
virt_acpi_setup(vms);
511
virt_build_smbios(vms);
512
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
513
vms->fw_cfg = create_fw_cfg(vms, &address_space_memory);
514
rom_set_fw(vms->fw_cfg);
515
516
- vms->machine_done.notify = virt_machine_done;
517
- qemu_add_machine_init_done_notifier(&vms->machine_done);
518
+ create_platform_bus(vms, pic);
519
520
vms->bootinfo.ram_size = machine->ram_size;
521
vms->bootinfo.kernel_filename = machine->kernel_filename;
522
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
523
vms->bootinfo.board_id = -1;
524
vms->bootinfo.loader_start = vms->memmap[VIRT_MEM].base;
525
vms->bootinfo.get_dtb = machvirt_dtb;
526
+ vms->bootinfo.skip_dtb_autoload = true;
527
vms->bootinfo.firmware_loaded = firmware_loaded;
528
arm_load_kernel(ARM_CPU(first_cpu), &vms->bootinfo);
529
530
- /*
531
- * arm_load_kernel machine init done notifier registration must
532
- * happen before the platform_bus_create call. In this latter,
533
- * another notifier is registered which adds platform bus nodes.
534
- * Notifiers are executed in registration reverse order.
535
- */
536
- create_platform_bus(vms, pic);
537
+ vms->machine_done.notify = virt_machine_done;
538
+ qemu_add_machine_init_done_notifier(&vms->machine_done);
539
}
540
541
static bool virt_get_secure(Object *obj, Error **errp)
542
--
104
--
543
2.17.0
105
2.20.1
544
106
545
107
diff view generated by jsdifflib
1
Coverity (CID1390573) spots that we forgot to free the
1
The M-profile FPCCR.ASPEN bit indicates that automatic floating-point
2
gpioname strings in a loop in the iotkit realize function.
2
context preservation is enabled. Before executing any floating-point
3
Correct the error.
3
instruction, if FPCCR.ASPEN is set and the CONTROL FPCA/SFPA bits
4
indicate that there is no active floating point context then we
5
must create a new context (by initializing FPSCR and setting
6
FPCA/SFPA to indicate that the context is now active). In the
7
pseudocode this is handled by ExecuteFPCheck().
4
8
5
This isn't a significant leak, because this function
9
Implement this with a new TB flag which tracks whether we
6
only ever runs once.
10
need to create a new FP context.
7
11
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Peter Xu <peterx@redhat.com>
14
Message-id: 20190416125744.27770-20-peter.maydell@linaro.org
11
Message-id: 20180427110137.19304-1-peter.maydell@linaro.org
12
---
15
---
13
hw/arm/iotkit.c | 1 +
16
target/arm/cpu.h | 2 ++
14
1 file changed, 1 insertion(+)
17
target/arm/translate.h | 1 +
18
target/arm/helper.c | 13 +++++++++++++
19
target/arm/translate.c | 29 +++++++++++++++++++++++++++++
20
4 files changed, 45 insertions(+)
15
21
16
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/iotkit.c
24
--- a/target/arm/cpu.h
19
+++ b/hw/arm/iotkit.c
25
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
26
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
21
qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), i));
27
FIELD(TBFLAG_A32, VFPEN, 7, 1)
22
qdev_connect_gpio_out_named(DEVICE(ppc), "irq", 0,
28
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
23
qdev_get_gpio_in(devs, 0));
29
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
24
+ g_free(gpioname);
30
+/* For M profile only, set if we must create a new FP context */
31
+FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
32
/* For M profile only, set if FPCCR.S does not match current security state */
33
FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
34
/* For M profile only, Handler (ie not Thread) mode */
35
diff --git a/target/arm/translate.h b/target/arm/translate.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate.h
38
+++ b/target/arm/translate.h
39
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
40
bool v8m_secure; /* true if v8M and we're in Secure mode */
41
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
42
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
43
+ bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
44
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
45
* so that top level loop can generate correct syndrome information.
46
*/
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/helper.c
50
+++ b/target/arm/helper.c
51
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
52
flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
25
}
53
}
26
54
27
iotkit_forward_sec_resp_cfg(s);
55
+ if (arm_feature(env, ARM_FEATURE_M) &&
56
+ (env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
57
+ (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
58
+ (env->v7m.secure &&
59
+ !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) {
60
+ /*
61
+ * ASPEN is set, but FPCA/SFPA indicate that there is no active
62
+ * FP context; we must create a new FP context before executing
63
+ * any FP insn.
64
+ */
65
+ flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
66
+ }
67
+
68
*pflags = flags;
69
*cs_base = 0;
70
}
71
diff --git a/target/arm/translate.c b/target/arm/translate.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/translate.c
74
+++ b/target/arm/translate.c
75
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
76
/* Don't need to do this for any further FP insns in this TB */
77
s->v8m_fpccr_s_wrong = false;
78
}
79
+
80
+ if (s->v7m_new_fp_ctxt_needed) {
81
+ /*
82
+ * Create new FP context by updating CONTROL.FPCA, CONTROL.SFPA
83
+ * and the FPSCR.
84
+ */
85
+ TCGv_i32 control, fpscr;
86
+ uint32_t bits = R_V7M_CONTROL_FPCA_MASK;
87
+
88
+ fpscr = load_cpu_field(v7m.fpdscr[s->v8m_secure]);
89
+ gen_helper_vfp_set_fpscr(cpu_env, fpscr);
90
+ tcg_temp_free_i32(fpscr);
91
+ /*
92
+ * We don't need to arrange to end the TB, because the only
93
+ * parts of FPSCR which we cache in the TB flags are the VECLEN
94
+ * and VECSTRIDE, and those don't exist for M-profile.
95
+ */
96
+
97
+ if (s->v8m_secure) {
98
+ bits |= R_V7M_CONTROL_SFPA_MASK;
99
+ }
100
+ control = load_cpu_field(v7m.control[M_REG_S]);
101
+ tcg_gen_ori_i32(control, control, bits);
102
+ store_cpu_field(control, v7m.control[M_REG_S]);
103
+ /* Don't need to do this for any further FP insns in this TB */
104
+ s->v7m_new_fp_ctxt_needed = false;
105
+ }
106
}
107
108
if (extract32(insn, 28, 4) == 0xf) {
109
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
110
regime_is_secure(env, dc->mmu_idx);
111
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
112
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
113
+ dc->v7m_new_fp_ctxt_needed =
114
+ FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
115
dc->cp_regs = cpu->cp_regs;
116
dc->features = env->features;
117
28
--
118
--
29
2.17.0
119
2.20.1
30
120
31
121
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Add a new helper function which returns the MMU index to use
2
for v7M, where the caller specifies all of the security
3
state, privilege level and whether the execution priority
4
is negative, and reimplement the existing
5
arm_v7m_mmu_idx_for_secstate_and_priv() in terms of it.
2
6
3
These operations are re-invented by several targets so far.
7
We are going to need this for the lazy-FP-stacking code.
4
Several supported hosts have insns for these, so place the
5
expanders out-of-line for a future introduction of tcg opcodes.
6
8
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180508151437.4232-2-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190416125744.27770-21-peter.maydell@linaro.org
11
---
12
---
12
tcg/tcg-op.h | 16 ++++++++++++++++
13
target/arm/cpu.h | 7 +++++++
13
tcg/tcg-op.c | 40 ++++++++++++++++++++++++++++++++++++++++
14
target/arm/helper.c | 14 +++++++++++---
14
2 files changed, 56 insertions(+)
15
2 files changed, 18 insertions(+), 3 deletions(-)
15
16
16
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/tcg/tcg-op.h
19
--- a/target/arm/cpu.h
19
+++ b/tcg/tcg-op.h
20
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg);
21
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
21
void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg);
22
void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg);
23
void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg);
24
+void tcg_gen_smin_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
25
+void tcg_gen_smax_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
26
+void tcg_gen_umin_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
27
+void tcg_gen_umax_i32(TCGv_i32, TCGv_i32 arg1, TCGv_i32 arg2);
28
29
static inline void tcg_gen_discard_i32(TCGv_i32 arg)
30
{
31
@@ -XXX,XX +XXX,XX @@ void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg);
32
void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg);
33
void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg);
34
void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg);
35
+void tcg_gen_smin_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
36
+void tcg_gen_smax_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
37
+void tcg_gen_umin_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
38
+void tcg_gen_umax_i64(TCGv_i64, TCGv_i64 arg1, TCGv_i64 arg2);
39
40
#if TCG_TARGET_REG_BITS == 64
41
static inline void tcg_gen_discard_i64(TCGv_i64 arg)
42
@@ -XXX,XX +XXX,XX @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t);
43
#define tcg_gen_mulu2_tl tcg_gen_mulu2_i64
44
#define tcg_gen_muls2_tl tcg_gen_muls2_i64
45
#define tcg_gen_mulsu2_tl tcg_gen_mulsu2_i64
46
+#define tcg_gen_smin_tl tcg_gen_smin_i64
47
+#define tcg_gen_umin_tl tcg_gen_umin_i64
48
+#define tcg_gen_smax_tl tcg_gen_smax_i64
49
+#define tcg_gen_umax_tl tcg_gen_umax_i64
50
#define tcg_gen_atomic_cmpxchg_tl tcg_gen_atomic_cmpxchg_i64
51
#define tcg_gen_atomic_xchg_tl tcg_gen_atomic_xchg_i64
52
#define tcg_gen_atomic_fetch_add_tl tcg_gen_atomic_fetch_add_i64
53
@@ -XXX,XX +XXX,XX @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t);
54
#define tcg_gen_mulu2_tl tcg_gen_mulu2_i32
55
#define tcg_gen_muls2_tl tcg_gen_muls2_i32
56
#define tcg_gen_mulsu2_tl tcg_gen_mulsu2_i32
57
+#define tcg_gen_smin_tl tcg_gen_smin_i32
58
+#define tcg_gen_umin_tl tcg_gen_umin_i32
59
+#define tcg_gen_smax_tl tcg_gen_smax_i32
60
+#define tcg_gen_umax_tl tcg_gen_umax_i32
61
#define tcg_gen_atomic_cmpxchg_tl tcg_gen_atomic_cmpxchg_i32
62
#define tcg_gen_atomic_xchg_tl tcg_gen_atomic_xchg_i32
63
#define tcg_gen_atomic_fetch_add_tl tcg_gen_atomic_fetch_add_i32
64
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/tcg/tcg-op.c
67
+++ b/tcg/tcg-op.c
68
@@ -XXX,XX +XXX,XX @@ void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg)
69
}
22
}
70
}
23
}
71
24
72
+void tcg_gen_smin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
25
+/*
26
+ * Return the MMU index for a v7M CPU with all relevant information
27
+ * manually specified.
28
+ */
29
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
30
+ bool secstate, bool priv, bool negpri);
31
+
32
/* Return the MMU index for a v7M CPU in the specified security and
33
* privilege state.
34
*/
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper.c
38
+++ b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
40
return 0;
41
}
42
43
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
44
- bool secstate, bool priv)
45
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
46
+ bool secstate, bool priv, bool negpri)
47
{
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)
73
+{
65
+{
74
+ tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, a, b);
66
+ bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
67
+
68
+ return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
75
+}
69
+}
76
+
70
+
77
+void tcg_gen_umin_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
71
/* Return the MMU index for a v7M CPU in the specified security state */
78
+{
72
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
79
+ tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, a, b);
73
{
80
+}
81
+
82
+void tcg_gen_smax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
83
+{
84
+ tcg_gen_movcond_i32(TCG_COND_LT, ret, a, b, b, a);
85
+}
86
+
87
+void tcg_gen_umax_i32(TCGv_i32 ret, TCGv_i32 a, TCGv_i32 b)
88
+{
89
+ tcg_gen_movcond_i32(TCG_COND_LTU, ret, a, b, b, a);
90
+}
91
+
92
/* 64-bit ops */
93
94
#if TCG_TARGET_REG_BITS == 32
95
@@ -XXX,XX +XXX,XX @@ void tcg_gen_mulsu2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 arg1, TCGv_i64 arg2)
96
tcg_temp_free_i64(t2);
97
}
98
99
+void tcg_gen_smin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
100
+{
101
+ tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, a, b);
102
+}
103
+
104
+void tcg_gen_umin_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
105
+{
106
+ tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, a, b);
107
+}
108
+
109
+void tcg_gen_smax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
110
+{
111
+ tcg_gen_movcond_i64(TCG_COND_LT, ret, a, b, b, a);
112
+}
113
+
114
+void tcg_gen_umax_i64(TCGv_i64 ret, TCGv_i64 a, TCGv_i64 b)
115
+{
116
+ tcg_gen_movcond_i64(TCG_COND_LTU, ret, a, b, b, a);
117
+}
118
+
119
/* Size changing operations. */
120
121
void tcg_gen_extrl_i64_i32(TCGv_i32 ret, TCGv_i64 arg)
122
--
74
--
123
2.17.0
75
2.20.1
124
76
125
77
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
In the v7M architecture, if an exception is generated in the process
2
of doing the lazy stacking of FP registers, the handling of
3
possible escalation to HardFault is treated differently to the normal
4
approach: it works based on the saved information about exception
5
readiness that was stored in the FPCCR when the stack frame was
6
created. Provide a new function armv7m_nvic_set_pending_lazyfp()
7
which pends exceptions during lazy stacking, and implements
8
this logic.
2
9
3
The generic expanders replace nearly identical code in the translator.
10
This corresponds to the pseudocode TakePreserveFPException().
4
11
5
Acked-by: Max Filippov <jcmvbkbc@gmail.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180508151437.4232-4-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-22-peter.maydell@linaro.org
9
---
15
---
10
target/xtensa/translate.c | 50 ++++++++++++++++++++++++++-------------
16
target/arm/cpu.h | 12 ++++++
11
1 file changed, 33 insertions(+), 17 deletions(-)
17
hw/intc/armv7m_nvic.c | 96 +++++++++++++++++++++++++++++++++++++++++++
18
2 files changed, 108 insertions(+)
12
19
13
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/target/xtensa/translate.c
22
--- a/target/arm/cpu.h
16
+++ b/target/xtensa/translate.c
23
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ static void translate_clamps(DisasContext *dc, const uint32_t arg[],
24
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
18
TCGv_i32 tmp1 = tcg_const_i32(-1u << arg[2]);
25
* a different exception).
19
TCGv_i32 tmp2 = tcg_const_i32((1 << arg[2]) - 1);
26
*/
20
27
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
21
- tcg_gen_movcond_i32(TCG_COND_GT, tmp1,
28
+/**
22
- cpu_R[arg[1]], tmp1, cpu_R[arg[1]], tmp1);
29
+ * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
23
- tcg_gen_movcond_i32(TCG_COND_LT, cpu_R[arg[0]],
30
+ * @opaque: the NVIC
24
- tmp1, tmp2, tmp1, tmp2);
31
+ * @irq: the exception number to mark pending
25
+ tcg_gen_smax_i32(tmp1, tmp1, cpu_R[arg[1]]);
32
+ * @secure: false for non-banked exceptions or for the nonsecure
26
+ tcg_gen_smin_i32(cpu_R[arg[0]], tmp1, tmp2);
33
+ * version of a banked exception, true for the secure version of a banked
27
tcg_temp_free(tmp1);
34
+ * exception.
28
tcg_temp_free(tmp2);
35
+ *
29
}
36
+ * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
30
@@ -XXX,XX +XXX,XX @@ static void translate_memw(DisasContext *dc, const uint32_t arg[],
37
+ * generated in the course of lazy stacking of FP registers.
31
tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
38
+ */
39
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
40
/**
41
* armv7m_nvic_get_pending_irq_info: return highest priority pending
42
* exception, and whether it targets Secure state
43
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/intc/armv7m_nvic.c
46
+++ b/hw/intc/armv7m_nvic.c
47
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
48
do_armv7m_nvic_set_pending(opaque, irq, secure, true);
32
}
49
}
33
50
34
-static void translate_minmax(DisasContext *dc, const uint32_t arg[],
51
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
35
- const uint32_t par[])
52
+{
36
+static void translate_smin(DisasContext *dc, const uint32_t arg[],
53
+ /*
37
+ const uint32_t par[])
54
+ * Pend an exception during lazy FP stacking. This differs
38
{
55
+ * from the usual exception pending because the logic for
39
if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
56
+ * whether we should escalate depends on the saved context
40
- tcg_gen_movcond_i32(par[0], cpu_R[arg[0]],
57
+ * in the FPCCR register, not on the current state of the CPU/NVIC.
41
- cpu_R[arg[1]], cpu_R[arg[2]],
58
+ */
42
- cpu_R[arg[1]], cpu_R[arg[2]]);
59
+ NVICState *s = (NVICState *)opaque;
43
+ tcg_gen_smin_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
60
+ bool banked = exc_is_banked(irq);
61
+ VecInfo *vec;
62
+ bool targets_secure;
63
+ bool escalate = false;
64
+ /*
65
+ * We will only look at bits in fpccr if this is a banked exception
66
+ * (in which case 'secure' tells us whether it is the S or NS version).
67
+ * All the bits for the non-banked exceptions are in fpccr_s.
68
+ */
69
+ uint32_t fpccr_s = s->cpu->env.v7m.fpccr[M_REG_S];
70
+ uint32_t fpccr = s->cpu->env.v7m.fpccr[secure];
71
+
72
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
73
+ assert(!secure || banked);
74
+
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
76
+
77
+ targets_secure = banked ? secure : exc_targets_secure(s, irq);
78
+
79
+ switch (irq) {
80
+ case ARMV7M_EXCP_DEBUG:
81
+ if (!(fpccr_s & R_V7M_FPCCR_MONRDY_MASK)) {
82
+ /* Ignore DebugMonitor exception */
83
+ return;
84
+ }
85
+ break;
86
+ case ARMV7M_EXCP_MEM:
87
+ escalate = !(fpccr & R_V7M_FPCCR_MMRDY_MASK);
88
+ break;
89
+ case ARMV7M_EXCP_USAGE:
90
+ escalate = !(fpccr & R_V7M_FPCCR_UFRDY_MASK);
91
+ break;
92
+ case ARMV7M_EXCP_BUS:
93
+ escalate = !(fpccr_s & R_V7M_FPCCR_BFRDY_MASK);
94
+ break;
95
+ case ARMV7M_EXCP_SECURE:
96
+ escalate = !(fpccr_s & R_V7M_FPCCR_SFRDY_MASK);
97
+ break;
98
+ default:
99
+ g_assert_not_reached();
100
+ }
101
+
102
+ if (escalate) {
103
+ /*
104
+ * Escalate to HardFault: faults that initially targeted Secure
105
+ * continue to do so, even if HF normally targets NonSecure.
106
+ */
107
+ irq = ARMV7M_EXCP_HARD;
108
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) &&
109
+ (targets_secure ||
110
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))) {
111
+ vec = &s->sec_vectors[irq];
112
+ } else {
113
+ vec = &s->vectors[irq];
114
+ }
115
+ }
116
+
117
+ if (!vec->enabled ||
118
+ nvic_exec_prio(s) <= exc_group_prio(s, vec->prio, secure)) {
119
+ if (!(fpccr_s & R_V7M_FPCCR_HFRDY_MASK)) {
120
+ /*
121
+ * We want to escalate to HardFault but the context the
122
+ * FP state belongs to prevents the exception pre-empting.
123
+ */
124
+ cpu_abort(&s->cpu->parent_obj,
125
+ "Lockup: can't escalate to HardFault during "
126
+ "lazy FP register stacking\n");
127
+ }
128
+ }
129
+
130
+ if (escalate) {
131
+ s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
132
+ }
133
+ if (!vec->pending) {
134
+ vec->pending = 1;
135
+ /*
136
+ * We do not call nvic_irq_update(), because we know our caller
137
+ * is going to handle causing us to take the exception by
138
+ * raising EXCP_LAZYFP, so raising the IRQ line would be
139
+ * pointless extra work. We just need to recompute the
140
+ * priorities so that armv7m_nvic_can_take_pending_exception()
141
+ * returns the right answer.
142
+ */
143
+ nvic_recompute_state(s);
44
+ }
144
+ }
45
+}
145
+}
46
+
146
+
47
+static void translate_umin(DisasContext *dc, const uint32_t arg[],
147
/* Make pending IRQ active. */
48
+ const uint32_t par[])
148
void armv7m_nvic_acknowledge_irq(void *opaque)
49
+{
149
{
50
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
51
+ tcg_gen_umin_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
52
+ }
53
+}
54
+
55
+static void translate_smax(DisasContext *dc, const uint32_t arg[],
56
+ const uint32_t par[])
57
+{
58
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
59
+ tcg_gen_smax_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
60
+ }
61
+}
62
+
63
+static void translate_umax(DisasContext *dc, const uint32_t arg[],
64
+ const uint32_t par[])
65
+{
66
+ if (gen_window_check3(dc, arg[0], arg[1], arg[2])) {
67
+ tcg_gen_umax_i32(cpu_R[arg[0]], cpu_R[arg[1]], cpu_R[arg[2]]);
68
}
69
}
70
71
@@ -XXX,XX +XXX,XX @@ static const XtensaOpcodeOps core_ops[] = {
72
.par = (const uint32_t[]){TCG_COND_NE},
73
}, {
74
.name = "max",
75
- .translate = translate_minmax,
76
- .par = (const uint32_t[]){TCG_COND_GE},
77
+ .translate = translate_smax,
78
}, {
79
.name = "maxu",
80
- .translate = translate_minmax,
81
- .par = (const uint32_t[]){TCG_COND_GEU},
82
+ .translate = translate_umax,
83
}, {
84
.name = "memw",
85
.translate = translate_memw,
86
}, {
87
.name = "min",
88
- .translate = translate_minmax,
89
- .par = (const uint32_t[]){TCG_COND_LT},
90
+ .translate = translate_smin,
91
}, {
92
.name = "minu",
93
- .translate = translate_minmax,
94
- .par = (const uint32_t[]){TCG_COND_LTU},
95
+ .translate = translate_umin,
96
}, {
97
.name = "mov",
98
.translate = translate_mov,
99
--
150
--
100
2.17.0
151
2.20.1
101
152
102
153
diff view generated by jsdifflib
New patch
1
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
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
New patch
1
1
The M-profile architecture floating point system supports
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
8
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
---
12
target/arm/cpu.h | 3 ++
13
target/arm/helper.h | 2 +
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
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@
24
#define EXCP_NOCP 17 /* v7M NOCP UsageFault */
25
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
26
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
27
+#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
28
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
29
30
#define ARMV7M_EXCP_RESET 1
31
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
32
FIELD(TBFLAG_A32, VFPEN, 7, 1)
33
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
34
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
+/* For M profile only, set if FPCCR.LSPACT is set */
36
+FIELD(TBFLAG_A32, LSPACT, 18, 1)
37
/* For M profile only, set if we must create a new FP context */
38
FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
39
/* For M profile only, set if FPCCR.S does not match current security state */
40
diff --git a/target/arm/helper.h b/target/arm/helper.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/helper.h
43
+++ b/target/arm/helper.h
44
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(v7m_blxns, void, env, i32)
45
46
DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
47
48
+DEF_HELPER_1(v7m_preserve_fp_state, void, env)
49
+
50
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
51
52
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
53
diff --git a/target/arm/translate.h b/target/arm/translate.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/translate.h
56
+++ b/target/arm/translate.h
57
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
58
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
59
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
60
bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
61
+ bool v7m_lspact; /* FPCCR.LSPACT set */
62
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
63
* so that top level loop can generate correct syndrome information.
64
*/
65
diff --git a/target/arm/helper.c b/target/arm/helper.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/helper.c
68
+++ b/target/arm/helper.c
69
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
70
g_assert_not_reached();
71
}
72
73
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
74
+{
75
+ /* translate.c should never generate calls here in user-only mode */
76
+ g_assert_not_reached();
77
+}
78
+
79
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
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
+{
88
+ /*
89
+ * Preserve FP state (because LSPACT was set and we are about
90
+ * to execute an FP instruction). This corresponds to the
91
+ * PreserveFPState() pseudocode.
92
+ * We may throw an exception if the stacking fails.
93
+ */
94
+ ARMCPU *cpu = arm_env_get_cpu(env);
95
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
96
+ bool negpri = !(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_HFRDY_MASK);
97
+ bool is_priv = !(env->v7m.fpccr[is_secure] & R_V7M_FPCCR_USER_MASK);
98
+ bool splimviol = env->v7m.fpccr[is_secure] & R_V7M_FPCCR_SPLIMVIOL_MASK;
99
+ uint32_t fpcar = env->v7m.fpcar[is_secure];
100
+ bool stacked_ok = true;
101
+ bool ts = is_secure && (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
102
+ bool take_exception;
103
+
104
+ /* Take the iothread lock as we are going to touch the NVIC */
105
+ qemu_mutex_lock_iothread();
106
+
107
+ /* Check the background context had access to the FPU */
108
+ if (!v7m_cpacr_pass(env, is_secure, is_priv)) {
109
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, is_secure);
110
+ env->v7m.cfsr[is_secure] |= R_V7M_CFSR_NOCP_MASK;
111
+ stacked_ok = false;
112
+ } else if (!is_secure && !extract32(env->v7m.nsacr, 10, 1)) {
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
114
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
115
+ stacked_ok = false;
116
+ }
117
+
118
+ if (!splimviol && stacked_ok) {
119
+ /* We only stack if the stack limit wasn't violated */
120
+ int i;
121
+ ARMMMUIdx mmu_idx;
122
+
123
+ mmu_idx = arm_v7m_mmu_idx_all(env, is_secure, is_priv, negpri);
124
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
125
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
126
+ uint32_t faddr = fpcar + 4 * i;
127
+ uint32_t slo = extract64(dn, 0, 32);
128
+ uint32_t shi = extract64(dn, 32, 32);
129
+
130
+ if (i >= 16) {
131
+ faddr += 8; /* skip the slot for the FPSCR */
132
+ }
133
+ stacked_ok = stacked_ok &&
134
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, STACK_LAZYFP) &&
135
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, STACK_LAZYFP);
136
+ }
137
+
138
+ stacked_ok = stacked_ok &&
139
+ v7m_stack_write(cpu, fpcar + 0x40,
140
+ vfp_get_fpscr(env), mmu_idx, STACK_LAZYFP);
141
+ }
142
+
143
+ /*
144
+ * We definitely pended an exception, but it's possible that it
145
+ * might not be able to be taken now. If its priority permits us
146
+ * to take it now, then we must not update the LSPACT or FP regs,
147
+ * but instead jump out to take the exception immediately.
148
+ * If it's just pending and won't be taken until the current
149
+ * handler exits, then we do update LSPACT and the FP regs.
150
+ */
151
+ take_exception = !stacked_ok &&
152
+ armv7m_nvic_can_take_pending_exception(env->nvic);
153
+
154
+ qemu_mutex_unlock_iothread();
155
+
156
+ if (take_exception) {
157
+ raise_exception_ra(env, EXCP_LAZYFP, 0, 1, GETPC());
158
+ }
159
+
160
+ env->v7m.fpccr[is_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
161
+
162
+ if (ts) {
163
+ /* Clear s0 to s31 and the FPSCR */
164
+ int i;
165
+
166
+ for (i = 0; i < 32; i += 2) {
167
+ *aa32_vfp_dreg(env, i / 2) = 0;
168
+ }
169
+ vfp_set_fpscr(env, 0);
170
+ }
171
+ /*
172
+ * Otherwise s0 to s15 and FPSCR are UNKNOWN; we choose to leave them
173
+ * unchanged.
174
+ */
175
+}
176
+
177
/* Write to v7M CONTROL.SPSEL bit for the specified security bank.
178
* This may change the current stack pointer between Main and Process
179
* stack pointers if it is done for the CONTROL register for the current
180
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
181
[EXCP_NOCP] = "v7M NOCP UsageFault",
182
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
183
[EXCP_STKOF] = "v8M STKOF UsageFault",
184
+ [EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
185
};
186
187
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
188
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
189
return;
190
}
191
break;
192
+ case EXCP_LAZYFP:
193
+ /*
194
+ * We already pended the specific exception in the NVIC in the
195
+ * v7m_preserve_fp_state() helper function.
196
+ */
197
+ break;
198
default:
199
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
200
return; /* Never happens. Keep compiler happy. */
201
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
202
flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
203
}
204
205
+ if (arm_feature(env, ARM_FEATURE_M)) {
206
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
207
+
208
+ if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
209
+ flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
210
+ }
211
+ }
212
+
213
*pflags = flags;
214
*cs_base = 0;
215
}
216
diff --git a/target/arm/translate.c b/target/arm/translate.c
217
index XXXXXXX..XXXXXXX 100644
218
--- a/target/arm/translate.c
219
+++ b/target/arm/translate.c
220
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
221
if (arm_dc_feature(s, ARM_FEATURE_M)) {
222
/* Handle M-profile lazy FP state mechanics */
223
224
+ /* Trigger lazy-state preservation if necessary */
225
+ if (s->v7m_lspact) {
226
+ /*
227
+ * Lazy state saving affects external memory and also the NVIC,
228
+ * so we must mark it as an IO operation for icount.
229
+ */
230
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
231
+ gen_io_start();
232
+ }
233
+ gen_helper_v7m_preserve_fp_state(cpu_env);
234
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
235
+ gen_io_end();
236
+ }
237
+ /*
238
+ * If the preserve_fp_state helper doesn't throw an exception
239
+ * then it will clear LSPACT; we don't need to repeat this for
240
+ * any further FP insns in this TB.
241
+ */
242
+ s->v7m_lspact = false;
243
+ }
244
+
245
/* Update ownership of FP context: set FPCCR.S to match current state */
246
if (s->v8m_fpccr_s_wrong) {
247
TCGv_i32 tmp;
248
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
249
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
250
dc->v7m_new_fp_ctxt_needed =
251
FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
252
+ dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
253
dc->cp_regs = cpu->cp_regs;
254
dc->features = env->features;
255
256
--
257
2.20.1
258
259
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the VLSTM instruction for v7M for the FPU present case.
2
2
3
The insns in the ARMv8.1-Atomics are added to the existing
4
load/store exclusive and load/store reg opcode spaces.
5
Rearrange the top-level decoders for these to accomodate.
6
The Atomics insns themselves still generate Unallocated.
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180508151437.4232-8-richard.henderson@linaro.org
10
[PMM: Drop the ARM_FEATURE_V8_1 feature flag]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-25-peter.maydell@linaro.org
13
---
6
---
14
target/arm/cpu.h | 1 +
7
target/arm/cpu.h | 2 +
15
linux-user/elfload.c | 1 +
8
target/arm/helper.h | 2 +
16
target/arm/translate-a64.c | 182 +++++++++++++++++++++++++++----------
9
target/arm/helper.c | 84 ++++++++++++++++++++++++++++++++++++++++++
17
3 files changed, 138 insertions(+), 46 deletions(-)
10
target/arm/translate.c | 15 +++++++-
11
4 files changed, 102 insertions(+), 1 deletion(-)
18
12
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
15
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@ enum arm_features {
17
@@ -XXX,XX +XXX,XX @@
24
ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
18
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
25
ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
19
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
26
ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
20
#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
27
+ ARM_FEATURE_V8_ATOMICS, /* ARMv8.1-Atomics feature */
21
+#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
28
ARM_FEATURE_V8_RDM, /* implements v8.1 simd round multiply */
22
+#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
29
ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
23
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
30
ARM_FEATURE_V8_FCMA, /* has complex number part of v8.3 extensions. */
24
31
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
25
#define ARMV7M_EXCP_RESET 1
26
diff --git a/target/arm/helper.h b/target/arm/helper.h
32
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
33
--- a/linux-user/elfload.c
28
--- a/target/arm/helper.h
34
+++ b/linux-user/elfload.c
29
+++ b/target/arm/helper.h
35
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
36
GET_FEATURE(ARM_FEATURE_V8_SHA512, ARM_HWCAP_A64_SHA512);
31
37
GET_FEATURE(ARM_FEATURE_V8_FP16,
32
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
38
ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
33
39
+ GET_FEATURE(ARM_FEATURE_V8_ATOMICS, ARM_HWCAP_A64_ATOMICS);
34
+DEF_HELPER_2(v7m_vlstm, void, env, i32)
40
GET_FEATURE(ARM_FEATURE_V8_RDM, ARM_HWCAP_A64_ASIMDRDM);
35
+
41
GET_FEATURE(ARM_FEATURE_V8_FCMA, ARM_HWCAP_A64_FCMA);
36
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
42
#undef GET_FEATURE
37
43
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
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
44
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/translate-a64.c
41
--- a/target/arm/helper.c
46
+++ b/target/arm/translate-a64.c
42
+++ b/target/arm/helper.c
47
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
43
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
48
int rt = extract32(insn, 0, 5);
44
g_assert_not_reached();
49
int rn = extract32(insn, 5, 5);
45
}
50
int rt2 = extract32(insn, 10, 5);
46
51
- int is_lasr = extract32(insn, 15, 1);
47
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
52
int rs = extract32(insn, 16, 5);
48
+{
53
- int is_pair = extract32(insn, 21, 1);
49
+ /* translate.c should never generate calls here in user-only mode */
54
- int is_store = !extract32(insn, 22, 1);
50
+ g_assert_not_reached();
55
- int is_excl = !extract32(insn, 23, 1);
51
+}
56
+ int is_lasr = extract32(insn, 15, 1);
57
+ int o2_L_o1_o0 = extract32(insn, 21, 3) * 2 | is_lasr;
58
int size = extract32(insn, 30, 2);
59
TCGv_i64 tcg_addr;
60
61
- if ((!is_excl && !is_pair && !is_lasr) ||
62
- (!is_excl && is_pair) ||
63
- (is_pair && size < 2)) {
64
- unallocated_encoding(s);
65
+ switch (o2_L_o1_o0) {
66
+ case 0x0: /* STXR */
67
+ case 0x1: /* STLXR */
68
+ if (rn == 31) {
69
+ gen_check_sp_alignment(s);
70
+ }
71
+ if (is_lasr) {
72
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
73
+ }
74
+ tcg_addr = read_cpu_reg_sp(s, rn, 1);
75
+ gen_store_exclusive(s, rs, rt, rt2, tcg_addr, size, false);
76
return;
77
- }
78
79
- if (rn == 31) {
80
- gen_check_sp_alignment(s);
81
- }
82
- tcg_addr = read_cpu_reg_sp(s, rn, 1);
83
-
84
- /* Note that since TCG is single threaded load-acquire/store-release
85
- * semantics require no extra if (is_lasr) { ... } handling.
86
- */
87
-
88
- if (is_excl) {
89
- if (!is_store) {
90
- s->is_ldex = true;
91
- gen_load_exclusive(s, rt, rt2, tcg_addr, size, is_pair);
92
- if (is_lasr) {
93
- tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
94
- }
95
- } else {
96
- if (is_lasr) {
97
- tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
98
- }
99
- gen_store_exclusive(s, rs, rt, rt2, tcg_addr, size, is_pair);
100
+ case 0x4: /* LDXR */
101
+ case 0x5: /* LDAXR */
102
+ if (rn == 31) {
103
+ gen_check_sp_alignment(s);
104
}
105
- } else {
106
- TCGv_i64 tcg_rt = cpu_reg(s, rt);
107
- bool iss_sf = disas_ldst_compute_iss_sf(size, false, 0);
108
+ tcg_addr = read_cpu_reg_sp(s, rn, 1);
109
+ s->is_ldex = true;
110
+ gen_load_exclusive(s, rt, rt2, tcg_addr, size, false);
111
+ if (is_lasr) {
112
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
113
+ }
114
+ return;
115
116
+ case 0x9: /* STLR */
117
/* Generate ISS for non-exclusive accesses including LASR. */
118
- if (is_store) {
119
+ if (rn == 31) {
120
+ gen_check_sp_alignment(s);
121
+ }
122
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
123
+ tcg_addr = read_cpu_reg_sp(s, rn, 1);
124
+ do_gpr_st(s, cpu_reg(s, rt), tcg_addr, size, true, rt,
125
+ disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
126
+ return;
127
+
52
+
128
+ case 0xd: /* LDAR */
53
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
129
+ /* Generate ISS for non-exclusive accesses including LASR. */
54
{
130
+ if (rn == 31) {
55
/* The TT instructions can be used by unprivileged code, but in
131
+ gen_check_sp_alignment(s);
56
@@ -XXX,XX +XXX,XX @@ static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
132
+ }
133
+ tcg_addr = read_cpu_reg_sp(s, rn, 1);
134
+ do_gpr_ld(s, cpu_reg(s, rt), tcg_addr, size, false, false, true, rt,
135
+ disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
136
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
137
+ return;
138
+
139
+ case 0x2: case 0x3: /* CASP / STXP */
140
+ if (size & 2) { /* STXP / STLXP */
141
+ if (rn == 31) {
142
+ gen_check_sp_alignment(s);
143
+ }
144
if (is_lasr) {
145
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
146
}
147
- do_gpr_st(s, tcg_rt, tcg_addr, size,
148
- true, rt, iss_sf, is_lasr);
149
- } else {
150
- do_gpr_ld(s, tcg_rt, tcg_addr, size, false, false,
151
- true, rt, iss_sf, is_lasr);
152
+ tcg_addr = read_cpu_reg_sp(s, rn, 1);
153
+ gen_store_exclusive(s, rs, rt, rt2, tcg_addr, size, true);
154
+ return;
155
+ }
156
+ /* CASP / CASPL */
157
+ break;
158
+
159
+ case 0x6: case 0x7: /* CASP / LDXP */
160
+ if (size & 2) { /* LDXP / LDAXP */
161
+ if (rn == 31) {
162
+ gen_check_sp_alignment(s);
163
+ }
164
+ tcg_addr = read_cpu_reg_sp(s, rn, 1);
165
+ s->is_ldex = true;
166
+ gen_load_exclusive(s, rt, rt2, tcg_addr, size, true);
167
if (is_lasr) {
168
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
169
}
170
+ return;
171
}
172
+ /* CASPA / CASPAL */
173
+ break;
174
+
175
+ case 0xa: /* CAS */
176
+ case 0xb: /* CASL */
177
+ case 0xe: /* CASA */
178
+ case 0xf: /* CASAL */
179
+ break;
180
}
181
+ unallocated_encoding(s);
182
}
183
184
/*
185
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn,
186
}
57
}
187
}
58
}
188
59
189
+/* Atomic memory operations
60
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
190
+ *
191
+ * 31 30 27 26 24 22 21 16 15 12 10 5 0
192
+ * +------+-------+---+-----+-----+---+----+----+-----+-----+----+-----+
193
+ * | size | 1 1 1 | V | 0 0 | A R | 1 | Rs | o3 | opc | 0 0 | Rn | Rt |
194
+ * +------+-------+---+-----+-----+--------+----+-----+-----+----+-----+
195
+ *
196
+ * Rt: the result register
197
+ * Rn: base address or SP
198
+ * Rs: the source register for the operation
199
+ * V: vector flag (always 0 as of v8.3)
200
+ * A: acquire flag
201
+ * R: release flag
202
+ */
203
+static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
204
+ int size, int rt, bool is_vector)
205
+{
61
+{
206
+ int rs = extract32(insn, 16, 5);
62
+ /* fptr is the value of Rn, the frame pointer we store the FP regs to */
207
+ int rn = extract32(insn, 5, 5);
63
+ bool s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
208
+ int o3_opc = extract32(insn, 12, 4);
64
+ bool lspact = env->v7m.fpccr[s] & R_V7M_FPCCR_LSPACT_MASK;
209
+ int feature = ARM_FEATURE_V8_ATOMICS;
210
+
65
+
211
+ if (is_vector) {
66
+ assert(env->v7m.secure);
212
+ unallocated_encoding(s);
67
+
213
+ return;
68
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
214
+ }
215
+ switch (o3_opc) {
216
+ case 000: /* LDADD */
217
+ case 001: /* LDCLR */
218
+ case 002: /* LDEOR */
219
+ case 003: /* LDSET */
220
+ case 004: /* LDSMAX */
221
+ case 005: /* LDSMIN */
222
+ case 006: /* LDUMAX */
223
+ case 007: /* LDUMIN */
224
+ case 010: /* SWP */
225
+ default:
226
+ unallocated_encoding(s);
227
+ return;
228
+ }
229
+ if (!arm_dc_feature(s, feature)) {
230
+ unallocated_encoding(s);
231
+ return;
69
+ return;
232
+ }
70
+ }
233
+
71
+
234
+ (void)rs;
72
+ /* Check access to the coprocessor is permitted */
235
+ (void)rn;
73
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
74
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
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;
236
+}
126
+}
237
+
127
+
238
/* Load/store register (all forms) */
128
static bool v7m_push_stack(ARMCPU *cpu)
239
static void disas_ldst_reg(DisasContext *s, uint32_t insn)
240
{
129
{
241
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg(DisasContext *s, uint32_t insn)
130
/* Do the "set up stack frame" part of exception entry,
242
131
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
243
switch (extract32(insn, 24, 2)) {
132
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
244
case 0:
133
[EXCP_STKOF] = "v8M STKOF UsageFault",
245
- if (extract32(insn, 21, 1) == 1 && extract32(insn, 10, 2) == 2) {
134
[EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
246
- disas_ldst_reg_roffset(s, insn, opc, size, rt, is_vector);
135
+ [EXCP_LSERR] = "v8M LSERR UsageFault",
247
- } else {
136
+ [EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
248
+ if (extract32(insn, 21, 1) == 0) {
137
};
249
/* Load/store register (unscaled immediate)
138
250
* Load/store immediate pre/post-indexed
139
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
251
* Load/store register unprivileged
140
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
252
*/
141
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
253
disas_ldst_reg_imm9(s, insn, opc, size, rt, is_vector);
142
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_STKOF_MASK;
254
+ return;
255
+ }
256
+ switch (extract32(insn, 10, 2)) {
257
+ case 0:
258
+ disas_ldst_atomic(s, insn, size, rt, is_vector);
259
+ return;
260
+ case 2:
261
+ disas_ldst_reg_roffset(s, insn, opc, size, rt, is_vector);
262
+ return;
263
}
264
break;
143
break;
265
case 1:
144
+ case EXCP_LSERR:
266
disas_ldst_reg_unsigned_imm(s, insn, opc, size, rt, is_vector);
145
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
267
- break;
146
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
268
- default:
147
+ break;
269
- unallocated_encoding(s);
148
+ case EXCP_UNALIGNED:
270
- break;
149
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
271
+ return;
150
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNALIGNED_MASK;
272
}
151
+ break;
273
+ unallocated_encoding(s);
152
case EXCP_SWI:
274
}
153
/* The PC already points to the next instruction. */
275
154
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC, env->v7m.secure);
276
/* AdvSIMD load/store multiple structures
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) &&
277
--
181
--
278
2.17.0
182
2.20.1
279
183
280
184
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the VLLDM instruction for v7M for the FPU present cas.
2
2
3
The instruction "ucvtf v0.4h, v04h, #2", with input 0x8000u,
4
overflows the intermediate float16 to infinity before we have a
5
chance to scale the output. Use float64 as the intermediate type
6
so that no input argument (uint32_t in this case) can overflow
7
or round before scaling. Given the declared argument, the signed
8
int32_t function has the same problem.
9
10
When converting from float16 to integer, using u/int32_t instead
11
of u/int16_t means that the bounding is incorrect.
12
13
Cc: qemu-stable@nongnu.org
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20180502221552.3873-4-richard.henderson@linaro.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-26-peter.maydell@linaro.org
18
---
6
---
19
target/arm/helper.h | 4 +--
7
target/arm/helper.h | 1 +
20
target/arm/helper.c | 53 ++++++++++++++++++++++++++++++++++++--
8
target/arm/helper.c | 54 ++++++++++++++++++++++++++++++++++++++++++
21
target/arm/translate-a64.c | 4 +--
9
target/arm/translate.c | 2 +-
22
3 files changed, 55 insertions(+), 6 deletions(-)
10
3 files changed, 56 insertions(+), 1 deletion(-)
23
11
24
diff --git a/target/arm/helper.h b/target/arm/helper.h
12
diff --git a/target/arm/helper.h b/target/arm/helper.h
25
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.h
14
--- a/target/arm/helper.h
27
+++ b/target/arm/helper.h
15
+++ b/target/arm/helper.h
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_toshd_round_to_zero, i64, f64, i32, ptr)
16
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
29
DEF_HELPER_3(vfp_tosld_round_to_zero, i64, f64, i32, ptr)
17
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
30
DEF_HELPER_3(vfp_touhd_round_to_zero, i64, f64, i32, ptr)
18
31
DEF_HELPER_3(vfp_tould_round_to_zero, i64, f64, i32, ptr)
19
DEF_HELPER_2(v7m_vlstm, void, env, i32)
32
-DEF_HELPER_3(vfp_toulh, i32, f16, i32, ptr)
20
+DEF_HELPER_2(v7m_vlldm, void, env, i32)
33
-DEF_HELPER_3(vfp_toslh, i32, f16, i32, ptr)
21
34
+DEF_HELPER_3(vfp_touhh, i32, f16, i32, ptr)
22
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
35
+DEF_HELPER_3(vfp_toshh, i32, f16, i32, ptr)
23
36
DEF_HELPER_3(vfp_toshs, i32, f32, i32, ptr)
37
DEF_HELPER_3(vfp_tosls, i32, f32, i32, ptr)
38
DEF_HELPER_3(vfp_tosqs, i64, f32, i32, ptr)
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
26
--- a/target/arm/helper.c
42
+++ b/target/arm/helper.c
27
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ VFP_CONV_FIX_A64(sq, s, 32, 64, int64)
28
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
44
VFP_CONV_FIX(uh, s, 32, 32, uint16)
29
g_assert_not_reached();
45
VFP_CONV_FIX(ul, s, 32, 32, uint32)
30
}
46
VFP_CONV_FIX_A64(uq, s, 32, 64, uint64)
31
47
-VFP_CONV_FIX_A64(sl, h, 16, 32, int32)
32
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
48
-VFP_CONV_FIX_A64(ul, h, 16, 32, uint32)
49
+
50
#undef VFP_CONV_FIX
51
#undef VFP_CONV_FIX_FLOAT
52
#undef VFP_CONV_FLOAT_FIX_ROUND
53
+#undef VFP_CONV_FIX_A64
54
+
55
+/* Conversion to/from f16 can overflow to infinity before/after scaling.
56
+ * Therefore we convert to f64 (which does not round), scale,
57
+ * and then convert f64 to f16 (which may round).
58
+ */
59
+
60
+static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst)
61
+{
33
+{
62
+ return float64_to_float16(float64_scalbn(f, -shift, fpst), true, fpst);
34
+ /* translate.c should never generate calls here in user-only mode */
35
+ g_assert_not_reached();
63
+}
36
+}
64
+
37
+
65
+float16 HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
38
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
39
{
40
/* The TT instructions can be used by unprivileged code, but in
41
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
42
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
43
}
44
45
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
66
+{
46
+{
67
+ return do_postscale_fp16(int32_to_float64(x, fpst), shift, fpst);
47
+ /* fptr is the value of Rn, the frame pointer we load the FP regs from */
48
+ assert(env->v7m.secure);
49
+
50
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
51
+ return;
52
+ }
53
+
54
+ /* Check access to the coprocessor is permitted */
55
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
56
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
57
+ }
58
+
59
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
60
+ /* State in FP is still valid */
61
+ env->v7m.fpccr[M_REG_S] &= ~R_V7M_FPCCR_LSPACT_MASK;
62
+ } else {
63
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
64
+ int i;
65
+ uint32_t fpscr;
66
+
67
+ if (fptr & 7) {
68
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
69
+ }
70
+
71
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
72
+ uint32_t slo, shi;
73
+ uint64_t dn;
74
+ uint32_t faddr = fptr + 4 * i;
75
+
76
+ if (i >= 16) {
77
+ faddr += 8; /* skip the slot for the FPSCR */
78
+ }
79
+
80
+ slo = cpu_ldl_data(env, faddr);
81
+ shi = cpu_ldl_data(env, faddr + 4);
82
+
83
+ dn = (uint64_t) shi << 32 | slo;
84
+ *aa32_vfp_dreg(env, i / 2) = dn;
85
+ }
86
+ fpscr = cpu_ldl_data(env, fptr + 0x40);
87
+ vfp_set_fpscr(env, fpscr);
88
+ }
89
+
90
+ env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
68
+}
91
+}
69
+
92
+
70
+float16 HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
93
static bool v7m_push_stack(ARMCPU *cpu)
71
+{
94
{
72
+ return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst);
95
/* Do the "set up stack frame" part of exception entry,
73
+}
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
74
+
75
+static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst)
76
+{
77
+ if (unlikely(float16_is_any_nan(f))) {
78
+ float_raise(float_flag_invalid, fpst);
79
+ return 0;
80
+ } else {
81
+ int old_exc_flags = get_float_exception_flags(fpst);
82
+ float64 ret;
83
+
84
+ ret = float16_to_float64(f, true, fpst);
85
+ ret = float64_scalbn(ret, shift, fpst);
86
+ old_exc_flags |= get_float_exception_flags(fpst)
87
+ & float_flag_input_denormal;
88
+ set_float_exception_flags(old_exc_flags, fpst);
89
+
90
+ return ret;
91
+ }
92
+}
93
+
94
+uint32_t HELPER(vfp_toshh)(float16 x, uint32_t shift, void *fpst)
95
+{
96
+ return float64_to_int16(do_prescale_fp16(x, shift, fpst), fpst);
97
+}
98
+
99
+uint32_t HELPER(vfp_touhh)(float16 x, uint32_t shift, void *fpst)
100
+{
101
+ return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst);
102
+}
103
104
/* Set the current fp rounding mode and return the old one.
105
* The argument is a softfloat float_round_ value.
106
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
107
index XXXXXXX..XXXXXXX 100644
97
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-a64.c
98
--- a/target/arm/translate.c
109
+++ b/target/arm/translate-a64.c
99
+++ b/target/arm/translate.c
110
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
100
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
111
switch (size) {
101
TCGv_i32 fptr = load_reg(s, rn);
112
case MO_16:
102
113
if (is_u) {
103
if (extract32(insn, 20, 1)) {
114
- fn = gen_helper_vfp_toulh;
104
- /* VLLDM */
115
+ fn = gen_helper_vfp_touhh;
105
+ gen_helper_v7m_vlldm(cpu_env, fptr);
116
} else {
106
} else {
117
- fn = gen_helper_vfp_toslh;
107
gen_helper_v7m_vlstm(cpu_env, fptr);
118
+ fn = gen_helper_vfp_toshh;
108
}
119
}
120
break;
121
case MO_32:
122
--
109
--
123
2.17.0
110
2.20.1
124
111
125
112
diff view generated by jsdifflib
1
Some versions of gcc produce a spurious warning if the result of
1
Enable the FPU by default for the Cortex-M4 and Cortex-M33.
2
__atomic_compare_echange_n() is not used and the type involved
3
is a signed 8 bit value:
4
error: value computed is not used [-Werror=unused-value]
5
This has been seen on at least
6
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
7
8
Work around this by using an explicit cast to void to indicate
9
that we don't care about the return value.
10
11
We don't currently use our atomic_cmpxchg() macro on any signed
12
8 bit types, but the upcoming support for the Arm v8.1-Atomics
13
will require it.
14
2
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Message-id: 20190416125744.27770-27-peter.maydell@linaro.org
18
---
6
---
19
include/qemu/atomic.h | 2 +-
7
target/arm/cpu.c | 8 ++++++++
20
1 file changed, 1 insertion(+), 1 deletion(-)
8
1 file changed, 8 insertions(+)
21
9
22
diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
10
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
23
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
24
--- a/include/qemu/atomic.h
12
--- a/target/arm/cpu.c
25
+++ b/include/qemu/atomic.h
13
+++ b/target/arm/cpu.c
26
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
27
/* Returns the eventual value, failed or not */
15
set_feature(&cpu->env, ARM_FEATURE_M);
28
#define atomic_cmpxchg__nocheck(ptr, old, new) ({ \
16
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
29
typeof_strip_qual(*ptr) _old = (old); \
17
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
30
- __atomic_compare_exchange_n(ptr, &_old, new, false, \
18
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
31
+ (void)__atomic_compare_exchange_n(ptr, &_old, new, false, \
19
cpu->midr = 0x410fc240; /* r0p0 */
32
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \
20
cpu->pmsav7_dregion = 8;
33
_old; \
21
+ cpu->isar.mvfr0 = 0x10110021;
34
})
22
+ cpu->isar.mvfr1 = 0x11000011;
23
+ cpu->isar.mvfr2 = 0x00000000;
24
cpu->id_pfr0 = 0x00000030;
25
cpu->id_pfr1 = 0x00000200;
26
cpu->id_dfr0 = 0x00100000;
27
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
28
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
29
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
30
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
31
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
32
cpu->midr = 0x410fd213; /* r0p3 */
33
cpu->pmsav7_dregion = 16;
34
cpu->sau_sregion = 8;
35
+ cpu->isar.mvfr0 = 0x10110021;
36
+ cpu->isar.mvfr1 = 0x11000011;
37
+ cpu->isar.mvfr2 = 0x00000040;
38
cpu->id_pfr0 = 0x00000030;
39
cpu->id_pfr1 = 0x00000210;
40
cpu->id_dfr0 = 0x00200000;
35
--
41
--
36
2.17.0
42
2.20.1
37
43
38
44
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
While we have some of the scalar paths for FCVT for fp16,
3
This device is used by both ARM (BCM2836, for raspi2) and AArch64
4
we failed to decode the fp16 version of these instructions.
4
(BCM2837, for raspi3) targets, and is not CPU-specific.
5
Move it to common object, so we build it once for all targets.
5
6
6
Cc: qemu-stable@nongnu.org
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190427133028.12874-1-philmd@redhat.com
8
Message-id: 20180502221552.3873-3-richard.henderson@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
target/arm/translate-a64.c | 65 +++++++++++++++++++++++++++-----------
12
hw/dma/Makefile.objs | 2 +-
13
1 file changed, 46 insertions(+), 19 deletions(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
diff --git a/hw/dma/Makefile.objs b/hw/dma/Makefile.objs
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
17
--- a/hw/dma/Makefile.objs
18
+++ b/target/arm/translate-a64.c
18
+++ b/hw/dma/Makefile.objs
19
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
19
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zdma.o
20
bool is_q, bool is_u,
20
21
int immh, int immb, int rn, int rd)
21
obj-$(CONFIG_OMAP) += omap_dma.o soc_dma.o
22
{
22
obj-$(CONFIG_PXA2XX) += pxa2xx_dma.o
23
- bool is_double = extract32(immh, 3, 1);
23
-obj-$(CONFIG_RASPI) += bcm2835_dma.o
24
int immhb = immh << 3 | immb;
24
+common-obj-$(CONFIG_RASPI) += bcm2835_dma.o
25
- int fracbits = (is_double ? 128 : 64) - immhb;
26
- int pass;
27
+ int pass, size, fracbits;
28
TCGv_ptr tcg_fpstatus;
29
TCGv_i32 tcg_rmode, tcg_shift;
30
31
- if (!extract32(immh, 2, 2)) {
32
- unallocated_encoding(s);
33
- return;
34
- }
35
-
36
- if (!is_scalar && !is_q && is_double) {
37
+ if (immh & 0x8) {
38
+ size = MO_64;
39
+ if (!is_scalar && !is_q) {
40
+ unallocated_encoding(s);
41
+ return;
42
+ }
43
+ } else if (immh & 0x4) {
44
+ size = MO_32;
45
+ } else if (immh & 0x2) {
46
+ size = MO_16;
47
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
48
+ unallocated_encoding(s);
49
+ return;
50
+ }
51
+ } else {
52
+ /* Should have split out AdvSIMD modified immediate earlier. */
53
+ assert(immh == 1);
54
unallocated_encoding(s);
55
return;
56
}
57
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
58
assert(!(is_scalar && is_q));
59
60
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(FPROUNDING_ZERO));
61
- tcg_fpstatus = get_fpstatus_ptr(false);
62
+ tcg_fpstatus = get_fpstatus_ptr(size == MO_16);
63
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
64
+ fracbits = (16 << size) - immhb;
65
tcg_shift = tcg_const_i32(fracbits);
66
67
- if (is_double) {
68
+ if (size == MO_64) {
69
int maxpass = is_scalar ? 1 : 2;
70
71
for (pass = 0; pass < maxpass; pass++) {
72
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
73
}
74
clear_vec_high(s, is_q, rd);
75
} else {
76
- int maxpass = is_scalar ? 1 : is_q ? 4 : 2;
77
+ void (*fn)(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
78
+ int maxpass = is_scalar ? 1 : ((8 << is_q) >> size);
79
+
80
+ switch (size) {
81
+ case MO_16:
82
+ if (is_u) {
83
+ fn = gen_helper_vfp_toulh;
84
+ } else {
85
+ fn = gen_helper_vfp_toslh;
86
+ }
87
+ break;
88
+ case MO_32:
89
+ if (is_u) {
90
+ fn = gen_helper_vfp_touls;
91
+ } else {
92
+ fn = gen_helper_vfp_tosls;
93
+ }
94
+ break;
95
+ default:
96
+ g_assert_not_reached();
97
+ }
98
+
99
for (pass = 0; pass < maxpass; pass++) {
100
TCGv_i32 tcg_op = tcg_temp_new_i32();
101
102
- read_vec_element_i32(s, tcg_op, rn, pass, MO_32);
103
- if (is_u) {
104
- gen_helper_vfp_touls(tcg_op, tcg_op, tcg_shift, tcg_fpstatus);
105
- } else {
106
- gen_helper_vfp_tosls(tcg_op, tcg_op, tcg_shift, tcg_fpstatus);
107
- }
108
+ read_vec_element_i32(s, tcg_op, rn, pass, size);
109
+ fn(tcg_op, tcg_op, tcg_shift, tcg_fpstatus);
110
if (is_scalar) {
111
write_fp_sreg(s, rd, tcg_op);
112
} else {
113
- write_vec_element_i32(s, tcg_op, rd, pass, MO_32);
114
+ write_vec_element_i32(s, tcg_op, rd, pass, size);
115
}
116
tcg_temp_free_i32(tcg_op);
117
}
118
--
25
--
119
2.17.0
26
2.20.1
120
27
121
28
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
The generic expanders replace nearly identical code in the translator.
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 20180508151437.4232-3-richard.henderson@linaro.org
7
Message-id: 20190412165416.7977-2-philmd@redhat.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
9
---
10
target/arm/translate-a64.c | 46 ++++++++++++--------------------------
10
hw/arm/aspeed.c | 13 +++++++++----
11
1 file changed, 14 insertions(+), 32 deletions(-)
11
1 file changed, 9 insertions(+), 4 deletions(-)
12
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
13
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
15
--- a/hw/arm/aspeed.c
16
+++ b/target/arm/translate-a64.c
16
+++ b/hw/arm/aspeed.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
17
@@ -XXX,XX +XXX,XX @@
18
tcg_gen_add_i64(tcg_res, tcg_res, tcg_elt);
18
#include "hw/arm/aspeed_soc.h"
19
break;
19
#include "hw/boards.h"
20
case 0x0a: /* SMAXV / UMAXV */
20
#include "hw/i2c/smbus_eeprom.h"
21
- tcg_gen_movcond_i64(is_u ? TCG_COND_GEU : TCG_COND_GE,
21
+#include "hw/misc/pca9552.h"
22
- tcg_res,
22
+#include "hw/misc/tmp105.h"
23
- tcg_res, tcg_elt, tcg_res, tcg_elt);
23
#include "qemu/log.h"
24
+ if (is_u) {
24
#include "sysemu/block-backend.h"
25
+ tcg_gen_umax_i64(tcg_res, tcg_res, tcg_elt);
25
#include "hw/loader.h"
26
+ } else {
26
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
27
+ tcg_gen_smax_i64(tcg_res, tcg_res, tcg_elt);
27
eeprom_buf);
28
+ }
28
29
break;
29
/* The AST2500 EVB expects a LM75 but a TMP105 is compatible */
30
case 0x1a: /* SMINV / UMINV */
30
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d);
31
- tcg_gen_movcond_i64(is_u ? TCG_COND_LEU : TCG_COND_LE,
31
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7),
32
- tcg_res,
32
+ TYPE_TMP105, 0x4d);
33
- tcg_res, tcg_elt, tcg_res, tcg_elt);
33
34
- break;
34
/* The AST2500 EVB does not have an RTC. Let's pretend that one is
35
+ if (is_u) {
35
* plugged on the I2C bus header */
36
+ tcg_gen_umin_i64(tcg_res, tcg_res, tcg_elt);
36
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
37
+ } else {
37
AspeedSoCState *soc = &bmc->soc;
38
+ tcg_gen_smin_i64(tcg_res, tcg_res, tcg_elt);
38
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
39
+ }
39
40
break;
40
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), "pca9552", 0x60);
41
default:
41
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
42
g_assert_not_reached();
42
+ 0x60);
43
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_logic(DisasContext *s, uint32_t insn)
43
44
}
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c);
45
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c);
46
47
/* The Witherspoon expects a TMP275 but a TMP105 is compatible */
48
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "tmp105", 0x4a);
49
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), TYPE_TMP105,
50
+ 0x4a);
51
52
/* The witherspoon board expects Epson RX8900 I2C RTC but a ds1338 is
53
* good enough */
54
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
55
56
smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), 0x51,
57
eeprom_buf);
58
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "pca9552",
59
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
60
0x60);
45
}
61
}
46
62
47
-/* Helper functions for 32 bit comparisons */
48
-static void gen_max_s32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2)
49
-{
50
- tcg_gen_movcond_i32(TCG_COND_GE, res, op1, op2, op1, op2);
51
-}
52
-
53
-static void gen_max_u32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2)
54
-{
55
- tcg_gen_movcond_i32(TCG_COND_GEU, res, op1, op2, op1, op2);
56
-}
57
-
58
-static void gen_min_s32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2)
59
-{
60
- tcg_gen_movcond_i32(TCG_COND_LE, res, op1, op2, op1, op2);
61
-}
62
-
63
-static void gen_min_u32(TCGv_i32 res, TCGv_i32 op1, TCGv_i32 op2)
64
-{
65
- tcg_gen_movcond_i32(TCG_COND_LEU, res, op1, op2, op1, op2);
66
-}
67
-
68
/* Pairwise op subgroup of C3.6.16.
69
*
70
* This is called directly or via the handle_3same_float for float pairwise
71
@@ -XXX,XX +XXX,XX @@ static void handle_simd_3same_pair(DisasContext *s, int is_q, int u, int opcode,
72
static NeonGenTwoOpFn * const fns[3][2] = {
73
{ gen_helper_neon_pmax_s8, gen_helper_neon_pmax_u8 },
74
{ gen_helper_neon_pmax_s16, gen_helper_neon_pmax_u16 },
75
- { gen_max_s32, gen_max_u32 },
76
+ { tcg_gen_smax_i32, tcg_gen_umax_i32 },
77
};
78
genfn = fns[size][u];
79
break;
80
@@ -XXX,XX +XXX,XX @@ static void handle_simd_3same_pair(DisasContext *s, int is_q, int u, int opcode,
81
static NeonGenTwoOpFn * const fns[3][2] = {
82
{ gen_helper_neon_pmin_s8, gen_helper_neon_pmin_u8 },
83
{ gen_helper_neon_pmin_s16, gen_helper_neon_pmin_u16 },
84
- { gen_min_s32, gen_min_u32 },
85
+ { tcg_gen_smin_i32, tcg_gen_umin_i32 },
86
};
87
genfn = fns[size][u];
88
break;
89
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
90
static NeonGenTwoOpFn * const fns[3][2] = {
91
{ gen_helper_neon_max_s8, gen_helper_neon_max_u8 },
92
{ gen_helper_neon_max_s16, gen_helper_neon_max_u16 },
93
- { gen_max_s32, gen_max_u32 },
94
+ { tcg_gen_smax_i32, tcg_gen_umax_i32 },
95
};
96
genfn = fns[size][u];
97
break;
98
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
99
static NeonGenTwoOpFn * const fns[3][2] = {
100
{ gen_helper_neon_min_s8, gen_helper_neon_min_u8 },
101
{ gen_helper_neon_min_s16, gen_helper_neon_min_u16 },
102
- { gen_min_s32, gen_min_u32 },
103
+ { tcg_gen_smin_i32, tcg_gen_umin_i32 },
104
};
105
genfn = fns[size][u];
106
break;
107
--
63
--
108
2.17.0
64
2.20.1
109
65
110
66
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
While we have some of the scalar paths for *CVF for fp16,
3
Suggested-by: Markus Armbruster <armbru@redhat.com>
4
we failed to decode the fp16 version of these instructions.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
5
Message-id: 20190412165416.7977-3-philmd@redhat.com
6
Cc: qemu-stable@nongnu.org
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180502221552.3873-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
target/arm/translate-a64.c | 33 ++++++++++++++++++++-------------
9
hw/arm/nseries.c | 3 ++-
13
1 file changed, 20 insertions(+), 13 deletions(-)
10
1 file changed, 2 insertions(+), 1 deletion(-)
14
11
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
12
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
14
--- a/hw/arm/nseries.c
18
+++ b/target/arm/translate-a64.c
15
+++ b/hw/arm/nseries.c
19
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_intfp_conv(DisasContext *s, bool is_scalar,
16
@@ -XXX,XX +XXX,XX @@
20
int immh, int immb, int opcode,
17
#include "hw/boards.h"
21
int rn, int rd)
18
#include "hw/i2c/i2c.h"
22
{
19
#include "hw/devices.h"
23
- bool is_double = extract32(immh, 3, 1);
20
+#include "hw/misc/tmp105.h"
24
- int size = is_double ? MO_64 : MO_32;
21
#include "hw/block/flash.h"
25
- int elements;
22
#include "hw/hw.h"
26
+ int size, elements, fracbits;
23
#include "hw/bt.h"
27
int immhb = immh << 3 | immb;
24
@@ -XXX,XX +XXX,XX @@ static void n8x0_i2c_setup(struct n800_s *s)
28
- int fracbits = (is_double ? 128 : 64) - immhb;
25
qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
29
26
30
- if (!extract32(immh, 2, 2)) {
27
/* Attach a TMP105 PM chip (A0 wired to ground) */
31
+ if (immh & 8) {
28
- dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
32
+ size = MO_64;
29
+ dev = i2c_create_slave(i2c, TYPE_TMP105, N8X0_TMP105_ADDR);
33
+ if (!is_scalar && !is_q) {
30
qdev_connect_gpio_out(dev, 0, tmp_irq);
34
+ unallocated_encoding(s);
35
+ return;
36
+ }
37
+ } else if (immh & 4) {
38
+ size = MO_32;
39
+ } else if (immh & 2) {
40
+ size = MO_16;
41
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
42
+ unallocated_encoding(s);
43
+ return;
44
+ }
45
+ } else {
46
+ /* immh == 0 would be a failure of the decode logic */
47
+ g_assert(immh == 1);
48
unallocated_encoding(s);
49
return;
50
}
51
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_intfp_conv(DisasContext *s, bool is_scalar,
52
if (is_scalar) {
53
elements = 1;
54
} else {
55
- elements = is_double ? 2 : is_q ? 4 : 2;
56
- if (is_double && !is_q) {
57
- unallocated_encoding(s);
58
- return;
59
- }
60
+ elements = (8 << is_q) >> size;
61
}
62
+ fracbits = (16 << size) - immhb;
63
64
if (!fp_access_check(s)) {
65
return;
66
}
67
68
- /* immh == 0 would be a failure of the decode logic */
69
- g_assert(immh);
70
-
71
handle_simd_intfp_conv(s, rd, rn, elements, !is_u, fracbits, size);
72
}
31
}
73
32
74
--
33
--
75
2.17.0
34
2.20.1
76
35
77
36
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
3
No code used the tc6393xb_gpio_in_get() and tc6393xb_gpio_out_set()
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
functions since their introduction in commit 88d2c950b002. Time to
5
Message-id: 20180508151437.4232-6-richard.henderson@linaro.org
5
remove them.
6
7
Suggested-by: Markus Armbruster <armbru@redhat.com>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190412165416.7977-4-philmd@redhat.com
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
12
---
9
accel/tcg/atomic_template.h | 49 ++++++-------------------------------
13
include/hw/devices.h | 3 ---
10
1 file changed, 7 insertions(+), 42 deletions(-)
14
hw/display/tc6393xb.c | 16 ----------------
15
2 files changed, 19 deletions(-)
11
16
12
diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/accel/tcg/atomic_template.h
19
--- a/include/hw/devices.h
15
+++ b/accel/tcg/atomic_template.h
20
+++ b/include/hw/devices.h
16
@@ -XXX,XX +XXX,XX @@ GEN_ATOMIC_HELPER(xor_fetch)
21
@@ -XXX,XX +XXX,XX @@ void retu_key_event(void *retu, int state);
17
22
typedef struct TC6393xbState TC6393xbState;
18
#undef GEN_ATOMIC_HELPER
23
TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
19
24
uint32_t base, qemu_irq irq);
20
-/* Note that for addition, we need to use a separate cmpxchg loop instead
25
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
21
- of bswaps for the reverse-host-endian helpers. */
26
- qemu_irq handler);
22
-ABI_TYPE ATOMIC_NAME(fetch_add)(CPUArchState *env, target_ulong addr,
27
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s);
23
- ABI_TYPE val EXTRA_ARGS)
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
};
38
39
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s)
24
-{
40
-{
25
- ATOMIC_MMU_DECLS;
41
- return s->gpio_in;
26
- DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
27
- DATA_TYPE ldo, ldn, ret, sto;
28
-
29
- ldo = atomic_read__nocheck(haddr);
30
- while (1) {
31
- ret = BSWAP(ldo);
32
- sto = BSWAP(ret + val);
33
- ldn = atomic_cmpxchg__nocheck(haddr, ldo, sto);
34
- if (ldn == ldo) {
35
- ATOMIC_MMU_CLEANUP;
36
- return ret;
37
- }
38
- ldo = ldn;
39
- }
40
-}
42
-}
41
-
43
-
42
-ABI_TYPE ATOMIC_NAME(add_fetch)(CPUArchState *env, target_ulong addr,
44
static void tc6393xb_gpio_set(void *opaque, int line, int level)
43
- ABI_TYPE val EXTRA_ARGS)
45
{
46
// TC6393xbState *s = opaque;
47
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_gpio_set(void *opaque, int line, int level)
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)
44
-{
53
-{
45
- ATOMIC_MMU_DECLS;
54
- if (line >= TC6393XB_GPIOS) {
46
- DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP;
55
- fprintf(stderr, "TC6393xb: no GPIO pin %d\n", line);
47
- DATA_TYPE ldo, ldn, ret, sto;
56
- return;
57
- }
48
-
58
-
49
- ldo = atomic_read__nocheck(haddr);
59
- s->handler[line] = handler;
50
- while (1) {
51
- ret = BSWAP(ldo) + val;
52
- sto = BSWAP(ret);
53
- ldn = atomic_cmpxchg__nocheck(haddr, ldo, sto);
54
- if (ldn == ldo) {
55
- ATOMIC_MMU_CLEANUP;
56
- return ret;
57
- }
58
- ldo = ldn;
59
- }
60
-}
60
-}
61
-
61
-
62
/* These helpers are, as a whole, full barriers. Within the helper,
62
static void tc6393xb_gpio_handler_update(TC6393xbState *s)
63
* the leading barrier is explicit and the trailing barrier is within
63
{
64
* cmpxchg primitive.
64
uint32_t level, diff;
65
@@ -XXX,XX +XXX,XX @@ GEN_ATOMIC_HELPER_FN(umin_fetch, MIN, DATA_TYPE, new)
66
GEN_ATOMIC_HELPER_FN(smax_fetch, MAX, SDATA_TYPE, new)
67
GEN_ATOMIC_HELPER_FN(umax_fetch, MAX, DATA_TYPE, new)
68
69
+/* Note that for addition, we need to use a separate cmpxchg loop instead
70
+ of bswaps for the reverse-host-endian helpers. */
71
+#define ADD(X, Y) (X + Y)
72
+GEN_ATOMIC_HELPER_FN(fetch_add, ADD, DATA_TYPE, old)
73
+GEN_ATOMIC_HELPER_FN(add_fetch, ADD, DATA_TYPE, new)
74
+#undef ADD
75
+
76
#undef GEN_ATOMIC_HELPER_FN
77
#endif /* DATA_SIZE >= 16 */
78
79
--
65
--
80
2.17.0
66
2.20.1
81
67
82
68
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20190412165416.7977-5-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
include/hw/devices.h | 6 ------
9
include/hw/display/tc6393xb.h | 24 ++++++++++++++++++++++++
10
hw/arm/tosa.c | 2 +-
11
hw/display/tc6393xb.c | 2 +-
12
MAINTAINERS | 1 +
13
5 files changed, 27 insertions(+), 8 deletions(-)
14
create mode 100644 include/hw/display/tc6393xb.h
15
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/devices.h
19
+++ b/include/hw/devices.h
20
@@ -XXX,XX +XXX,XX @@ void *tahvo_init(qemu_irq irq, int betty);
21
22
void retu_key_event(void *retu, int state);
23
24
-/* tc6393xb.c */
25
-typedef struct TC6393xbState TC6393xbState;
26
-TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
27
- uint32_t base, qemu_irq irq);
28
-qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
29
-
30
#endif
31
diff --git a/include/hw/display/tc6393xb.h b/include/hw/display/tc6393xb.h
32
new file mode 100644
33
index XXXXXXX..XXXXXXX
34
--- /dev/null
35
+++ b/include/hw/display/tc6393xb.h
36
@@ -XXX,XX +XXX,XX @@
37
+/*
38
+ * Toshiba TC6393XB I/O Controller.
39
+ * Found in Sharp Zaurus SL-6000 (tosa) or some
40
+ * Toshiba e-Series PDAs.
41
+ *
42
+ * Copyright (c) 2007 Hervé Poussineau
43
+ *
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
45
+ * See the COPYING file in the top-level directory.
46
+ */
47
+
48
+#ifndef HW_DISPLAY_TC6393XB_H
49
+#define HW_DISPLAY_TC6393XB_H
50
+
51
+#include "exec/memory.h"
52
+#include "hw/irq.h"
53
+
54
+typedef struct TC6393xbState TC6393xbState;
55
+
56
+TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
57
+ uint32_t base, qemu_irq irq);
58
+qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
59
+
60
+#endif
61
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/tosa.c
64
+++ b/hw/arm/tosa.c
65
@@ -XXX,XX +XXX,XX @@
66
#include "hw/hw.h"
67
#include "hw/arm/pxa.h"
68
#include "hw/arm/arm.h"
69
-#include "hw/devices.h"
70
#include "hw/arm/sharpsl.h"
71
#include "hw/pcmcia.h"
72
#include "hw/boards.h"
73
+#include "hw/display/tc6393xb.h"
74
#include "hw/i2c/i2c.h"
75
#include "hw/ssi/ssi.h"
76
#include "hw/sysbus.h"
77
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/display/tc6393xb.c
80
+++ b/hw/display/tc6393xb.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "qapi/error.h"
83
#include "qemu/host-utils.h"
84
#include "hw/hw.h"
85
-#include "hw/devices.h"
86
+#include "hw/display/tc6393xb.h"
87
#include "hw/block/flash.h"
88
#include "ui/console.h"
89
#include "ui/pixel_ops.h"
90
diff --git a/MAINTAINERS b/MAINTAINERS
91
index XXXXXXX..XXXXXXX 100644
92
--- a/MAINTAINERS
93
+++ b/MAINTAINERS
94
@@ -XXX,XX +XXX,XX @@ F: hw/misc/mst_fpga.c
95
F: hw/misc/max111x.c
96
F: include/hw/arm/pxa.h
97
F: include/hw/arm/sharpsl.h
98
+F: include/hw/display/tc6393xb.h
99
100
SABRELITE / i.MX6
101
M: Peter Maydell <peter.maydell@linaro.org>
102
--
103
2.20.1
104
105
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
Add an entries the Blizzard device in MAINTAINERS.
4
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190412165416.7977-6-philmd@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/devices.h | 7 -------
12
include/hw/display/blizzard.h | 22 ++++++++++++++++++++++
13
hw/arm/nseries.c | 1 +
14
hw/display/blizzard.c | 2 +-
15
MAINTAINERS | 2 ++
16
5 files changed, 26 insertions(+), 8 deletions(-)
17
create mode 100644 include/hw/display/blizzard.h
18
19
diff --git a/include/hw/devices.h b/include/hw/devices.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/devices.h
22
+++ b/include/hw/devices.h
23
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
24
/* stellaris_input.c */
25
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
26
27
-/* blizzard.c */
28
-void *s1d13745_init(qemu_irq gpio_int);
29
-void s1d13745_write(void *opaque, int dc, uint16_t value);
30
-void s1d13745_write_block(void *opaque, int dc,
31
- void *buf, size_t len, int pitch);
32
-uint16_t s1d13745_read(void *opaque, int dc);
33
-
34
/* cbus.c */
35
typedef struct {
36
qemu_irq clk;
37
diff --git a/include/hw/display/blizzard.h b/include/hw/display/blizzard.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/display/blizzard.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * Epson S1D13744/S1D13745 (Blizzard/Hailstorm/Tornado) LCD/TV controller.
45
+ *
46
+ * Copyright (C) 2008 Nokia Corporation
47
+ * Written by Andrzej Zaborowski
48
+ *
49
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
50
+ * See the COPYING file in the top-level directory.
51
+ */
52
+
53
+#ifndef HW_DISPLAY_BLIZZARD_H
54
+#define HW_DISPLAY_BLIZZARD_H
55
+
56
+#include "hw/irq.h"
57
+
58
+void *s1d13745_init(qemu_irq gpio_int);
59
+void s1d13745_write(void *opaque, int dc, uint16_t value);
60
+void s1d13745_write_block(void *opaque, int dc,
61
+ void *buf, size_t len, int pitch);
62
+uint16_t s1d13745_read(void *opaque, int dc);
63
+
64
+#endif
65
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/arm/nseries.c
68
+++ b/hw/arm/nseries.c
69
@@ -XXX,XX +XXX,XX @@
70
#include "hw/boards.h"
71
#include "hw/i2c/i2c.h"
72
#include "hw/devices.h"
73
+#include "hw/display/blizzard.h"
74
#include "hw/misc/tmp105.h"
75
#include "hw/block/flash.h"
76
#include "hw/hw.h"
77
diff --git a/hw/display/blizzard.c b/hw/display/blizzard.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/display/blizzard.c
80
+++ b/hw/display/blizzard.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "qemu/osdep.h"
83
#include "qemu-common.h"
84
#include "ui/console.h"
85
-#include "hw/devices.h"
86
+#include "hw/display/blizzard.h"
87
#include "ui/pixel_ops.h"
88
89
typedef void (*blizzard_fn_t)(uint8_t *, const uint8_t *, unsigned int);
90
diff --git a/MAINTAINERS b/MAINTAINERS
91
index XXXXXXX..XXXXXXX 100644
92
--- a/MAINTAINERS
93
+++ b/MAINTAINERS
94
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
95
L: qemu-arm@nongnu.org
96
S: Odd Fixes
97
F: hw/arm/nseries.c
98
+F: hw/display/blizzard.c
99
F: hw/input/lm832x.c
100
F: hw/input/tsc2005.c
101
F: hw/misc/cbus.c
102
F: hw/timer/twl92230.c
103
+F: include/hw/display/blizzard.h
104
105
Palm
106
M: Andrzej Zaborowski <balrogg@gmail.com>
107
--
108
2.20.1
109
110
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Use write_fp_dreg and clear_vec_high to zero the bits
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
that need zeroing for these cases.
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Cc: qemu-stable@nongnu.org
6
Message-id: 20190412165416.7977-7-philmd@redhat.com
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180502221552.3873-5-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
target/arm/translate-a64.c | 17 +++++------------
9
include/hw/devices.h | 14 --------------
13
1 file changed, 5 insertions(+), 12 deletions(-)
10
include/hw/misc/cbus.h | 32 ++++++++++++++++++++++++++++++++
11
hw/arm/nseries.c | 1 +
12
hw/misc/cbus.c | 2 +-
13
MAINTAINERS | 1 +
14
5 files changed, 35 insertions(+), 15 deletions(-)
15
create mode 100644 include/hw/misc/cbus.h
14
16
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
19
--- a/include/hw/devices.h
18
+++ b/target/arm/translate-a64.c
20
+++ b/include/hw/devices.h
19
@@ -XXX,XX +XXX,XX @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
21
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
20
22
/* stellaris_input.c */
21
if (itof) {
23
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
22
TCGv_i64 tcg_rn = cpu_reg(s, rn);
24
23
+ TCGv_i64 tmp;
25
-/* cbus.c */
24
26
-typedef struct {
25
switch (type) {
27
- qemu_irq clk;
26
case 0:
28
- qemu_irq dat;
27
- {
29
- qemu_irq sel;
28
/* 32 bit */
30
-} CBus;
29
- TCGv_i64 tmp = tcg_temp_new_i64();
31
-CBus *cbus_init(qemu_irq dat_out);
30
+ tmp = tcg_temp_new_i64();
32
-void cbus_attach(CBus *bus, void *slave_opaque);
31
tcg_gen_ext32u_i64(tmp, tcg_rn);
33
-
32
- tcg_gen_st_i64(tmp, cpu_env, fp_reg_offset(s, rd, MO_64));
34
-void *retu_init(qemu_irq irq, int vilma);
33
- tcg_gen_movi_i64(tmp, 0);
35
-void *tahvo_init(qemu_irq irq, int betty);
34
- tcg_gen_st_i64(tmp, cpu_env, fp_reg_hi_offset(s, rd));
36
-
35
+ write_fp_dreg(s, rd, tmp);
37
-void retu_key_event(void *retu, int state);
36
tcg_temp_free_i64(tmp);
38
-
37
break;
39
#endif
38
- }
40
diff --git a/include/hw/misc/cbus.h b/include/hw/misc/cbus.h
39
case 1:
41
new file mode 100644
40
- {
42
index XXXXXXX..XXXXXXX
41
/* 64 bit */
43
--- /dev/null
42
- TCGv_i64 tmp = tcg_const_i64(0);
44
+++ b/include/hw/misc/cbus.h
43
- tcg_gen_st_i64(tcg_rn, cpu_env, fp_reg_offset(s, rd, MO_64));
45
@@ -XXX,XX +XXX,XX @@
44
- tcg_gen_st_i64(tmp, cpu_env, fp_reg_hi_offset(s, rd));
46
+/*
45
- tcg_temp_free_i64(tmp);
47
+ * CBUS three-pin bus and the Retu / Betty / Tahvo / Vilma / Avilma /
46
+ write_fp_dreg(s, rd, tcg_rn);
48
+ * Hinku / Vinku / Ahne / Pihi chips used in various Nokia platforms.
47
break;
49
+ * Based on reverse-engineering of a linux driver.
48
- }
50
+ *
49
case 2:
51
+ * Copyright (C) 2008 Nokia Corporation
50
/* 64 bit to top half. */
52
+ * Written by Andrzej Zaborowski
51
tcg_gen_st_i64(tcg_rn, cpu_env, fp_reg_hi_offset(s, rd));
53
+ *
52
+ clear_vec_high(s, true, rd);
54
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
53
break;
55
+ * See the COPYING file in the top-level directory.
54
}
56
+ */
55
} else {
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
104
index XXXXXXX..XXXXXXX 100644
105
--- a/MAINTAINERS
106
+++ b/MAINTAINERS
107
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
108
F: hw/misc/cbus.c
109
F: hw/timer/twl92230.c
110
F: include/hw/display/blizzard.h
111
+F: include/hw/misc/cbus.h
112
113
Palm
114
M: Andrzej Zaborowski <balrogg@gmail.com>
56
--
115
--
57
2.17.0
116
2.20.1
58
117
59
118
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20180508151437.4232-11-richard.henderson@linaro.org
5
Message-id: 20190412165416.7977-8-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
target/arm/cpu64.c | 1 +
8
include/hw/devices.h | 3 ---
9
1 file changed, 1 insertion(+)
9
include/hw/input/gamepad.h | 19 +++++++++++++++++++
10
hw/arm/stellaris.c | 2 +-
11
hw/input/stellaris_input.c | 2 +-
12
MAINTAINERS | 1 +
13
5 files changed, 22 insertions(+), 5 deletions(-)
14
create mode 100644 include/hw/input/gamepad.h
10
15
11
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu64.c
18
--- a/include/hw/devices.h
14
+++ b/target/arm/cpu64.c
19
+++ b/include/hw/devices.h
15
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ void *tsc2005_init(qemu_irq pintdav);
16
set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
21
uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
17
set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
22
void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
18
set_feature(&cpu->env, ARM_FEATURE_CRC);
23
19
+ set_feature(&cpu->env, ARM_FEATURE_V8_ATOMICS);
24
-/* stellaris_input.c */
20
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
25
-void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
21
set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
26
-
22
set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
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
87
index XXXXXXX..XXXXXXX 100644
88
--- a/MAINTAINERS
89
+++ b/MAINTAINERS
90
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
91
L: qemu-arm@nongnu.org
92
S: Maintained
93
F: hw/*/stellaris*
94
+F: include/hw/input/gamepad.h
95
96
Versatile Express
97
M: Peter Maydell <peter.maydell@linaro.org>
23
--
98
--
24
2.17.0
99
2.20.1
25
100
26
101
diff view generated by jsdifflib
New patch
1
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
3
Since uWireSlave is only used in this new header, there is no
4
need to expose it via "qemu/typedefs.h".
5
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190412165416.7977-9-philmd@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/omap.h | 6 +-----
12
include/hw/devices.h | 15 ---------------
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
23
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/omap.h
26
+++ b/include/hw/arm/omap.h
27
@@ -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"
157
#include "exec/address-spaces.h"
158
#include "cpu.h"
159
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/hw/input/tsc2005.c
162
+++ b/hw/input/tsc2005.c
163
@@ -XXX,XX +XXX,XX @@
164
#include "hw/hw.h"
165
#include "qemu/timer.h"
166
#include "ui/console.h"
167
-#include "hw/devices.h"
168
+#include "hw/input/tsc2xxx.h"
169
#include "trace.h"
170
171
#define TSC_CUT_RESOLUTION(value, p)    ((value) >> (16 - (p ? 12 : 10)))
172
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/hw/input/tsc210x.c
175
+++ b/hw/input/tsc210x.c
176
@@ -XXX,XX +XXX,XX @@
177
#include "audio/audio.h"
178
#include "qemu/timer.h"
179
#include "ui/console.h"
180
-#include "hw/arm/omap.h"    /* For I2SCodec and uWireSlave */
181
-#include "hw/devices.h"
182
+#include "hw/arm/omap.h" /* For I2SCodec */
183
+#include "hw/input/tsc2xxx.h"
184
185
#define TSC_DATA_REGISTERS_PAGE        0x0
186
#define TSC_CONTROL_REGISTERS_PAGE    0x1
187
diff --git a/MAINTAINERS b/MAINTAINERS
188
index XXXXXXX..XXXXXXX 100644
189
--- a/MAINTAINERS
190
+++ b/MAINTAINERS
191
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
192
F: hw/misc/cbus.c
193
F: hw/timer/twl92230.c
194
F: include/hw/display/blizzard.h
195
+F: include/hw/input/tsc2xxx.h
196
F: include/hw/misc/cbus.h
197
198
Palm
199
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
200
S: Odd Fixes
201
F: hw/arm/palm.c
202
F: hw/input/tsc210x.c
203
+F: include/hw/input/tsc2xxx.h
204
205
Raspberry Pi
206
M: Peter Maydell <peter.maydell@linaro.org>
207
--
208
2.20.1
209
210
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Reviewed-by: Michael Clark <mjc@sifive.com>
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20180508151437.4232-7-richard.henderson@linaro.org
5
Message-id: 20190412165416.7977-10-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
target/riscv/translate.c | 72 +++++++++++-----------------------------
8
include/hw/devices.h | 3 ---
9
1 file changed, 20 insertions(+), 52 deletions(-)
9
include/hw/net/lan9118.h | 19 +++++++++++++++++++
10
hw/arm/kzm.c | 2 +-
11
hw/arm/mps2.c | 2 +-
12
hw/arm/realview.c | 1 +
13
hw/arm/vexpress.c | 2 +-
14
hw/net/lan9118.c | 2 +-
15
7 files changed, 24 insertions(+), 7 deletions(-)
16
create mode 100644 include/hw/net/lan9118.h
10
17
11
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
18
diff --git a/include/hw/devices.h b/include/hw/devices.h
12
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
13
--- a/target/riscv/translate.c
20
--- a/include/hw/devices.h
14
+++ b/target/riscv/translate.c
21
+++ b/include/hw/devices.h
15
@@ -XXX,XX +XXX,XX @@ static void gen_atomic(DisasContext *ctx, uint32_t opc,
22
@@ -XXX,XX +XXX,XX @@
16
TCGv src1, src2, dat;
23
/* smc91c111.c */
17
TCGLabel *l1, *l2;
24
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
18
TCGMemOp mop;
25
19
- TCGCond cond;
26
-/* lan9118.c */
20
bool aq, rl;
27
-void lan9118_init(NICInfo *, uint32_t, qemu_irq);
21
22
/* Extract the size of the atomic operation. */
23
@@ -XXX,XX +XXX,XX @@ static void gen_atomic(DisasContext *ctx, uint32_t opc,
24
tcg_gen_atomic_fetch_or_tl(src2, src1, src2, ctx->mem_idx, mop);
25
gen_set_gpr(rd, src2);
26
break;
27
-
28
-
28
case OPC_RISC_AMOMIN:
29
#endif
29
- cond = TCG_COND_LT;
30
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
30
- goto do_minmax;
31
new file mode 100644
31
- case OPC_RISC_AMOMAX:
32
index XXXXXXX..XXXXXXX
32
- cond = TCG_COND_GT;
33
--- /dev/null
33
- goto do_minmax;
34
+++ b/include/hw/net/lan9118.h
34
- case OPC_RISC_AMOMINU:
35
@@ -XXX,XX +XXX,XX @@
35
- cond = TCG_COND_LTU;
36
+/*
36
- goto do_minmax;
37
+ * SMSC LAN9118 Ethernet interface emulation
37
- case OPC_RISC_AMOMAXU:
38
+ *
38
- cond = TCG_COND_GTU;
39
+ * Copyright (c) 2009 CodeSourcery, LLC.
39
- goto do_minmax;
40
+ * Written by Paul Brook
40
- do_minmax:
41
+ *
41
- /* Handle the RL barrier. The AQ barrier is handled along the
42
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
42
- parallel path by the SC atomic cmpxchg. On the serial path,
43
+ * See the COPYING file in the top-level directory.
43
- of course, barriers do not matter. */
44
+ */
44
- if (rl) {
45
+
45
- tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
46
+#ifndef HW_NET_LAN9118_H
46
- }
47
+#define HW_NET_LAN9118_H
47
- if (tb_cflags(ctx->tb) & CF_PARALLEL) {
48
+
48
- l1 = gen_new_label();
49
+#include "hw/irq.h"
49
- gen_set_label(l1);
50
+#include "net/net.h"
50
- } else {
51
+
51
- l1 = NULL;
52
+void lan9118_init(NICInfo *, uint32_t, qemu_irq);
52
- }
53
+
53
-
54
+#endif
54
gen_get_gpr(src1, rs1);
55
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
55
gen_get_gpr(src2, rs2);
56
index XXXXXXX..XXXXXXX 100644
56
- if ((mop & MO_SSIZE) == MO_SL) {
57
--- a/hw/arm/kzm.c
57
- /* Sign-extend the register comparison input. */
58
+++ b/hw/arm/kzm.c
58
- tcg_gen_ext32s_tl(src2, src2);
59
@@ -XXX,XX +XXX,XX @@
59
- }
60
#include "qemu/error-report.h"
60
- dat = tcg_temp_local_new();
61
#include "exec/address-spaces.h"
61
- tcg_gen_qemu_ld_tl(dat, src1, ctx->mem_idx, mop);
62
#include "net/net.h"
62
- tcg_gen_movcond_tl(cond, src2, dat, src2, dat, src2);
63
-#include "hw/devices.h"
63
-
64
+#include "hw/net/lan9118.h"
64
- if (tb_cflags(ctx->tb) & CF_PARALLEL) {
65
#include "hw/char/serial.h"
65
- /* Parallel context. Make this operation atomic by verifying
66
#include "sysemu/qtest.h"
66
- that the memory didn't change while we computed the result. */
67
67
- tcg_gen_atomic_cmpxchg_tl(src2, src1, dat, src2, ctx->mem_idx, mop);
68
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
68
-
69
index XXXXXXX..XXXXXXX 100644
69
- /* If the cmpxchg failed, retry. */
70
--- a/hw/arm/mps2.c
70
- /* ??? There is an assumption here that this will eventually
71
+++ b/hw/arm/mps2.c
71
- succeed, such that we don't live-lock. This is not unlike
72
@@ -XXX,XX +XXX,XX @@
72
- a similar loop that the compiler would generate for e.g.
73
#include "hw/timer/cmsdk-apb-timer.h"
73
- __atomic_fetch_and_xor, so don't worry about it. */
74
#include "hw/timer/cmsdk-apb-dualtimer.h"
74
- tcg_gen_brcond_tl(TCG_COND_NE, dat, src2, l1);
75
#include "hw/misc/mps2-scc.h"
75
- } else {
76
-#include "hw/devices.h"
76
- /* Serial context. Directly store the result. */
77
+#include "hw/net/lan9118.h"
77
- tcg_gen_qemu_st_tl(src2, src1, ctx->mem_idx, mop);
78
#include "net/net.h"
78
- }
79
79
- gen_set_gpr(rd, dat);
80
typedef enum MPS2FPGAType {
80
- tcg_temp_free(dat);
81
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
81
+ tcg_gen_atomic_fetch_smin_tl(src2, src1, src2, ctx->mem_idx, mop);
82
index XXXXXXX..XXXXXXX 100644
82
+ gen_set_gpr(rd, src2);
83
--- a/hw/arm/realview.c
83
+ break;
84
+++ b/hw/arm/realview.c
84
+ case OPC_RISC_AMOMAX:
85
@@ -XXX,XX +XXX,XX @@
85
+ gen_get_gpr(src1, rs1);
86
#include "hw/arm/arm.h"
86
+ gen_get_gpr(src2, rs2);
87
#include "hw/arm/primecell.h"
87
+ tcg_gen_atomic_fetch_smax_tl(src2, src1, src2, ctx->mem_idx, mop);
88
#include "hw/devices.h"
88
+ gen_set_gpr(rd, src2);
89
+#include "hw/net/lan9118.h"
89
+ break;
90
#include "hw/pci/pci.h"
90
+ case OPC_RISC_AMOMINU:
91
#include "net/net.h"
91
+ gen_get_gpr(src1, rs1);
92
#include "sysemu/sysemu.h"
92
+ gen_get_gpr(src2, rs2);
93
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
93
+ tcg_gen_atomic_fetch_umin_tl(src2, src1, src2, ctx->mem_idx, mop);
94
index XXXXXXX..XXXXXXX 100644
94
+ gen_set_gpr(rd, src2);
95
--- a/hw/arm/vexpress.c
95
+ break;
96
+++ b/hw/arm/vexpress.c
96
+ case OPC_RISC_AMOMAXU:
97
@@ -XXX,XX +XXX,XX @@
97
+ gen_get_gpr(src1, rs1);
98
#include "hw/sysbus.h"
98
+ gen_get_gpr(src2, rs2);
99
#include "hw/arm/arm.h"
99
+ tcg_gen_atomic_fetch_umax_tl(src2, src1, src2, ctx->mem_idx, mop);
100
#include "hw/arm/primecell.h"
100
+ gen_set_gpr(rd, src2);
101
-#include "hw/devices.h"
101
break;
102
+#include "hw/net/lan9118.h"
102
103
#include "hw/i2c/i2c.h"
103
default:
104
#include "net/net.h"
105
#include "sysemu/sysemu.h"
106
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/net/lan9118.c
109
+++ b/hw/net/lan9118.c
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
112
#include "net/net.h"
113
#include "net/eth.h"
114
-#include "hw/devices.h"
115
+#include "hw/net/lan9118.h"
116
#include "sysemu/sysemu.h"
117
#include "hw/ptimer.h"
118
#include "qemu/log.h"
104
--
119
--
105
2.17.0
120
2.20.1
106
121
107
122
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Given that this atomic operation will be used by both risc-v
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
and aarch64, let's not duplicate code across the two targets.
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Message-id: 20190412165416.7977-11-philmd@redhat.com
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180508151437.4232-5-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
8
---
11
accel/tcg/atomic_template.h | 71 +++++++++++++++++++++++++++++++++++++
9
include/hw/net/ne2000-isa.h | 6 ++++++
12
accel/tcg/tcg-runtime.h | 8 +++++
10
1 file changed, 6 insertions(+)
13
tcg/tcg-op.h | 34 ++++++++++++++++++
14
tcg/tcg.h | 8 +++++
15
tcg/tcg-op.c | 8 +++++
16
5 files changed, 129 insertions(+)
17
11
18
diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h
12
diff --git a/include/hw/net/ne2000-isa.h b/include/hw/net/ne2000-isa.h
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/accel/tcg/atomic_template.h
14
--- a/include/hw/net/ne2000-isa.h
21
+++ b/accel/tcg/atomic_template.h
15
+++ b/include/hw/net/ne2000-isa.h
22
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
23
#elif DATA_SIZE == 8
17
* This work is licensed under the terms of the GNU GPL, version 2 or later.
24
# define SUFFIX q
18
* See the COPYING file in the top-level directory.
25
# define DATA_TYPE uint64_t
19
*/
26
+# define SDATA_TYPE int64_t
27
# define BSWAP bswap64
28
#elif DATA_SIZE == 4
29
# define SUFFIX l
30
# define DATA_TYPE uint32_t
31
+# define SDATA_TYPE int32_t
32
# define BSWAP bswap32
33
#elif DATA_SIZE == 2
34
# define SUFFIX w
35
# define DATA_TYPE uint16_t
36
+# define SDATA_TYPE int16_t
37
# define BSWAP bswap16
38
#elif DATA_SIZE == 1
39
# define SUFFIX b
40
# define DATA_TYPE uint8_t
41
+# define SDATA_TYPE int8_t
42
# define BSWAP
43
#else
44
# error unsupported data size
45
@@ -XXX,XX +XXX,XX @@ GEN_ATOMIC_HELPER(or_fetch)
46
GEN_ATOMIC_HELPER(xor_fetch)
47
48
#undef GEN_ATOMIC_HELPER
49
+
20
+
50
+/* These helpers are, as a whole, full barriers. Within the helper,
21
+#ifndef HW_NET_NE2K_ISA_H
51
+ * the leading barrier is explicit and the trailing barrier is within
22
+#define HW_NET_NE2K_ISA_H
52
+ * cmpxchg primitive.
53
+ */
54
+#define GEN_ATOMIC_HELPER_FN(X, FN, XDATA_TYPE, RET) \
55
+ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
56
+ ABI_TYPE xval EXTRA_ARGS) \
57
+{ \
58
+ ATOMIC_MMU_DECLS; \
59
+ XDATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
60
+ XDATA_TYPE cmp, old, new, val = xval; \
61
+ smp_mb(); \
62
+ cmp = atomic_read__nocheck(haddr); \
63
+ do { \
64
+ old = cmp; new = FN(old, val); \
65
+ cmp = atomic_cmpxchg__nocheck(haddr, old, new); \
66
+ } while (cmp != old); \
67
+ ATOMIC_MMU_CLEANUP; \
68
+ return RET; \
69
+}
70
+
23
+
71
+GEN_ATOMIC_HELPER_FN(fetch_smin, MIN, SDATA_TYPE, old)
24
#include "hw/hw.h"
72
+GEN_ATOMIC_HELPER_FN(fetch_umin, MIN, DATA_TYPE, old)
25
#include "hw/qdev.h"
73
+GEN_ATOMIC_HELPER_FN(fetch_smax, MAX, SDATA_TYPE, old)
26
#include "hw/isa/isa.h"
74
+GEN_ATOMIC_HELPER_FN(fetch_umax, MAX, DATA_TYPE, old)
27
@@ -XXX,XX +XXX,XX @@ static inline ISADevice *isa_ne2000_init(ISABus *bus, int base, int irq,
75
+
76
+GEN_ATOMIC_HELPER_FN(smin_fetch, MIN, SDATA_TYPE, new)
77
+GEN_ATOMIC_HELPER_FN(umin_fetch, MIN, DATA_TYPE, new)
78
+GEN_ATOMIC_HELPER_FN(smax_fetch, MAX, SDATA_TYPE, new)
79
+GEN_ATOMIC_HELPER_FN(umax_fetch, MAX, DATA_TYPE, new)
80
+
81
+#undef GEN_ATOMIC_HELPER_FN
82
#endif /* DATA SIZE >= 16 */
83
84
#undef END
85
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(add_fetch)(CPUArchState *env, target_ulong addr,
86
ldo = ldn;
87
}
28
}
29
return d;
88
}
30
}
89
+
31
+
90
+/* These helpers are, as a whole, full barriers. Within the helper,
32
+#endif
91
+ * the leading barrier is explicit and the trailing barrier is within
92
+ * cmpxchg primitive.
93
+ */
94
+#define GEN_ATOMIC_HELPER_FN(X, FN, XDATA_TYPE, RET) \
95
+ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
96
+ ABI_TYPE xval EXTRA_ARGS) \
97
+{ \
98
+ ATOMIC_MMU_DECLS; \
99
+ XDATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
100
+ XDATA_TYPE ldo, ldn, old, new, val = xval; \
101
+ smp_mb(); \
102
+ ldn = atomic_read__nocheck(haddr); \
103
+ do { \
104
+ ldo = ldn; old = BSWAP(ldo); new = FN(old, val); \
105
+ ldn = atomic_cmpxchg__nocheck(haddr, ldo, BSWAP(new)); \
106
+ } while (ldo != ldn); \
107
+ ATOMIC_MMU_CLEANUP; \
108
+ return RET; \
109
+}
110
+
111
+GEN_ATOMIC_HELPER_FN(fetch_smin, MIN, SDATA_TYPE, old)
112
+GEN_ATOMIC_HELPER_FN(fetch_umin, MIN, DATA_TYPE, old)
113
+GEN_ATOMIC_HELPER_FN(fetch_smax, MAX, SDATA_TYPE, old)
114
+GEN_ATOMIC_HELPER_FN(fetch_umax, MAX, DATA_TYPE, old)
115
+
116
+GEN_ATOMIC_HELPER_FN(smin_fetch, MIN, SDATA_TYPE, new)
117
+GEN_ATOMIC_HELPER_FN(umin_fetch, MIN, DATA_TYPE, new)
118
+GEN_ATOMIC_HELPER_FN(smax_fetch, MAX, SDATA_TYPE, new)
119
+GEN_ATOMIC_HELPER_FN(umax_fetch, MAX, DATA_TYPE, new)
120
+
121
+#undef GEN_ATOMIC_HELPER_FN
122
#endif /* DATA_SIZE >= 16 */
123
124
#undef END
125
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(add_fetch)(CPUArchState *env, target_ulong addr,
126
#undef BSWAP
127
#undef ABI_TYPE
128
#undef DATA_TYPE
129
+#undef SDATA_TYPE
130
#undef SUFFIX
131
#undef DATA_SIZE
132
diff --git a/accel/tcg/tcg-runtime.h b/accel/tcg/tcg-runtime.h
133
index XXXXXXX..XXXXXXX 100644
134
--- a/accel/tcg/tcg-runtime.h
135
+++ b/accel/tcg/tcg-runtime.h
136
@@ -XXX,XX +XXX,XX @@ GEN_ATOMIC_HELPERS(fetch_add)
137
GEN_ATOMIC_HELPERS(fetch_and)
138
GEN_ATOMIC_HELPERS(fetch_or)
139
GEN_ATOMIC_HELPERS(fetch_xor)
140
+GEN_ATOMIC_HELPERS(fetch_smin)
141
+GEN_ATOMIC_HELPERS(fetch_umin)
142
+GEN_ATOMIC_HELPERS(fetch_smax)
143
+GEN_ATOMIC_HELPERS(fetch_umax)
144
145
GEN_ATOMIC_HELPERS(add_fetch)
146
GEN_ATOMIC_HELPERS(and_fetch)
147
GEN_ATOMIC_HELPERS(or_fetch)
148
GEN_ATOMIC_HELPERS(xor_fetch)
149
+GEN_ATOMIC_HELPERS(smin_fetch)
150
+GEN_ATOMIC_HELPERS(umin_fetch)
151
+GEN_ATOMIC_HELPERS(smax_fetch)
152
+GEN_ATOMIC_HELPERS(umax_fetch)
153
154
GEN_ATOMIC_HELPERS(xchg)
155
156
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
157
index XXXXXXX..XXXXXXX 100644
158
--- a/tcg/tcg-op.h
159
+++ b/tcg/tcg-op.h
160
@@ -XXX,XX +XXX,XX @@ void tcg_gen_atomic_cmpxchg_i64(TCGv_i64, TCGv, TCGv_i64, TCGv_i64,
161
162
void tcg_gen_atomic_xchg_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
163
void tcg_gen_atomic_xchg_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
164
+
165
void tcg_gen_atomic_fetch_add_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
166
void tcg_gen_atomic_fetch_add_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
167
void tcg_gen_atomic_fetch_and_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
168
@@ -XXX,XX +XXX,XX @@ void tcg_gen_atomic_fetch_or_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
169
void tcg_gen_atomic_fetch_or_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
170
void tcg_gen_atomic_fetch_xor_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
171
void tcg_gen_atomic_fetch_xor_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
172
+void tcg_gen_atomic_fetch_smin_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
173
+void tcg_gen_atomic_fetch_smin_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
174
+void tcg_gen_atomic_fetch_umin_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
175
+void tcg_gen_atomic_fetch_umin_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
176
+void tcg_gen_atomic_fetch_smax_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
177
+void tcg_gen_atomic_fetch_smax_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
178
+void tcg_gen_atomic_fetch_umax_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
179
+void tcg_gen_atomic_fetch_umax_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
180
+
181
void tcg_gen_atomic_add_fetch_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
182
void tcg_gen_atomic_add_fetch_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
183
void tcg_gen_atomic_and_fetch_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
184
@@ -XXX,XX +XXX,XX @@ void tcg_gen_atomic_or_fetch_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
185
void tcg_gen_atomic_or_fetch_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
186
void tcg_gen_atomic_xor_fetch_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
187
void tcg_gen_atomic_xor_fetch_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
188
+void tcg_gen_atomic_smin_fetch_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
189
+void tcg_gen_atomic_smin_fetch_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
190
+void tcg_gen_atomic_umin_fetch_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
191
+void tcg_gen_atomic_umin_fetch_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
192
+void tcg_gen_atomic_smax_fetch_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
193
+void tcg_gen_atomic_smax_fetch_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
194
+void tcg_gen_atomic_umax_fetch_i32(TCGv_i32, TCGv, TCGv_i32, TCGArg, TCGMemOp);
195
+void tcg_gen_atomic_umax_fetch_i64(TCGv_i64, TCGv, TCGv_i64, TCGArg, TCGMemOp);
196
197
void tcg_gen_mov_vec(TCGv_vec, TCGv_vec);
198
void tcg_gen_dup_i32_vec(unsigned vece, TCGv_vec, TCGv_i32);
199
@@ -XXX,XX +XXX,XX @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t);
200
#define tcg_gen_atomic_fetch_and_tl tcg_gen_atomic_fetch_and_i64
201
#define tcg_gen_atomic_fetch_or_tl tcg_gen_atomic_fetch_or_i64
202
#define tcg_gen_atomic_fetch_xor_tl tcg_gen_atomic_fetch_xor_i64
203
+#define tcg_gen_atomic_fetch_smin_tl tcg_gen_atomic_fetch_smin_i64
204
+#define tcg_gen_atomic_fetch_umin_tl tcg_gen_atomic_fetch_umin_i64
205
+#define tcg_gen_atomic_fetch_smax_tl tcg_gen_atomic_fetch_smax_i64
206
+#define tcg_gen_atomic_fetch_umax_tl tcg_gen_atomic_fetch_umax_i64
207
#define tcg_gen_atomic_add_fetch_tl tcg_gen_atomic_add_fetch_i64
208
#define tcg_gen_atomic_and_fetch_tl tcg_gen_atomic_and_fetch_i64
209
#define tcg_gen_atomic_or_fetch_tl tcg_gen_atomic_or_fetch_i64
210
#define tcg_gen_atomic_xor_fetch_tl tcg_gen_atomic_xor_fetch_i64
211
+#define tcg_gen_atomic_smin_fetch_tl tcg_gen_atomic_smin_fetch_i64
212
+#define tcg_gen_atomic_umin_fetch_tl tcg_gen_atomic_umin_fetch_i64
213
+#define tcg_gen_atomic_smax_fetch_tl tcg_gen_atomic_smax_fetch_i64
214
+#define tcg_gen_atomic_umax_fetch_tl tcg_gen_atomic_umax_fetch_i64
215
#define tcg_gen_dup_tl_vec tcg_gen_dup_i64_vec
216
#else
217
#define tcg_gen_movi_tl tcg_gen_movi_i32
218
@@ -XXX,XX +XXX,XX @@ void tcg_gen_stl_vec(TCGv_vec r, TCGv_ptr base, TCGArg offset, TCGType t);
219
#define tcg_gen_atomic_fetch_and_tl tcg_gen_atomic_fetch_and_i32
220
#define tcg_gen_atomic_fetch_or_tl tcg_gen_atomic_fetch_or_i32
221
#define tcg_gen_atomic_fetch_xor_tl tcg_gen_atomic_fetch_xor_i32
222
+#define tcg_gen_atomic_fetch_smin_tl tcg_gen_atomic_fetch_smin_i32
223
+#define tcg_gen_atomic_fetch_umin_tl tcg_gen_atomic_fetch_umin_i32
224
+#define tcg_gen_atomic_fetch_smax_tl tcg_gen_atomic_fetch_smax_i32
225
+#define tcg_gen_atomic_fetch_umax_tl tcg_gen_atomic_fetch_umax_i32
226
#define tcg_gen_atomic_add_fetch_tl tcg_gen_atomic_add_fetch_i32
227
#define tcg_gen_atomic_and_fetch_tl tcg_gen_atomic_and_fetch_i32
228
#define tcg_gen_atomic_or_fetch_tl tcg_gen_atomic_or_fetch_i32
229
#define tcg_gen_atomic_xor_fetch_tl tcg_gen_atomic_xor_fetch_i32
230
+#define tcg_gen_atomic_smin_fetch_tl tcg_gen_atomic_smin_fetch_i32
231
+#define tcg_gen_atomic_umin_fetch_tl tcg_gen_atomic_umin_fetch_i32
232
+#define tcg_gen_atomic_smax_fetch_tl tcg_gen_atomic_smax_fetch_i32
233
+#define tcg_gen_atomic_umax_fetch_tl tcg_gen_atomic_umax_fetch_i32
234
#define tcg_gen_dup_tl_vec tcg_gen_dup_i32_vec
235
#endif
236
237
diff --git a/tcg/tcg.h b/tcg/tcg.h
238
index XXXXXXX..XXXXXXX 100644
239
--- a/tcg/tcg.h
240
+++ b/tcg/tcg.h
241
@@ -XXX,XX +XXX,XX @@ GEN_ATOMIC_HELPER_ALL(fetch_sub)
242
GEN_ATOMIC_HELPER_ALL(fetch_and)
243
GEN_ATOMIC_HELPER_ALL(fetch_or)
244
GEN_ATOMIC_HELPER_ALL(fetch_xor)
245
+GEN_ATOMIC_HELPER_ALL(fetch_smin)
246
+GEN_ATOMIC_HELPER_ALL(fetch_umin)
247
+GEN_ATOMIC_HELPER_ALL(fetch_smax)
248
+GEN_ATOMIC_HELPER_ALL(fetch_umax)
249
250
GEN_ATOMIC_HELPER_ALL(add_fetch)
251
GEN_ATOMIC_HELPER_ALL(sub_fetch)
252
GEN_ATOMIC_HELPER_ALL(and_fetch)
253
GEN_ATOMIC_HELPER_ALL(or_fetch)
254
GEN_ATOMIC_HELPER_ALL(xor_fetch)
255
+GEN_ATOMIC_HELPER_ALL(smin_fetch)
256
+GEN_ATOMIC_HELPER_ALL(umin_fetch)
257
+GEN_ATOMIC_HELPER_ALL(smax_fetch)
258
+GEN_ATOMIC_HELPER_ALL(umax_fetch)
259
260
GEN_ATOMIC_HELPER_ALL(xchg)
261
262
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
263
index XXXXXXX..XXXXXXX 100644
264
--- a/tcg/tcg-op.c
265
+++ b/tcg/tcg-op.c
266
@@ -XXX,XX +XXX,XX @@ GEN_ATOMIC_HELPER(fetch_add, add, 0)
267
GEN_ATOMIC_HELPER(fetch_and, and, 0)
268
GEN_ATOMIC_HELPER(fetch_or, or, 0)
269
GEN_ATOMIC_HELPER(fetch_xor, xor, 0)
270
+GEN_ATOMIC_HELPER(fetch_smin, smin, 0)
271
+GEN_ATOMIC_HELPER(fetch_umin, umin, 0)
272
+GEN_ATOMIC_HELPER(fetch_smax, smax, 0)
273
+GEN_ATOMIC_HELPER(fetch_umax, umax, 0)
274
275
GEN_ATOMIC_HELPER(add_fetch, add, 1)
276
GEN_ATOMIC_HELPER(and_fetch, and, 1)
277
GEN_ATOMIC_HELPER(or_fetch, or, 1)
278
GEN_ATOMIC_HELPER(xor_fetch, xor, 1)
279
+GEN_ATOMIC_HELPER(smin_fetch, smin, 1)
280
+GEN_ATOMIC_HELPER(umin_fetch, umin, 1)
281
+GEN_ATOMIC_HELPER(smax_fetch, smax, 1)
282
+GEN_ATOMIC_HELPER(umax_fetch, umax, 1)
283
284
static void tcg_gen_mov2_i32(TCGv_i32 r, TCGv_i32 a, TCGv_i32 b)
285
{
286
--
33
--
287
2.17.0
34
2.20.1
288
35
289
36
diff view generated by jsdifflib
1
From: Igor Mammedov <imammedo@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Suggested-by: Eduardo Habkost <ehabkost@redhat.com>
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Message-id: 20190412165416.7977-12-philmd@redhat.com
6
Message-id: 1525691524-32265-5-git-send-email-imammedo@redhat.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
7
---
9
hw/arm/virt.c | 1 +
8
include/hw/net/lan9118.h | 2 ++
10
hw/i386/pc.c | 1 +
9
hw/arm/exynos4_boards.c | 3 ++-
11
hw/ppc/e500plat.c | 1 +
10
hw/arm/mps2-tz.c | 3 ++-
12
hw/ppc/spapr.c | 1 +
11
hw/net/lan9118.c | 1 -
13
hw/s390x/s390-virtio-ccw.c | 1 +
12
4 files changed, 6 insertions(+), 3 deletions(-)
14
5 files changed, 5 insertions(+)
15
13
16
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
14
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/virt.c
16
--- a/include/hw/net/lan9118.h
19
+++ b/hw/arm/virt.c
17
+++ b/include/hw/net/lan9118.h
20
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
18
@@ -XXX,XX +XXX,XX @@
21
mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
19
#include "hw/irq.h"
22
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
20
#include "net/net.h"
23
mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
21
24
+ assert(!mc->get_hotplug_handler);
22
+#define TYPE_LAN9118 "lan9118"
25
mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
23
+
26
hc->plug = virt_machine_device_plug_cb;
24
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
27
}
25
28
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
26
#endif
27
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
29
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/i386/pc.c
29
--- a/hw/arm/exynos4_boards.c
31
+++ b/hw/i386/pc.c
30
+++ b/hw/arm/exynos4_boards.c
32
@@ -XXX,XX +XXX,XX @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
31
@@ -XXX,XX +XXX,XX @@
33
pcmc->acpi_data_size = 0x20000 + 0x8000;
32
#include "hw/arm/arm.h"
34
pcmc->save_tsc_khz = true;
33
#include "exec/address-spaces.h"
35
pcmc->linuxboot_dma_enabled = true;
34
#include "hw/arm/exynos4210.h"
36
+ assert(!mc->get_hotplug_handler);
35
+#include "hw/net/lan9118.h"
37
mc->get_hotplug_handler = pc_get_hotpug_handler;
36
#include "hw/boards.h"
38
mc->cpu_index_to_instance_props = pc_cpu_index_to_props;
37
39
mc->get_default_cpu_node_id = pc_get_default_cpu_node_id;
38
#undef DEBUG
40
diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c
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
41
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/ppc/e500plat.c
50
--- a/hw/arm/mps2-tz.c
43
+++ b/hw/ppc/e500plat.c
51
+++ b/hw/arm/mps2-tz.c
44
@@ -XXX,XX +XXX,XX @@ static void e500plat_machine_class_init(ObjectClass *oc, void *data)
52
@@ -XXX,XX +XXX,XX @@
45
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
53
#include "hw/arm/armsse.h"
46
MachineClass *mc = MACHINE_CLASS(oc);
54
#include "hw/dma/pl080.h"
47
55
#include "hw/ssi/pl022.h"
48
+ assert(!mc->get_hotplug_handler);
56
+#include "hw/net/lan9118.h"
49
mc->get_hotplug_handler = e500plat_machine_get_hotpug_handler;
57
#include "net/net.h"
50
hc->plug = e500plat_machine_device_plug_cb;
58
#include "hw/core/split-irq.h"
51
59
52
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
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
53
index XXXXXXX..XXXXXXX 100644
70
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/ppc/spapr.c
71
--- a/hw/net/lan9118.c
55
+++ b/hw/ppc/spapr.c
72
+++ b/hw/net/lan9118.c
56
@@ -XXX,XX +XXX,XX @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
73
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_packet = {
57
mc->kvm_type = spapr_kvm_type;
74
}
58
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_SPAPR_PCI_HOST_BRIDGE);
75
};
59
mc->pci_allow_0_address = true;
76
60
+ assert(!mc->get_hotplug_handler);
77
-#define TYPE_LAN9118 "lan9118"
61
mc->get_hotplug_handler = spapr_get_hotplug_handler;
78
#define LAN9118(obj) OBJECT_CHECK(lan9118_state, (obj), TYPE_LAN9118)
62
hc->pre_plug = spapr_machine_device_pre_plug;
79
63
hc->plug = spapr_machine_device_plug;
80
typedef struct {
64
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/hw/s390x/s390-virtio-ccw.c
67
+++ b/hw/s390x/s390-virtio-ccw.c
68
@@ -XXX,XX +XXX,XX @@ static void ccw_machine_class_init(ObjectClass *oc, void *data)
69
mc->no_sdcard = 1;
70
mc->max_cpus = S390_MAX_CPUS;
71
mc->has_hotpluggable_cpus = true;
72
+ assert(!mc->get_hotplug_handler);
73
mc->get_hotplug_handler = s390_get_hotplug_handler;
74
mc->cpu_index_to_instance_props = s390_cpu_index_to_props;
75
mc->possible_cpu_arch_ids = s390_possible_cpu_arch_ids;
76
--
81
--
77
2.17.0
82
2.20.1
78
83
79
84
diff view generated by jsdifflib
1
From: Igor Mammedov <imammedo@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
By default MachineClass::get_hotplug_handler is NULL and concrete board
3
This commit finally deletes "hw/devices.h".
4
should set it to it's own handler.
5
Considering there isn't any default handler, drop saving empty
6
MachineClass::get_hotplug_handler in child class and make PC code
7
consistent with spapr/s390x boards.
8
4
9
We can bring this back when actual usecase surfaces and do it
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
10
consistently across boards that use get_hotplug_handler().
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
7
Message-id: 20190412165416.7977-13-philmd@redhat.com
12
Suggested-by: David Gibson <david@gibson.dropbear.id.au>
13
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Reviewed-by: Eduardo Habkost <ehabkost@redhat.com>
16
Message-id: 1525691524-32265-2-git-send-email-imammedo@redhat.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
9
---
19
include/hw/i386/pc.h | 8 --------
10
include/hw/devices.h | 11 -----------
20
hw/i386/pc.c | 6 +-----
11
include/hw/net/smc91c111.h | 19 +++++++++++++++++++
21
2 files changed, 1 insertion(+), 13 deletions(-)
12
hw/arm/gumstix.c | 2 +-
13
hw/arm/integratorcp.c | 2 +-
14
hw/arm/mainstone.c | 2 +-
15
hw/arm/realview.c | 2 +-
16
hw/arm/versatilepb.c | 2 +-
17
hw/net/smc91c111.c | 2 +-
18
8 files changed, 25 insertions(+), 17 deletions(-)
19
delete mode 100644 include/hw/devices.h
20
create mode 100644 include/hw/net/smc91c111.h
22
21
23
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
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
24
index XXXXXXX..XXXXXXX 100644
65
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/i386/pc.h
66
--- a/hw/arm/gumstix.c
26
+++ b/include/hw/i386/pc.h
67
+++ b/hw/arm/gumstix.c
27
@@ -XXX,XX +XXX,XX @@ struct PCMachineState {
68
@@ -XXX,XX +XXX,XX @@
28
/**
69
#include "hw/arm/pxa.h"
29
* PCMachineClass:
70
#include "net/net.h"
30
*
71
#include "hw/block/flash.h"
31
- * Methods:
72
-#include "hw/devices.h"
32
- *
73
+#include "hw/net/smc91c111.h"
33
- * @get_hotplug_handler: pointer to parent class callback @get_hotplug_handler
74
#include "hw/boards.h"
34
- *
75
#include "exec/address-spaces.h"
35
* Compat fields:
76
#include "sysemu/qtest.h"
36
*
77
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
37
* @enforce_aligned_dimm: check that DIMM's address/size is aligned by
38
@@ -XXX,XX +XXX,XX @@ struct PCMachineClass {
39
40
/*< public >*/
41
42
- /* Methods: */
43
- HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
44
- DeviceState *dev);
45
-
46
/* Device configuration: */
47
bool pci_enabled;
48
bool kvmclock_enabled;
49
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
50
index XXXXXXX..XXXXXXX 100644
78
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/i386/pc.c
79
--- a/hw/arm/integratorcp.c
52
+++ b/hw/i386/pc.c
80
+++ b/hw/arm/integratorcp.c
53
@@ -XXX,XX +XXX,XX @@ static void pc_machine_device_unplug_cb(HotplugHandler *hotplug_dev,
81
@@ -XXX,XX +XXX,XX @@
54
static HotplugHandler *pc_get_hotpug_handler(MachineState *machine,
82
#include "qemu-common.h"
55
DeviceState *dev)
83
#include "cpu.h"
56
{
84
#include "hw/sysbus.h"
57
- PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);
85
-#include "hw/devices.h"
58
-
86
#include "hw/boards.h"
59
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
87
#include "hw/arm/arm.h"
60
object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
88
#include "hw/misc/arm_integrator_debug.h"
61
return HOTPLUG_HANDLER(machine);
89
+#include "hw/net/smc91c111.h"
62
}
90
#include "net/net.h"
63
91
#include "exec/address-spaces.h"
64
- return pcmc->get_hotplug_handler ?
92
#include "sysemu/sysemu.h"
65
- pcmc->get_hotplug_handler(machine, dev) : NULL;
93
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
66
+ return NULL;
94
index XXXXXXX..XXXXXXX 100644
67
}
95
--- a/hw/arm/mainstone.c
68
96
+++ b/hw/arm/mainstone.c
69
static void
97
@@ -XXX,XX +XXX,XX @@
70
@@ -XXX,XX +XXX,XX @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
98
#include "hw/arm/pxa.h"
71
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
99
#include "hw/arm/arm.h"
72
NMIClass *nc = NMI_CLASS(oc);
100
#include "net/net.h"
73
101
-#include "hw/devices.h"
74
- pcmc->get_hotplug_handler = mc->get_hotplug_handler;
102
+#include "hw/net/smc91c111.h"
75
pcmc->pci_enabled = true;
103
#include "hw/boards.h"
76
pcmc->has_acpi_build = true;
104
#include "hw/block/flash.h"
77
pcmc->rsdp_in_ram = true;
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>
78
--
146
--
79
2.17.0
147
2.20.1
80
148
81
149
diff view generated by jsdifflib