1
target-arm queue. This has the "plumb txattrs through various
1
Latest arm queue, half minor code cleanups and half minor
2
bits of exec.c" patches, and a collection of bug fixes from
2
bug fixes.
3
various people.
4
3
5
thanks
6
-- PMM
4
-- PMM
7
5
6
The following changes since commit 5d0e5694470d2952b4f257bc985cac8c89b4fd92:
8
7
9
8
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2019-06-17 11:55:14 +0100)
10
The following changes since commit a3ac12fba028df90f7b3dbec924995c126c41022:
11
12
Merge remote-tracking branch 'remotes/ehabkost/tags/numa-next-pull-request' into staging (2018-05-31 11:12:36 +0100)
13
9
14
are available in the Git repository at:
10
are available in the Git repository at:
15
11
16
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180531
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190617
17
13
18
for you to fetch changes up to 49d1dca0520ea71bc21867fab6647f474fcf857b:
14
for you to fetch changes up to 1120827fa182f0e76226df7ffe7a86598d1df54f:
19
15
20
KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice (2018-05-31 14:52:53 +0100)
16
target/arm: Only implement doubles if the FPU supports them (2019-06-17 15:15:06 +0100)
21
17
22
----------------------------------------------------------------
18
----------------------------------------------------------------
23
target-arm queue:
19
target-arm queue:
24
* target/arm: Honour FPCR.FZ in FRECPX
20
* support large kernel images in bootloader (by avoiding
25
* MAINTAINERS: Add entries for newer MPS2 boards and devices
21
putting the initrd over the top of them)
26
* hw/intc/arm_gicv3: Fix APxR<n> register dispatching
22
* correctly disable FPU/DSP in the CPU for the mps2-an521, musca-a boards
27
* arm_gicv3_kvm: fix bug in writing zero bits back to the in-kernel
23
* arm_gicv3: Fix decoding of ID register range
28
GIC state
24
* arm_gicv3: GICD_TYPER.SecurityExtn is RAZ if GICD_CTLR.DS == 1
29
* tcg: Fix helper function vs host abi for float16
25
* some code cleanups following on from the VFP decodetree conversion
30
* arm: fix qemu crash on startup with -bios option
26
* Only implement doubles if the FPU supports them
31
* arm: fix malloc type mismatch
27
(so we now correctly model Cortex-M4, -M33 as single precision only)
32
* xlnx-zdma: Correct mem leaks and memset to zero on desc unaligned errors
33
* Correct CPACR reset value for v7 cores
34
* memory.h: Improve IOMMU related documentation
35
* exec: Plumb transaction attributes through various functions in
36
preparation for allowing IOMMUs to see them
37
* vmstate.h: Provide VMSTATE_BOOL_SUB_ARRAY
38
* ARM: ACPI: Fix use-after-free due to memory realloc
39
* KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice
40
28
41
----------------------------------------------------------------
29
----------------------------------------------------------------
42
Francisco Iglesias (1):
30
Peter Maydell (24):
43
xlnx-zdma: Correct mem leaks and memset to zero on desc unaligned errors
31
hw/arm/boot: Don't assume RAM starts at address zero
32
hw/arm/boot: Diagnose layouts that put initrd or DTB off the end of RAM
33
hw/arm/boot: Avoid placing the initrd on top of the kernel
34
hw/arm/boot: Honour image size field in AArch64 Image format kernels
35
target/arm: Allow VFP and Neon to be disabled via a CPU property
36
target/arm: Allow M-profile CPUs to disable the DSP extension via CPU property
37
hw/arm/armv7m: Forward "vfp" and "dsp" properties to CPU
38
hw/arm: Correctly disable FPU/DSP for some ARMSSE-based boards
39
hw/intc/arm_gicv3: Fix decoding of ID register range
40
hw/intc/arm_gicv3: GICD_TYPER.SecurityExtn is RAZ if GICD_CTLR.DS == 1
41
target/arm: Move vfp_expand_imm() to translate.[ch]
42
target/arm: Use vfp_expand_imm() for AArch32 VFP VMOV_imm
43
target/arm: Stop using cpu_F0s for NEON_2RM_VABS_F
44
target/arm: Stop using cpu_F0s for NEON_2RM_VNEG_F
45
target/arm: Stop using cpu_F0s for NEON_2RM_VRINT*
46
target/arm: Stop using cpu_F0s for NEON_2RM_VCVT[ANPM][US]
47
target/arm: Stop using cpu_F0s for NEON_2RM_VRECPE_F and NEON_2RM_VRSQRTE_F
48
target/arm: Stop using cpu_F0s for Neon f32/s32 VCVT
49
target/arm: Stop using cpu_F0s in Neon VCVT fixed-point ops
50
target/arm: stop using deprecated functions in NEON_2RM_VCVT_F16_F32
51
target/arm: Stop using deprecated functions in NEON_2RM_VCVT_F32_F16
52
target/arm: Remove unused cpu_F0s, cpu_F0d, cpu_F1s, cpu_F1d
53
target/arm: Fix typos in trans function prototypes
54
target/arm: Only implement doubles if the FPU supports them
44
55
45
Igor Mammedov (1):
56
include/hw/arm/armsse.h | 7 ++
46
arm: fix qemu crash on startup with -bios option
57
include/hw/arm/armv7m.h | 4 +
58
target/arm/cpu.h | 12 +++
59
target/arm/translate-a64.h | 1 -
60
target/arm/translate.h | 7 ++
61
hw/arm/armsse.c | 58 +++++++---
62
hw/arm/armv7m.c | 18 ++++
63
hw/arm/boot.c | 83 ++++++++++----
64
hw/arm/musca.c | 8 ++
65
hw/intc/arm_gicv3_dist.c | 12 ++-
66
hw/intc/arm_gicv3_redist.c | 4 +-
67
target/arm/cpu.c | 179 ++++++++++++++++++++++++++++--
68
target/arm/translate-a64.c | 32 ------
69
target/arm/translate-vfp.inc.c | 173 ++++++++++++++++++++++-------
70
target/arm/translate.c | 240 ++++++++++++++---------------------------
71
target/arm/vfp.decode | 10 +-
72
16 files changed, 572 insertions(+), 276 deletions(-)
47
73
48
Jan Kiszka (1):
49
hw/intc/arm_gicv3: Fix APxR<n> register dispatching
50
51
Paolo Bonzini (1):
52
arm: fix malloc type mismatch
53
54
Peter Maydell (17):
55
target/arm: Honour FPCR.FZ in FRECPX
56
MAINTAINERS: Add entries for newer MPS2 boards and devices
57
Correct CPACR reset value for v7 cores
58
memory.h: Improve IOMMU related documentation
59
Make tb_invalidate_phys_addr() take a MemTxAttrs argument
60
Make address_space_translate{, _cached}() take a MemTxAttrs argument
61
Make address_space_map() take a MemTxAttrs argument
62
Make address_space_access_valid() take a MemTxAttrs argument
63
Make flatview_extend_translation() take a MemTxAttrs argument
64
Make memory_region_access_valid() take a MemTxAttrs argument
65
Make MemoryRegion valid.accepts callback take a MemTxAttrs argument
66
Make flatview_access_valid() take a MemTxAttrs argument
67
Make flatview_translate() take a MemTxAttrs argument
68
Make address_space_get_iotlb_entry() take a MemTxAttrs argument
69
Make flatview_do_translate() take a MemTxAttrs argument
70
Make address_space_translate_iommu take a MemTxAttrs argument
71
vmstate.h: Provide VMSTATE_BOOL_SUB_ARRAY
72
73
Richard Henderson (1):
74
tcg: Fix helper function vs host abi for float16
75
76
Shannon Zhao (3):
77
arm_gicv3_kvm: increase clroffset accordingly
78
ARM: ACPI: Fix use-after-free due to memory realloc
79
KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice
80
81
include/exec/exec-all.h | 5 +-
82
include/exec/helper-head.h | 2 +-
83
include/exec/memory-internal.h | 3 +-
84
include/exec/memory.h | 128 +++++++++++++++++++++++++++++++++++------
85
include/migration/vmstate.h | 3 +
86
include/sysemu/dma.h | 6 +-
87
accel/tcg/translate-all.c | 4 +-
88
exec.c | 95 ++++++++++++++++++------------
89
hw/arm/boot.c | 18 +++---
90
hw/arm/virt-acpi-build.c | 20 +++++--
91
hw/dma/xlnx-zdma.c | 10 +++-
92
hw/hppa/dino.c | 3 +-
93
hw/intc/arm_gic_kvm.c | 1 -
94
hw/intc/arm_gicv3_cpuif.c | 12 ++--
95
hw/intc/arm_gicv3_kvm.c | 2 +-
96
hw/nvram/fw_cfg.c | 12 ++--
97
hw/s390x/s390-pci-inst.c | 3 +-
98
hw/scsi/esp.c | 3 +-
99
hw/vfio/common.c | 3 +-
100
hw/virtio/vhost.c | 3 +-
101
hw/xen/xen_pt_msi.c | 3 +-
102
memory.c | 12 ++--
103
memory_ldst.inc.c | 18 +++---
104
target/arm/gdbstub.c | 3 +-
105
target/arm/helper-a64.c | 41 +++++++------
106
target/arm/helper.c | 90 ++++++++++++++++-------------
107
target/ppc/mmu-hash64.c | 3 +-
108
target/riscv/helper.c | 2 +-
109
target/s390x/diag.c | 6 +-
110
target/s390x/excp_helper.c | 3 +-
111
target/s390x/mmu_helper.c | 3 +-
112
target/s390x/sigp.c | 3 +-
113
target/xtensa/op_helper.c | 3 +-
114
MAINTAINERS | 9 ++-
115
34 files changed, 353 insertions(+), 182 deletions(-)
116
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
In the Arm kernel/initrd loading code, in some places we make the
2
add MemTxAttrs as an argument to flatview_do_translate().
2
incorrect assumption that info->ram_size can be treated as the
3
address of the end of RAM, as for instance when we calculate the
4
available space for the initrd using "info->ram_size - info->initrd_start".
5
This is wrong, because many Arm boards (including "virt") specify
6
a non-zero info->loader_start to indicate that their RAM area
7
starts at a non-zero physical address.
8
9
Correct the places which make this incorrect assumption.
3
10
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Tested-by: Mark Rutland <mark.rutland@arm.com>
7
Message-id: 20180521140402.23318-13-peter.maydell@linaro.org
14
Message-id: 20190516144733.32399-2-peter.maydell@linaro.org
8
---
15
---
9
exec.c | 9 ++++++---
16
hw/arm/boot.c | 9 ++++-----
10
1 file changed, 6 insertions(+), 3 deletions(-)
17
1 file changed, 4 insertions(+), 5 deletions(-)
11
18
12
diff --git a/exec.c b/exec.c
19
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
13
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
14
--- a/exec.c
21
--- a/hw/arm/boot.c
15
+++ b/exec.c
22
+++ b/hw/arm/boot.c
16
@@ -XXX,XX +XXX,XX @@ unassigned:
23
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
17
* @is_write: whether the translation operation is for write
24
int elf_machine;
18
* @is_mmio: whether this can be MMIO, set true if it can
25
hwaddr entry;
19
* @target_as: the address space targeted by the IOMMU
26
static const ARMInsnFixup *primary_loader;
20
+ * @attrs: memory transaction attributes
27
+ uint64_t ram_end = info->loader_start + info->ram_size;
21
*
28
22
* This function is called from RCU critical section
29
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
23
*/
30
primary_loader = bootloader_aarch64;
24
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
31
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
25
hwaddr *page_mask_out,
32
/* 32-bit ARM */
26
bool is_write,
33
entry = info->loader_start + KERNEL_LOAD_ADDR;
27
bool is_mmio,
34
kernel_size = load_image_targphys_as(info->kernel_filename, entry,
28
- AddressSpace **target_as)
35
- info->ram_size - KERNEL_LOAD_ADDR,
29
+ AddressSpace **target_as,
36
- as);
30
+ MemTxAttrs attrs)
37
+ ram_end - KERNEL_LOAD_ADDR, as);
31
{
38
is_linux = 1;
32
MemoryRegionSection *section;
39
}
33
IOMMUMemoryRegion *iommu_mr;
40
if (kernel_size < 0) {
34
@@ -XXX,XX +XXX,XX @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
41
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
35
* but page mask.
42
if (info->initrd_filename) {
36
*/
43
initrd_size = load_ramdisk_as(info->initrd_filename,
37
section = flatview_do_translate(address_space_to_flatview(as), addr, &xlat,
44
info->initrd_start,
38
- NULL, &page_mask, is_write, false, &as);
45
- info->ram_size - info->initrd_start,
39
+ NULL, &page_mask, is_write, false, &as,
46
- as);
40
+ attrs);
47
+ ram_end - info->initrd_start, as);
41
48
if (initrd_size < 0) {
42
/* Illegal translation */
49
initrd_size = load_image_targphys_as(info->initrd_filename,
43
if (section.mr == &io_mem_unassigned) {
50
info->initrd_start,
44
@@ -XXX,XX +XXX,XX @@ MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat,
51
- info->ram_size -
45
52
+ ram_end -
46
/* This can be MMIO, so setup MMIO bit. */
53
info->initrd_start,
47
section = flatview_do_translate(fv, addr, xlat, plen, NULL,
54
as);
48
- is_write, true, &as);
55
}
49
+ is_write, true, &as, attrs);
50
mr = section.mr;
51
52
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
53
--
56
--
54
2.17.1
57
2.20.1
55
58
56
59
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
We calculate the locations in memory where we want to put the
2
add MemTxAttrs as an argument to address_space_get_iotlb_entry().
2
initrd and the DTB based on the size of the kernel, since they
3
come after it. Add some explicit checks that these aren't off the
4
end of RAM entirely.
5
6
(At the moment the way we calculate the initrd_start means that
7
it can't ever be off the end of RAM, but that will change with
8
the next commit.)
3
9
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Tested-by: Mark Rutland <mark.rutland@arm.com>
7
Message-id: 20180521140402.23318-12-peter.maydell@linaro.org
13
Message-id: 20190516144733.32399-3-peter.maydell@linaro.org
8
---
14
---
9
include/exec/memory.h | 2 +-
15
hw/arm/boot.c | 23 +++++++++++++++++++++++
10
exec.c | 2 +-
16
1 file changed, 23 insertions(+)
11
hw/virtio/vhost.c | 3 ++-
12
3 files changed, 4 insertions(+), 3 deletions(-)
13
17
14
diff --git a/include/exec/memory.h b/include/exec/memory.h
18
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/memory.h
20
--- a/hw/arm/boot.c
17
+++ b/include/exec/memory.h
21
+++ b/hw/arm/boot.c
18
@@ -XXX,XX +XXX,XX @@ void address_space_cache_destroy(MemoryRegionCache *cache);
22
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
19
* entry. Should be called from an RCU critical section.
23
error_report("could not load kernel '%s'", info->kernel_filename);
20
*/
24
exit(1);
21
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
25
}
22
- bool is_write);
26
+
23
+ bool is_write, MemTxAttrs attrs);
27
+ if (kernel_size > info->ram_size) {
24
28
+ error_report("kernel '%s' is too large to fit in RAM "
25
/* address_space_translate: translate an address range into an address space
29
+ "(kernel size %d, RAM size %" PRId64 ")",
26
* into a MemoryRegion and an address range into that section. Should be
30
+ info->kernel_filename, kernel_size, info->ram_size);
27
diff --git a/exec.c b/exec.c
31
+ exit(1);
28
index XXXXXXX..XXXXXXX 100644
32
+ }
29
--- a/exec.c
33
+
30
+++ b/exec.c
34
info->entry = entry;
31
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
35
if (is_linux) {
32
36
uint32_t fixupcontext[FIXUP_MAX];
33
/* Called from RCU critical section */
37
34
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
38
if (info->initrd_filename) {
35
- bool is_write)
39
+
36
+ bool is_write, MemTxAttrs attrs)
40
+ if (info->initrd_start >= ram_end) {
37
{
41
+ error_report("not enough space after kernel to load initrd");
38
MemoryRegionSection section;
42
+ exit(1);
39
hwaddr xlat, page_mask;
43
+ }
40
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
44
+
41
index XXXXXXX..XXXXXXX 100644
45
initrd_size = load_ramdisk_as(info->initrd_filename,
42
--- a/hw/virtio/vhost.c
46
info->initrd_start,
43
+++ b/hw/virtio/vhost.c
47
ram_end - info->initrd_start, as);
44
@@ -XXX,XX +XXX,XX @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write)
48
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
45
trace_vhost_iotlb_miss(dev, 1);
49
info->initrd_filename);
46
50
exit(1);
47
iotlb = address_space_get_iotlb_entry(dev->vdev->dma_as,
51
}
48
- iova, write);
52
+ if (info->initrd_start + initrd_size > info->ram_size) {
49
+ iova, write,
53
+ error_report("could not load initrd '%s': "
50
+ MEMTXATTRS_UNSPECIFIED);
54
+ "too big to fit into RAM after the kernel",
51
if (iotlb.target_as != NULL) {
55
+ info->initrd_filename);
52
ret = vhost_memory_region_lookup(dev, iotlb.translated_addr,
56
+ }
53
&uaddr, &len);
57
} else {
58
initrd_size = 0;
59
}
60
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
61
/* Place the DTB after the initrd in memory with alignment. */
62
info->dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size,
63
align);
64
+ if (info->dtb_start >= ram_end) {
65
+ error_report("Not enough space for DTB after kernel/initrd");
66
+ exit(1);
67
+ }
68
fixupcontext[FIXUP_ARGPTR_LO] = info->dtb_start;
69
fixupcontext[FIXUP_ARGPTR_HI] = info->dtb_start >> 32;
70
} else {
54
--
71
--
55
2.17.1
72
2.20.1
56
73
57
74
diff view generated by jsdifflib
1
Provide a VMSTATE_BOOL_SUB_ARRAY to go with VMSTATE_UINT8_SUB_ARRAY
1
We currently put the initrd at the smaller of:
2
and friends.
2
* 128MB into RAM
3
* halfway into the RAM
4
(with the dtb following it).
5
6
However for large kernels this might mean that the kernel
7
overlaps the initrd. For some kinds of kernel (self-decompressing
8
32-bit kernels, and ELF images with a BSS section at the end)
9
we don't know the exact size, but even there we have a
10
minimum size. Put the initrd at least further into RAM than
11
that. For image formats that can give us an exact kernel size, this
12
will mean that we definitely avoid overlaying kernel and initrd.
3
13
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Message-id: 20180521140402.23318-23-peter.maydell@linaro.org
16
Tested-by: Mark Rutland <mark.rutland@arm.com>
17
Message-id: 20190516144733.32399-4-peter.maydell@linaro.org
7
---
18
---
8
include/migration/vmstate.h | 3 +++
19
hw/arm/boot.c | 34 ++++++++++++++++++++--------------
9
1 file changed, 3 insertions(+)
20
1 file changed, 20 insertions(+), 14 deletions(-)
10
21
11
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
22
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
12
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
13
--- a/include/migration/vmstate.h
24
--- a/hw/arm/boot.c
14
+++ b/include/migration/vmstate.h
25
+++ b/hw/arm/boot.c
15
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
26
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
16
#define VMSTATE_BOOL_ARRAY(_f, _s, _n) \
27
if (info->nb_cpus == 0)
17
VMSTATE_BOOL_ARRAY_V(_f, _s, _n, 0)
28
info->nb_cpus = 1;
18
29
19
+#define VMSTATE_BOOL_SUB_ARRAY(_f, _s, _start, _num) \
30
- /*
20
+ VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_bool, bool)
31
- * We want to put the initrd far enough into RAM that when the
32
- * kernel is uncompressed it will not clobber the initrd. However
33
- * on boards without much RAM we must ensure that we still leave
34
- * enough room for a decent sized initrd, and on boards with large
35
- * amounts of RAM we must avoid the initrd being so far up in RAM
36
- * that it is outside lowmem and inaccessible to the kernel.
37
- * So for boards with less than 256MB of RAM we put the initrd
38
- * halfway into RAM, and for boards with 256MB of RAM or more we put
39
- * the initrd at 128MB.
40
- */
41
- info->initrd_start = info->loader_start +
42
- MIN(info->ram_size / 2, 128 * 1024 * 1024);
43
-
44
/* Assume that raw images are linux kernels, and ELF images are not. */
45
kernel_size = arm_load_elf(info, &elf_entry, &elf_low_addr,
46
&elf_high_addr, elf_machine, as);
47
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
48
}
49
50
info->entry = entry;
21
+
51
+
22
#define VMSTATE_UINT16_ARRAY_V(_f, _s, _n, _v) \
52
+ /*
23
VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint16, uint16_t)
53
+ * We want to put the initrd far enough into RAM that when the
54
+ * kernel is uncompressed it will not clobber the initrd. However
55
+ * on boards without much RAM we must ensure that we still leave
56
+ * enough room for a decent sized initrd, and on boards with large
57
+ * amounts of RAM we must avoid the initrd being so far up in RAM
58
+ * that it is outside lowmem and inaccessible to the kernel.
59
+ * So for boards with less than 256MB of RAM we put the initrd
60
+ * halfway into RAM, and for boards with 256MB of RAM or more we put
61
+ * the initrd at 128MB.
62
+ * We also refuse to put the initrd somewhere that will definitely
63
+ * overlay the kernel we just loaded, though for kernel formats which
64
+ * don't tell us their exact size (eg self-decompressing 32-bit kernels)
65
+ * we might still make a bad choice here.
66
+ */
67
+ info->initrd_start = info->loader_start +
68
+ MAX(MIN(info->ram_size / 2, 128 * 1024 * 1024), kernel_size);
69
+ info->initrd_start = TARGET_PAGE_ALIGN(info->initrd_start);
70
+
71
if (is_linux) {
72
uint32_t fixupcontext[FIXUP_MAX];
24
73
25
--
74
--
26
2.17.1
75
2.20.1
27
76
28
77
diff view generated by jsdifflib
1
From: Igor Mammedov <imammedo@redhat.com>
1
Since Linux v3.17, the kernel's Image header includes a field image_size,
2
which gives the total size of the kernel including unpopulated data
3
sections such as the BSS). If this is present, then return it from
4
load_aarch64_image() as the true size of the kernel rather than
5
just using the size of the Image file itself. This allows the code
6
which calculates where to put the initrd to avoid putting it in
7
the kernel's BSS area.
2
8
3
When QEMU is started with following CLI
9
This means that we should be able to reliably load kernel images
4
-machine virt,gic-version=3,accel=kvm -cpu host -bios AAVMF_CODE.fd
10
which are larger than 128MB without accidentally putting the
5
it crashes with abort at
11
initrd or dtb in locations that clash with the kernel itself.
6
accel/kvm/kvm-all.c:2164:
7
KVM_SET_DEVICE_ATTR failed: Group 6 attr 0x000000000000c665: Invalid argument
8
12
9
Which is caused by implicit dependency of kvm_arm_gicv3_reset() on
13
Fixes: https://bugs.launchpad.net/qemu/+bug/1823998
10
arm_gicv3_icc_reset() where the later is called by CPU reset
11
reset callback.
12
13
However commit:
14
3b77f6c arm/boot: split load_dtb() from arm_load_kernel()
15
broke CPU reset callback registration in case
16
17
arm_load_kernel()
18
...
19
if (!info->kernel_filename || info->firmware_loaded)
20
21
branch is taken, i.e. it's sufficient to provide a firmware
22
or do not provide kernel on CLI to skip cpu reset callback
23
registration, where before offending commit the callback
24
has been registered unconditionally.
25
26
Fix it by registering the callback right at the beginning of
27
arm_load_kernel() unconditionally instead of doing it at the end.
28
29
NOTE:
30
we probably should eliminate that dependency anyways as well as
31
separate arch CPU reset parts from arm_load_kernel() into CPU
32
itself, but that refactoring that I probably would have to do
33
anyways later for CPU hotplug to work.
34
35
Reported-by: Auger Eric <eric.auger@redhat.com>
36
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
37
Reviewed-by: Eric Auger <eric.auger@redhat.com>
38
Tested-by: Eric Auger <eric.auger@redhat.com>
39
Message-id: 1527070950-208350-1-git-send-email-imammedo@redhat.com
40
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
41
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
17
Tested-by: Mark Rutland <mark.rutland@arm.com>
18
Message-id: 20190516144733.32399-5-peter.maydell@linaro.org
42
---
19
---
43
hw/arm/boot.c | 18 +++++++++---------
20
hw/arm/boot.c | 17 +++++++++++++++--
44
1 file changed, 9 insertions(+), 9 deletions(-)
21
1 file changed, 15 insertions(+), 2 deletions(-)
45
22
46
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
23
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
47
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/boot.c
25
--- a/hw/arm/boot.c
49
+++ b/hw/arm/boot.c
26
+++ b/hw/arm/boot.c
50
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
27
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
51
static const ARMInsnFixup *primary_loader;
28
hwaddr *entry, AddressSpace *as)
52
AddressSpace *as = arm_boot_address_space(cpu, info);
29
{
53
30
hwaddr kernel_load_offset = KERNEL64_LOAD_ADDR;
54
+ /* CPU objects (unlike devices) are not automatically reset on system
31
+ uint64_t kernel_size = 0;
55
+ * reset, so we must always register a handler to do so. If we're
32
uint8_t *buffer;
56
+ * actually loading a kernel, the handler is also responsible for
33
int size;
57
+ * arranging that we start it correctly.
34
35
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
36
* is only valid if the image_size is non-zero.
37
*/
38
memcpy(&hdrvals, buffer + ARM64_TEXT_OFFSET_OFFSET, sizeof(hdrvals));
39
- if (hdrvals[1] != 0) {
40
+
41
+ kernel_size = le64_to_cpu(hdrvals[1]);
42
+
43
+ if (kernel_size != 0) {
44
kernel_load_offset = le64_to_cpu(hdrvals[0]);
45
46
/*
47
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
48
}
49
}
50
51
+ /*
52
+ * Kernels before v3.17 don't populate the image_size field, and
53
+ * raw images have no header. For those our best guess at the size
54
+ * is the size of the Image file itself.
58
+ */
55
+ */
59
+ for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
56
+ if (kernel_size == 0) {
60
+ qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
57
+ kernel_size = size;
61
+ }
58
+ }
62
+
59
+
63
/* The board code is not supposed to set secure_board_setup unless
60
*entry = mem_base + kernel_load_offset;
64
* running its code in secure mode is actually possible, and KVM
61
rom_add_blob_fixed_as(filename, buffer, size, *entry, as);
65
* doesn't support secure.
62
66
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
63
g_free(buffer);
67
ARM_CPU(cs)->env.boot_info = info;
64
68
}
65
- return size;
69
66
+ return kernel_size;
70
- /* CPU objects (unlike devices) are not automatically reset on system
67
}
71
- * reset, so we must always register a handler to do so. If we're
68
72
- * actually loading a kernel, the handler is also responsible for
69
static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
73
- * arranging that we start it correctly.
74
- */
75
- for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
76
- qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
77
- }
78
-
79
if (!info->skip_dtb_autoload && have_dtb(info)) {
80
if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as) < 0) {
81
exit(1);
82
--
70
--
83
2.17.1
71
2.20.1
84
72
85
73
diff view generated by jsdifflib
1
From: Shannon Zhao <zhaoshenglong@huawei.com>
1
Allow VFP and neon to be disabled via a CPU property. As with
2
2
the "pmu" property, we only allow these features to be removed
3
kvm_irqchip_create called by kvm_init will call kvm_init_irq_routing to
3
from CPUs which have it by default, not added to CPUs which
4
initialize global capability variables. If we call kvm_init_irq_routing in
4
don't have it.
5
GIC realize function, previous allocated memory will leak.
5
6
6
The primary motivation here is to be able to optionally
7
Fix this by deleting the unnecessary call.
7
create Cortex-M33 CPUs with no FPU, but we provide switches
8
8
for both VFP and Neon because the two interact:
9
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
9
* AArch64 can't have one without the other
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
* Some ID register fields only change if both are disabled
11
Message-id: 1527750994-14360-1-git-send-email-zhaoshenglong@huawei.com
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Message-id: 20190517174046.11146-2-peter.maydell@linaro.org
13
---
16
---
14
hw/intc/arm_gic_kvm.c | 1 -
17
target/arm/cpu.h | 4 ++
15
hw/intc/arm_gicv3_kvm.c | 1 -
18
target/arm/cpu.c | 150 +++++++++++++++++++++++++++++++++++++++++++++--
16
2 files changed, 2 deletions(-)
19
2 files changed, 148 insertions(+), 6 deletions(-)
17
20
18
diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/arm_gic_kvm.c
23
--- a/target/arm/cpu.h
21
+++ b/hw/intc/arm_gic_kvm.c
24
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
25
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
23
26
bool has_el3;
24
if (kvm_has_gsi_routing()) {
27
/* CPU has PMU (Performance Monitor Unit) */
25
/* set up irq routing */
28
bool has_pmu;
26
- kvm_init_irq_routing(kvm_state);
29
+ /* CPU has VFP */
27
for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
30
+ bool has_vfp;
28
kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
31
+ /* CPU has Neon */
29
}
32
+ bool has_neon;
30
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
33
34
/* CPU has memory protection unit */
35
bool has_mpu;
36
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
31
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/intc/arm_gicv3_kvm.c
38
--- a/target/arm/cpu.c
33
+++ b/hw/intc/arm_gicv3_kvm.c
39
+++ b/target/arm/cpu.c
34
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
40
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_cfgend_property =
35
41
static Property arm_cpu_has_pmu_property =
36
if (kvm_has_gsi_routing()) {
42
DEFINE_PROP_BOOL("pmu", ARMCPU, has_pmu, true);
37
/* set up irq routing */
43
38
- kvm_init_irq_routing(kvm_state);
44
+static Property arm_cpu_has_vfp_property =
39
for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
45
+ DEFINE_PROP_BOOL("vfp", ARMCPU, has_vfp, true);
40
kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
46
+
41
}
47
+static Property arm_cpu_has_neon_property =
48
+ DEFINE_PROP_BOOL("neon", ARMCPU, has_neon, true);
49
+
50
static Property arm_cpu_has_mpu_property =
51
DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true);
52
53
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
54
if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
55
set_feature(&cpu->env, ARM_FEATURE_PMSA);
56
}
57
+ /* Similarly for the VFP feature bits */
58
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP4)) {
59
+ set_feature(&cpu->env, ARM_FEATURE_VFP3);
60
+ }
61
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP3)) {
62
+ set_feature(&cpu->env, ARM_FEATURE_VFP);
63
+ }
64
65
if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) ||
66
arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) {
67
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
68
&error_abort);
69
}
70
71
+ /*
72
+ * Allow user to turn off VFP and Neon support, but only for TCG --
73
+ * KVM does not currently allow us to lie to the guest about its
74
+ * ID/feature registers, so the guest always sees what the host has.
75
+ */
76
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
77
+ cpu->has_vfp = true;
78
+ if (!kvm_enabled()) {
79
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_has_vfp_property,
80
+ &error_abort);
81
+ }
82
+ }
83
+
84
+ if (arm_feature(&cpu->env, ARM_FEATURE_NEON)) {
85
+ cpu->has_neon = true;
86
+ if (!kvm_enabled()) {
87
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_has_neon_property,
88
+ &error_abort);
89
+ }
90
+ }
91
+
92
if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) {
93
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property,
94
&error_abort);
95
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
96
return;
97
}
98
99
+ if (arm_feature(env, ARM_FEATURE_AARCH64) &&
100
+ cpu->has_vfp != cpu->has_neon) {
101
+ /*
102
+ * This is an architectural requirement for AArch64; AArch32 is
103
+ * more flexible and permits VFP-no-Neon and Neon-no-VFP.
104
+ */
105
+ error_setg(errp,
106
+ "AArch64 CPUs must have both VFP and Neon or neither");
107
+ return;
108
+ }
109
+
110
+ if (!cpu->has_vfp) {
111
+ uint64_t t;
112
+ uint32_t u;
113
+
114
+ unset_feature(env, ARM_FEATURE_VFP);
115
+ unset_feature(env, ARM_FEATURE_VFP3);
116
+ unset_feature(env, ARM_FEATURE_VFP4);
117
+
118
+ t = cpu->isar.id_aa64isar1;
119
+ t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 0);
120
+ cpu->isar.id_aa64isar1 = t;
121
+
122
+ t = cpu->isar.id_aa64pfr0;
123
+ t = FIELD_DP64(t, ID_AA64PFR0, FP, 0xf);
124
+ cpu->isar.id_aa64pfr0 = t;
125
+
126
+ u = cpu->isar.id_isar6;
127
+ u = FIELD_DP32(u, ID_ISAR6, JSCVT, 0);
128
+ cpu->isar.id_isar6 = u;
129
+
130
+ u = cpu->isar.mvfr0;
131
+ u = FIELD_DP32(u, MVFR0, FPSP, 0);
132
+ u = FIELD_DP32(u, MVFR0, FPDP, 0);
133
+ u = FIELD_DP32(u, MVFR0, FPTRAP, 0);
134
+ u = FIELD_DP32(u, MVFR0, FPDIVIDE, 0);
135
+ u = FIELD_DP32(u, MVFR0, FPSQRT, 0);
136
+ u = FIELD_DP32(u, MVFR0, FPSHVEC, 0);
137
+ u = FIELD_DP32(u, MVFR0, FPROUND, 0);
138
+ cpu->isar.mvfr0 = u;
139
+
140
+ u = cpu->isar.mvfr1;
141
+ u = FIELD_DP32(u, MVFR1, FPFTZ, 0);
142
+ u = FIELD_DP32(u, MVFR1, FPDNAN, 0);
143
+ u = FIELD_DP32(u, MVFR1, FPHP, 0);
144
+ cpu->isar.mvfr1 = u;
145
+
146
+ u = cpu->isar.mvfr2;
147
+ u = FIELD_DP32(u, MVFR2, FPMISC, 0);
148
+ cpu->isar.mvfr2 = u;
149
+ }
150
+
151
+ if (!cpu->has_neon) {
152
+ uint64_t t;
153
+ uint32_t u;
154
+
155
+ unset_feature(env, ARM_FEATURE_NEON);
156
+
157
+ t = cpu->isar.id_aa64isar0;
158
+ t = FIELD_DP64(t, ID_AA64ISAR0, DP, 0);
159
+ cpu->isar.id_aa64isar0 = t;
160
+
161
+ t = cpu->isar.id_aa64isar1;
162
+ t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 0);
163
+ cpu->isar.id_aa64isar1 = t;
164
+
165
+ t = cpu->isar.id_aa64pfr0;
166
+ t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 0xf);
167
+ cpu->isar.id_aa64pfr0 = t;
168
+
169
+ u = cpu->isar.id_isar5;
170
+ u = FIELD_DP32(u, ID_ISAR5, RDM, 0);
171
+ u = FIELD_DP32(u, ID_ISAR5, VCMA, 0);
172
+ cpu->isar.id_isar5 = u;
173
+
174
+ u = cpu->isar.id_isar6;
175
+ u = FIELD_DP32(u, ID_ISAR6, DP, 0);
176
+ u = FIELD_DP32(u, ID_ISAR6, FHM, 0);
177
+ cpu->isar.id_isar6 = u;
178
+
179
+ u = cpu->isar.mvfr1;
180
+ u = FIELD_DP32(u, MVFR1, SIMDLS, 0);
181
+ u = FIELD_DP32(u, MVFR1, SIMDINT, 0);
182
+ u = FIELD_DP32(u, MVFR1, SIMDSP, 0);
183
+ u = FIELD_DP32(u, MVFR1, SIMDHP, 0);
184
+ u = FIELD_DP32(u, MVFR1, SIMDFMAC, 0);
185
+ cpu->isar.mvfr1 = u;
186
+
187
+ u = cpu->isar.mvfr2;
188
+ u = FIELD_DP32(u, MVFR2, SIMDMISC, 0);
189
+ cpu->isar.mvfr2 = u;
190
+ }
191
+
192
+ if (!cpu->has_neon && !cpu->has_vfp) {
193
+ uint64_t t;
194
+ uint32_t u;
195
+
196
+ t = cpu->isar.id_aa64isar0;
197
+ t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 0);
198
+ cpu->isar.id_aa64isar0 = t;
199
+
200
+ t = cpu->isar.id_aa64isar1;
201
+ t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 0);
202
+ cpu->isar.id_aa64isar1 = t;
203
+
204
+ u = cpu->isar.mvfr0;
205
+ u = FIELD_DP32(u, MVFR0, SIMDREG, 0);
206
+ cpu->isar.mvfr0 = u;
207
+ }
208
+
209
/* Some features automatically imply others: */
210
if (arm_feature(env, ARM_FEATURE_V8)) {
211
if (arm_feature(env, ARM_FEATURE_M)) {
212
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
213
if (arm_feature(env, ARM_FEATURE_V5)) {
214
set_feature(env, ARM_FEATURE_V4T);
215
}
216
- if (arm_feature(env, ARM_FEATURE_VFP4)) {
217
- set_feature(env, ARM_FEATURE_VFP3);
218
- }
219
- if (arm_feature(env, ARM_FEATURE_VFP3)) {
220
- set_feature(env, ARM_FEATURE_VFP);
221
- }
222
if (arm_feature(env, ARM_FEATURE_LPAE)) {
223
set_feature(env, ARM_FEATURE_V7MP);
224
set_feature(env, ARM_FEATURE_PXN);
42
--
225
--
43
2.17.1
226
2.20.1
44
227
45
228
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
Allow the DSP extension to be disabled via a CPU property for
2
add MemTxAttrs as an argument to flatview_translate(); all its
2
M-profile CPUs. (A and R-profile CPUs don't have this extension
3
callers now have attrs available.
3
as a defined separate optional architecture extension, so
4
they don't need the property.)
4
5
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190517174046.11146-3-peter.maydell@linaro.org
8
Message-id: 20180521140402.23318-11-peter.maydell@linaro.org
9
---
10
---
10
include/exec/memory.h | 7 ++++---
11
target/arm/cpu.h | 2 ++
11
exec.c | 17 +++++++++--------
12
target/arm/cpu.c | 29 +++++++++++++++++++++++++++++
12
2 files changed, 13 insertions(+), 11 deletions(-)
13
2 files changed, 31 insertions(+)
13
14
14
diff --git a/include/exec/memory.h b/include/exec/memory.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/memory.h
17
--- a/target/arm/cpu.h
17
+++ b/include/exec/memory.h
18
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
19
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
19
*/
20
bool has_vfp;
20
MemoryRegion *flatview_translate(FlatView *fv,
21
/* CPU has Neon */
21
hwaddr addr, hwaddr *xlat,
22
bool has_neon;
22
- hwaddr *len, bool is_write);
23
+ /* CPU has M-profile DSP extension */
23
+ hwaddr *len, bool is_write,
24
+ bool has_dsp;
24
+ MemTxAttrs attrs);
25
25
26
/* CPU has memory protection unit */
26
static inline MemoryRegion *address_space_translate(AddressSpace *as,
27
bool has_mpu;
27
hwaddr addr, hwaddr *xlat,
28
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
28
@@ -XXX,XX +XXX,XX @@ static inline MemoryRegion *address_space_translate(AddressSpace *as,
29
MemTxAttrs attrs)
30
{
31
return flatview_translate(address_space_to_flatview(as),
32
- addr, xlat, len, is_write);
33
+ addr, xlat, len, is_write, attrs);
34
}
35
36
/* address_space_access_valid: check for validity of accessing an address
37
@@ -XXX,XX +XXX,XX @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
38
rcu_read_lock();
39
fv = address_space_to_flatview(as);
40
l = len;
41
- mr = flatview_translate(fv, addr, &addr1, &l, false);
42
+ mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
43
if (len == l && memory_access_is_direct(mr, false)) {
44
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
45
memcpy(buf, ptr, len);
46
diff --git a/exec.c b/exec.c
47
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
48
--- a/exec.c
30
--- a/target/arm/cpu.c
49
+++ b/exec.c
31
+++ b/target/arm/cpu.c
50
@@ -XXX,XX +XXX,XX @@ iotlb_fail:
32
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_has_vfp_property =
51
33
static Property arm_cpu_has_neon_property =
52
/* Called from RCU critical section */
34
DEFINE_PROP_BOOL("neon", ARMCPU, has_neon, true);
53
MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat,
35
54
- hwaddr *plen, bool is_write)
36
+static Property arm_cpu_has_dsp_property =
55
+ hwaddr *plen, bool is_write,
37
+ DEFINE_PROP_BOOL("dsp", ARMCPU, has_dsp, true);
56
+ MemTxAttrs attrs)
38
+
57
{
39
static Property arm_cpu_has_mpu_property =
58
MemoryRegion *mr;
40
DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true);
59
MemoryRegionSection section;
41
60
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
42
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
61
}
43
}
62
63
l = len;
64
- mr = flatview_translate(fv, addr, &addr1, &l, true);
65
+ mr = flatview_translate(fv, addr, &addr1, &l, true, attrs);
66
}
44
}
67
45
68
return result;
46
+ if (arm_feature(&cpu->env, ARM_FEATURE_M) &&
69
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
47
+ arm_feature(&cpu->env, ARM_FEATURE_THUMB_DSP)) {
70
MemTxResult result = MEMTX_OK;
48
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_has_dsp_property,
71
49
+ &error_abort);
72
l = len;
50
+ }
73
- mr = flatview_translate(fv, addr, &addr1, &l, true);
51
+
74
+ mr = flatview_translate(fv, addr, &addr1, &l, true, attrs);
52
if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) {
75
result = flatview_write_continue(fv, addr, attrs, buf, len,
53
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property,
76
addr1, l, mr);
54
&error_abort);
77
55
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
78
@@ -XXX,XX +XXX,XX @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
56
cpu->isar.mvfr0 = u;
79
}
80
81
l = len;
82
- mr = flatview_translate(fv, addr, &addr1, &l, false);
83
+ mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
84
}
57
}
85
58
86
return result;
59
+ if (arm_feature(env, ARM_FEATURE_M) && !cpu->has_dsp) {
87
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
60
+ uint32_t u;
88
MemoryRegion *mr;
61
+
89
62
+ unset_feature(env, ARM_FEATURE_THUMB_DSP);
90
l = len;
63
+
91
- mr = flatview_translate(fv, addr, &addr1, &l, false);
64
+ u = cpu->isar.id_isar1;
92
+ mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
65
+ u = FIELD_DP32(u, ID_ISAR1, EXTEND, 1);
93
return flatview_read_continue(fv, addr, attrs, buf, len,
66
+ cpu->isar.id_isar1 = u;
94
addr1, l, mr);
67
+
95
}
68
+ u = cpu->isar.id_isar2;
96
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
69
+ u = FIELD_DP32(u, ID_ISAR2, MULTU, 1);
97
70
+ u = FIELD_DP32(u, ID_ISAR2, MULTS, 1);
98
while (len > 0) {
71
+ cpu->isar.id_isar2 = u;
99
l = len;
72
+
100
- mr = flatview_translate(fv, addr, &xlat, &l, is_write);
73
+ u = cpu->isar.id_isar3;
101
+ mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
74
+ u = FIELD_DP32(u, ID_ISAR3, SIMD, 1);
102
if (!memory_access_is_direct(mr, is_write)) {
75
+ u = FIELD_DP32(u, ID_ISAR3, SATURATE, 0);
103
l = memory_access_size(mr, l, addr);
76
+ cpu->isar.id_isar3 = u;
104
if (!memory_region_access_valid(mr, xlat, l, is_write, attrs)) {
77
+ }
105
@@ -XXX,XX +XXX,XX @@ flatview_extend_translation(FlatView *fv, hwaddr addr,
78
+
106
79
/* Some features automatically imply others: */
107
len = target_len;
80
if (arm_feature(env, ARM_FEATURE_V8)) {
108
this_mr = flatview_translate(fv, addr, &xlat,
81
if (arm_feature(env, ARM_FEATURE_M)) {
109
- &len, is_write);
110
+ &len, is_write, attrs);
111
if (this_mr != mr || xlat != base + done) {
112
return done;
113
}
114
@@ -XXX,XX +XXX,XX @@ void *address_space_map(AddressSpace *as,
115
l = len;
116
rcu_read_lock();
117
fv = address_space_to_flatview(as);
118
- mr = flatview_translate(fv, addr, &xlat, &l, is_write);
119
+ mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
120
121
if (!memory_access_is_direct(mr, is_write)) {
122
if (atomic_xchg(&bounce.in_use, true)) {
123
--
82
--
124
2.17.1
83
2.20.1
125
84
126
85
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
Create "vfp" and "dsp" properties on the armv7m container object
2
which will be forwarded to its CPU object, so that SoCs can
3
configure whether the CPU has these features.
2
4
3
Coverity found that the string return by 'object_get_canonical_path' was not
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
being freed at two locations in the model (CID 1391294 and CID 1391293) and
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
also that a memset was being called with a value greater than the max of a byte
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
on the second argument (CID 1391286). This patch corrects this by adding the
8
Message-id: 20190517174046.11146-4-peter.maydell@linaro.org
7
freeing of the strings and also changing to memset to zero instead on
9
---
8
descriptor unaligned errors.
10
include/hw/arm/armv7m.h | 4 ++++
11
hw/arm/armv7m.c | 18 ++++++++++++++++++
12
2 files changed, 22 insertions(+)
9
13
10
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
14
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20180528184859.3530-1-frasse.iglesias@gmail.com
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/dma/xlnx-zdma.c | 10 +++++++---
18
1 file changed, 7 insertions(+), 3 deletions(-)
19
20
diff --git a/hw/dma/xlnx-zdma.c b/hw/dma/xlnx-zdma.c
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/dma/xlnx-zdma.c
16
--- a/include/hw/arm/armv7m.h
23
+++ b/hw/dma/xlnx-zdma.c
17
+++ b/include/hw/arm/armv7m.h
24
@@ -XXX,XX +XXX,XX @@ static bool zdma_load_descriptor(XlnxZDMA *s, uint64_t addr, void *buf)
18
@@ -XXX,XX +XXX,XX @@ typedef struct {
25
qemu_log_mask(LOG_GUEST_ERROR,
19
* devices will be automatically layered on top of this view.)
26
"zdma: unaligned descriptor at %" PRIx64,
20
* + Property "idau": IDAU interface (forwarded to CPU object)
27
addr);
21
* + Property "init-svtor": secure VTOR reset value (forwarded to CPU object)
28
- memset(buf, 0xdeadbeef, sizeof(XlnxZDMADescr));
22
+ * + Property "vfp": enable VFP (forwarded to CPU object)
29
+ memset(buf, 0x0, sizeof(XlnxZDMADescr));
23
+ * + Property "dsp": enable DSP (forwarded to CPU object)
30
s->error = true;
24
* + Property "enable-bitband": expose bitbanded IO
31
return false;
25
*/
26
typedef struct ARMv7MState {
27
@@ -XXX,XX +XXX,XX @@ typedef struct ARMv7MState {
28
uint32_t init_svtor;
29
bool enable_bitband;
30
bool start_powered_off;
31
+ bool vfp;
32
+ bool dsp;
33
} ARMv7MState;
34
35
#endif
36
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/armv7m.c
39
+++ b/hw/arm/armv7m.c
40
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
41
return;
42
}
32
}
43
}
33
@@ -XXX,XX +XXX,XX @@ static uint64_t zdma_read(void *opaque, hwaddr addr, unsigned size)
44
+ if (object_property_find(OBJECT(s->cpu), "vfp", NULL)) {
34
RegisterInfo *r = &s->regs_info[addr / 4];
45
+ object_property_set_bool(OBJECT(s->cpu), s->vfp,
35
46
+ "vfp", &err);
36
if (!r->data) {
47
+ if (err != NULL) {
37
+ gchar *path = object_get_canonical_path(OBJECT(s));
48
+ error_propagate(errp, err);
38
qemu_log("%s: Decode error: read from %" HWADDR_PRIx "\n",
49
+ return;
39
- object_get_canonical_path(OBJECT(s)),
50
+ }
40
+ path,
51
+ }
41
addr);
52
+ if (object_property_find(OBJECT(s->cpu), "dsp", NULL)) {
42
+ g_free(path);
53
+ object_property_set_bool(OBJECT(s->cpu), s->dsp,
43
ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, INV_APB, true);
54
+ "dsp", &err);
44
zdma_ch_imr_update_irq(s);
55
+ if (err != NULL) {
45
return 0;
56
+ error_propagate(errp, err);
46
@@ -XXX,XX +XXX,XX @@ static void zdma_write(void *opaque, hwaddr addr, uint64_t value,
57
+ return;
47
RegisterInfo *r = &s->regs_info[addr / 4];
58
+ }
48
59
+ }
49
if (!r->data) {
60
50
+ gchar *path = object_get_canonical_path(OBJECT(s));
61
/*
51
qemu_log("%s: Decode error: write to %" HWADDR_PRIx "=%" PRIx64 "\n",
62
* Tell the CPU where the NVIC is; it will fail realize if it doesn't
52
- object_get_canonical_path(OBJECT(s)),
63
@@ -XXX,XX +XXX,XX @@ static Property armv7m_properties[] = {
53
+ path,
64
DEFINE_PROP_BOOL("enable-bitband", ARMv7MState, enable_bitband, false),
54
addr, value);
65
DEFINE_PROP_BOOL("start-powered-off", ARMv7MState, start_powered_off,
55
+ g_free(path);
66
false),
56
ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, INV_APB, true);
67
+ DEFINE_PROP_BOOL("vfp", ARMv7MState, vfp, true),
57
zdma_ch_imr_update_irq(s);
68
+ DEFINE_PROP_BOOL("dsp", ARMv7MState, dsp, true),
58
return;
69
DEFINE_PROP_END_OF_LIST(),
70
};
71
59
--
72
--
60
2.17.1
73
2.20.1
61
74
62
75
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
The SSE-200 hardware has configurable integration settings which
2
add MemTxAttrs as an argument to memory_region_access_valid().
2
determine whether its two CPUs have the FPU and DSP:
3
Its callers either have an attrs value to hand, or don't care
3
* CPU0_FPU (default 0)
4
and can use MEMTXATTRS_UNSPECIFIED.
4
* CPU0_DSP (default 0)
5
* CPU1_FPU (default 1)
6
* CPU1_DSP (default 1)
5
7
6
The callsite in flatview_access_valid() is part of a recursive
8
Similarly, the IoTKit has settings for its single CPU:
7
loop flatview_access_valid() -> memory_region_access_valid() ->
9
* CPU0_FPU (default 1)
8
subpage_accepts() -> flatview_access_valid(); we make it pass
10
* CPU0_DSP (default 1)
9
MEMTXATTRS_UNSPECIFIED for now, until the next several commits
11
10
have plumbed an attrs parameter through the rest of the loop
12
Of our four boards that use either the IoTKit or the SSE-200:
11
and we can add an attrs parameter to flatview_access_valid().
13
* mps2-an505, mps2-an521 and musca-a use the default settings
14
* musca-b1 enables FPU and DSP on both CPUs
15
16
Currently QEMU models all these boards using CPUs with
17
both FPU and DSP enabled. This means that we are incorrect
18
for mps2-an521 and musca-a, which should not have FPU or DSP
19
on CPU0.
20
21
Create QOM properties on the ARMSSE devices corresponding to the
22
default h/w integration settings, and make the Musca-B1 board
23
enable FPU and DSP on both CPUs. This fixes the mps2-an521
24
and musca-a behaviour, and leaves the musca-b1 and mps2-an505
25
behaviour unchanged.
12
26
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
28
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Message-id: 20190517174046.11146-5-peter.maydell@linaro.org
16
Message-id: 20180521140402.23318-8-peter.maydell@linaro.org
17
---
30
---
18
include/exec/memory-internal.h | 3 ++-
31
include/hw/arm/armsse.h | 7 +++++
19
exec.c | 4 +++-
32
hw/arm/armsse.c | 58 ++++++++++++++++++++++++++++++++---------
20
hw/s390x/s390-pci-inst.c | 3 ++-
33
hw/arm/musca.c | 8 ++++++
21
memory.c | 7 ++++---
34
3 files changed, 61 insertions(+), 12 deletions(-)
22
4 files changed, 11 insertions(+), 6 deletions(-)
23
35
24
diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
36
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
25
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
26
--- a/include/exec/memory-internal.h
38
--- a/include/hw/arm/armsse.h
27
+++ b/include/exec/memory-internal.h
39
+++ b/include/hw/arm/armsse.h
28
@@ -XXX,XX +XXX,XX @@ void flatview_unref(FlatView *view);
40
@@ -XXX,XX +XXX,XX @@
29
extern const MemoryRegionOps unassigned_mem_ops;
41
* address of each SRAM bank (and thus the total amount of internal SRAM)
30
42
* + QOM property "init-svtor" sets the initial value of the CPU SVTOR register
31
bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
43
* (where it expects to load the PC and SP from the vector table on reset)
32
- unsigned size, bool is_write);
44
+ * + QOM properties "CPU0_FPU", "CPU0_DSP", "CPU1_FPU" and "CPU1_DSP" which
33
+ unsigned size, bool is_write,
45
+ * set whether the CPUs have the FPU and DSP features present. The default
34
+ MemTxAttrs attrs);
46
+ * (matching the hardware) is that for CPU0 in an IoTKit and CPU1 in an
35
47
+ * SSE-200 both are present; CPU0 in an SSE-200 has neither.
36
void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection *section);
48
+ * Since the IoTKit has only one CPU, it does not have the CPU1_* properties.
37
AddressSpaceDispatch *address_space_dispatch_new(FlatView *fv);
49
* + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts for CPU 0,
38
diff --git a/exec.c b/exec.c
50
* which are wired to its NVIC lines 32 .. n+32
51
* + Named GPIO inputs "EXP_CPU1_IRQ" 0..n are the expansion interrupts for
52
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
53
uint32_t mainclk_frq;
54
uint32_t sram_addr_width;
55
uint32_t init_svtor;
56
+ bool cpu_fpu[SSE_MAX_CPUS];
57
+ bool cpu_dsp[SSE_MAX_CPUS];
58
} ARMSSE;
59
60
typedef struct ARMSSEInfo ARMSSEInfo;
61
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
39
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
40
--- a/exec.c
63
--- a/hw/arm/armsse.c
41
+++ b/exec.c
64
+++ b/hw/arm/armsse.c
42
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
65
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
43
mr = flatview_translate(fv, addr, &xlat, &l, is_write);
66
bool has_cachectrl;
44
if (!memory_access_is_direct(mr, is_write)) {
67
bool has_cpusecctrl;
45
l = memory_access_size(mr, l, addr);
68
bool has_cpuid;
46
- if (!memory_region_access_valid(mr, xlat, l, is_write)) {
69
+ Property *props;
47
+ /* When our callers all have attrs we'll pass them through here */
70
+};
48
+ if (!memory_region_access_valid(mr, xlat, l, is_write,
71
+
49
+ MEMTXATTRS_UNSPECIFIED)) {
72
+static Property iotkit_properties[] = {
50
return false;
73
+ DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
74
+ MemoryRegion *),
75
+ DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
76
+ DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
77
+ DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
78
+ DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
79
+ DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
80
+ DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
81
+ DEFINE_PROP_END_OF_LIST()
82
+};
83
+
84
+static Property armsse_properties[] = {
85
+ DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
86
+ MemoryRegion *),
87
+ DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
88
+ DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
89
+ DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
90
+ DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
91
+ DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
92
+ DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], false),
93
+ DEFINE_PROP_BOOL("CPU1_FPU", ARMSSE, cpu_fpu[1], true),
94
+ DEFINE_PROP_BOOL("CPU1_DSP", ARMSSE, cpu_dsp[1], true),
95
+ DEFINE_PROP_END_OF_LIST()
96
};
97
98
static const ARMSSEInfo armsse_variants[] = {
99
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
100
.has_cachectrl = false,
101
.has_cpusecctrl = false,
102
.has_cpuid = false,
103
+ .props = iotkit_properties,
104
},
105
{
106
.name = TYPE_SSE200,
107
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
108
.has_cachectrl = true,
109
.has_cpusecctrl = true,
110
.has_cpuid = true,
111
+ .props = armsse_properties,
112
},
113
};
114
115
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
116
return;
51
}
117
}
52
}
118
}
53
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
119
+ if (!s->cpu_fpu[i]) {
120
+ object_property_set_bool(cpuobj, false, "vfp", &err);
121
+ if (err) {
122
+ error_propagate(errp, err);
123
+ return;
124
+ }
125
+ }
126
+ if (!s->cpu_dsp[i]) {
127
+ object_property_set_bool(cpuobj, false, "dsp", &err);
128
+ if (err) {
129
+ error_propagate(errp, err);
130
+ return;
131
+ }
132
+ }
133
134
if (i > 0) {
135
memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
136
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription armsse_vmstate = {
137
}
138
};
139
140
-static Property armsse_properties[] = {
141
- DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
142
- MemoryRegion *),
143
- DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
144
- DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
145
- DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
146
- DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
147
- DEFINE_PROP_END_OF_LIST()
148
-};
149
-
150
static void armsse_reset(DeviceState *dev)
151
{
152
ARMSSE *s = ARMSSE(dev);
153
@@ -XXX,XX +XXX,XX @@ static void armsse_class_init(ObjectClass *klass, void *data)
154
DeviceClass *dc = DEVICE_CLASS(klass);
155
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
156
ARMSSEClass *asc = ARMSSE_CLASS(klass);
157
+ const ARMSSEInfo *info = data;
158
159
dc->realize = armsse_realize;
160
dc->vmsd = &armsse_vmstate;
161
- dc->props = armsse_properties;
162
+ dc->props = info->props;
163
dc->reset = armsse_reset;
164
iic->check = armsse_idau_check;
165
- asc->info = data;
166
+ asc->info = info;
167
}
168
169
static const TypeInfo armsse_info = {
170
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
54
index XXXXXXX..XXXXXXX 100644
171
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/s390x/s390-pci-inst.c
172
--- a/hw/arm/musca.c
56
+++ b/hw/s390x/s390-pci-inst.c
173
+++ b/hw/arm/musca.c
57
@@ -XXX,XX +XXX,XX @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
174
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
58
mr = s390_get_subregion(mr, offset, len);
175
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
59
offset -= mr->addr;
176
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
60
177
qdev_prop_set_uint32(ssedev, "MAINCLK", SYSCLK_FRQ);
61
- if (!memory_region_access_valid(mr, offset, len, true)) {
178
+ /*
62
+ if (!memory_region_access_valid(mr, offset, len, true,
179
+ * Musca-A takes the default SSE-200 FPU/DSP settings (ie no for
63
+ MEMTXATTRS_UNSPECIFIED)) {
180
+ * CPU0 and yes for CPU1); Musca-B1 explicitly enables them for CPU0.
64
s390_program_interrupt(env, PGM_OPERAND, 6, ra);
181
+ */
65
return 0;
182
+ if (mmc->type == MUSCA_B1) {
66
}
183
+ qdev_prop_set_bit(ssedev, "CPU0_FPU", true);
67
diff --git a/memory.c b/memory.c
184
+ qdev_prop_set_bit(ssedev, "CPU0_DSP", true);
68
index XXXXXXX..XXXXXXX 100644
185
+ }
69
--- a/memory.c
186
object_property_set_bool(OBJECT(&mms->sse), true, "realized",
70
+++ b/memory.c
187
&error_fatal);
71
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps ram_device_mem_ops = {
188
72
bool memory_region_access_valid(MemoryRegion *mr,
73
hwaddr addr,
74
unsigned size,
75
- bool is_write)
76
+ bool is_write,
77
+ MemTxAttrs attrs)
78
{
79
int access_size_min, access_size_max;
80
int access_size, i;
81
@@ -XXX,XX +XXX,XX @@ MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
82
{
83
MemTxResult r;
84
85
- if (!memory_region_access_valid(mr, addr, size, false)) {
86
+ if (!memory_region_access_valid(mr, addr, size, false, attrs)) {
87
*pval = unassigned_mem_read(mr, addr, size);
88
return MEMTX_DECODE_ERROR;
89
}
90
@@ -XXX,XX +XXX,XX @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
91
unsigned size,
92
MemTxAttrs attrs)
93
{
94
- if (!memory_region_access_valid(mr, addr, size, true)) {
95
+ if (!memory_region_access_valid(mr, addr, size, true, attrs)) {
96
unassigned_mem_write(mr, addr, data, size);
97
return MEMTX_DECODE_ERROR;
98
}
99
--
189
--
100
2.17.1
190
2.20.1
101
191
102
192
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
The GIC ID registers cover an area 0x30 bytes in size
2
(12 registers, 4 bytes each). We were incorrectly decoding
3
only the first 0x20 bytes.
2
4
3
cpregs_keys is an uint32_t* so the allocation should use uint32_t.
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
g_new is even better because it is type-safe.
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 20190524124248.28394-2-peter.maydell@linaro.org
8
---
9
hw/intc/arm_gicv3_dist.c | 4 ++--
10
hw/intc/arm_gicv3_redist.c | 4 ++--
11
2 files changed, 4 insertions(+), 4 deletions(-)
5
12
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
13
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/gdbstub.c | 3 +--
12
1 file changed, 1 insertion(+), 2 deletions(-)
13
14
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/gdbstub.c
15
--- a/hw/intc/arm_gicv3_dist.c
17
+++ b/target/arm/gdbstub.c
16
+++ b/hw/intc/arm_gicv3_dist.c
18
@@ -XXX,XX +XXX,XX @@ int arm_gen_dynamic_xml(CPUState *cs)
17
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicd_readl(GICv3State *s, hwaddr offset,
19
RegisterSysregXmlParam param = {cs, s};
18
}
20
19
return MEMTX_OK;
21
cpu->dyn_xml.num_cpregs = 0;
20
}
22
- cpu->dyn_xml.cpregs_keys = g_malloc(sizeof(uint32_t *) *
21
- case GICD_IDREGS ... GICD_IDREGS + 0x1f:
23
- g_hash_table_size(cpu->cp_regs));
22
+ case GICD_IDREGS ... GICD_IDREGS + 0x2f:
24
+ cpu->dyn_xml.cpregs_keys = g_new(uint32_t, g_hash_table_size(cpu->cp_regs));
23
/* ID registers */
25
g_string_printf(s, "<?xml version=\"1.0\"?>");
24
*data = gicv3_idreg(offset - GICD_IDREGS);
26
g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
25
return MEMTX_OK;
27
g_string_append_printf(s, "<feature name=\"org.qemu.gdb.arm.sys.regs\">");
26
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicd_writel(GICv3State *s, hwaddr offset,
27
gicd_write_irouter(s, attrs, irq, r);
28
return MEMTX_OK;
29
}
30
- case GICD_IDREGS ... GICD_IDREGS + 0x1f:
31
+ case GICD_IDREGS ... GICD_IDREGS + 0x2f:
32
case GICD_TYPER:
33
case GICD_IIDR:
34
/* RO registers, ignore the write */
35
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/intc/arm_gicv3_redist.c
38
+++ b/hw/intc/arm_gicv3_redist.c
39
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicr_readl(GICv3CPUState *cs, hwaddr offset,
40
}
41
*data = cs->gicr_nsacr;
42
return MEMTX_OK;
43
- case GICR_IDREGS ... GICR_IDREGS + 0x1f:
44
+ case GICR_IDREGS ... GICR_IDREGS + 0x2f:
45
*data = gicv3_idreg(offset - GICR_IDREGS);
46
return MEMTX_OK;
47
default:
48
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset,
49
return MEMTX_OK;
50
case GICR_IIDR:
51
case GICR_TYPER:
52
- case GICR_IDREGS ... GICR_IDREGS + 0x1f:
53
+ case GICR_IDREGS ... GICR_IDREGS + 0x2f:
54
/* RO registers, ignore the write */
55
qemu_log_mask(LOG_GUEST_ERROR,
56
"%s: invalid guest write to RO register at offset "
28
--
57
--
29
2.17.1
58
2.20.1
30
59
31
60
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
The GICv3 specification says that the GICD_TYPER.SecurityExtn bit
2
add MemTxAttrs as an argument to address_space_map().
2
is RAZ if GICD_CTLR.DS is 1. We were incorrectly making it RAZ
3
Its callers either have an attrs value to hand, or don't care
3
if the security extension is unsupported. "Security extension
4
and can use MEMTXATTRS_UNSPECIFIED.
4
unsupported" always implies GICD_CTLR.DS == 1, but the guest can
5
also set DS on a GIC which does support the security extension.
6
Fix the condition to correctly check the GICD_CTLR.DS bit.
5
7
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20190524124248.28394-3-peter.maydell@linaro.org
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-5-peter.maydell@linaro.org
10
---
10
---
11
include/exec/memory.h | 3 ++-
11
hw/intc/arm_gicv3_dist.c | 8 +++++++-
12
include/sysemu/dma.h | 3 ++-
12
1 file changed, 7 insertions(+), 1 deletion(-)
13
exec.c | 6 ++++--
14
target/ppc/mmu-hash64.c | 3 ++-
15
4 files changed, 10 insertions(+), 5 deletions(-)
16
13
17
diff --git a/include/exec/memory.h b/include/exec/memory.h
14
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/memory.h
16
--- a/hw/intc/arm_gicv3_dist.c
20
+++ b/include/exec/memory.h
17
+++ b/hw/intc/arm_gicv3_dist.c
21
@@ -XXX,XX +XXX,XX @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_
18
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicd_readl(GICv3State *s, hwaddr offset,
22
* @addr: address within that address space
19
* ITLinesNumber == (num external irqs / 32) - 1
23
* @plen: pointer to length of buffer; updated on return
20
*/
24
* @is_write: indicates the transfer direction
21
int itlinesnumber = ((s->num_irq - GIC_INTERNAL) / 32) - 1;
25
+ * @attrs: memory attributes
22
+ /*
26
*/
23
+ * SecurityExtn must be RAZ if GICD_CTLR.DS == 1, and
27
void *address_space_map(AddressSpace *as, hwaddr addr,
24
+ * "security extensions not supported" always implies DS == 1,
28
- hwaddr *plen, bool is_write);
25
+ * so we only need to check the DS bit.
29
+ hwaddr *plen, bool is_write, MemTxAttrs attrs);
26
+ */
30
27
+ bool sec_extn = !(s->gicd_ctlr & GICD_CTLR_DS);
31
/* address_space_unmap: Unmaps a memory region previously mapped by address_space_map()
28
32
*
29
- *data = (1 << 25) | (1 << 24) | (s->security_extn << 10) |
33
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
30
+ *data = (1 << 25) | (1 << 24) | (sec_extn << 10) |
34
index XXXXXXX..XXXXXXX 100644
31
(0xf << 19) | itlinesnumber;
35
--- a/include/sysemu/dma.h
32
return MEMTX_OK;
36
+++ b/include/sysemu/dma.h
37
@@ -XXX,XX +XXX,XX @@ static inline void *dma_memory_map(AddressSpace *as,
38
hwaddr xlen = *len;
39
void *p;
40
41
- p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE);
42
+ p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE,
43
+ MEMTXATTRS_UNSPECIFIED);
44
*len = xlen;
45
return p;
46
}
47
diff --git a/exec.c b/exec.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/exec.c
50
+++ b/exec.c
51
@@ -XXX,XX +XXX,XX @@ flatview_extend_translation(FlatView *fv, hwaddr addr,
52
void *address_space_map(AddressSpace *as,
53
hwaddr addr,
54
hwaddr *plen,
55
- bool is_write)
56
+ bool is_write,
57
+ MemTxAttrs attrs)
58
{
59
hwaddr len = *plen;
60
hwaddr l, xlat;
61
@@ -XXX,XX +XXX,XX @@ void *cpu_physical_memory_map(hwaddr addr,
62
hwaddr *plen,
63
int is_write)
64
{
65
- return address_space_map(&address_space_memory, addr, plen, is_write);
66
+ return address_space_map(&address_space_memory, addr, plen, is_write,
67
+ MEMTXATTRS_UNSPECIFIED);
68
}
69
70
void cpu_physical_memory_unmap(void *buffer, hwaddr len,
71
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/ppc/mmu-hash64.c
74
+++ b/target/ppc/mmu-hash64.c
75
@@ -XXX,XX +XXX,XX @@ const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCCPU *cpu,
76
return NULL;
77
}
78
79
- hptes = address_space_map(CPU(cpu)->as, base + pte_offset, &plen, false);
80
+ hptes = address_space_map(CPU(cpu)->as, base + pte_offset, &plen, false,
81
+ MEMTXATTRS_UNSPECIFIED);
82
if (plen < (n * HASH_PTE_SIZE_64)) {
83
hw_error("%s: Unable to map all requested HPTEs\n", __func__);
84
}
33
}
85
--
34
--
86
2.17.1
35
2.20.1
87
36
88
37
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
We want to use vfp_expand_imm() in the AArch32 VFP decode;
2
add MemTxAttrs as an argument to tb_invalidate_phys_addr().
2
move it from the a64-only header/source file to the
3
Its callers either have an attrs value to hand, or don't care
3
AArch32 one (which is always compiled even for AArch64).
4
and can use MEMTXATTRS_UNSPECIFIED.
5
4
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20180521140402.23318-3-peter.maydell@linaro.org
8
Message-id: 20190613163917.28589-2-peter.maydell@linaro.org
10
---
9
---
11
include/exec/exec-all.h | 5 +++--
10
target/arm/translate-a64.h | 1 -
12
accel/tcg/translate-all.c | 2 +-
11
target/arm/translate.h | 7 +++++++
13
exec.c | 2 +-
12
target/arm/translate-a64.c | 32 --------------------------------
14
target/xtensa/op_helper.c | 3 ++-
13
target/arm/translate-vfp.inc.c | 33 +++++++++++++++++++++++++++++++++
15
4 files changed, 7 insertions(+), 5 deletions(-)
14
4 files changed, 40 insertions(+), 33 deletions(-)
16
15
17
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
16
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/exec-all.h
18
--- a/target/arm/translate-a64.h
20
+++ b/include/exec/exec-all.h
19
+++ b/target/arm/translate-a64.h
21
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
20
@@ -XXX,XX +XXX,XX @@ void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v);
22
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
21
TCGv_ptr get_fpstatus_ptr(bool);
23
hwaddr paddr, int prot,
22
bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
24
int mmu_idx, target_ulong size);
23
unsigned int imms, unsigned int immr);
25
-void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr);
24
-uint64_t vfp_expand_imm(int size, uint8_t imm8);
26
+void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs);
25
bool sve_access_check(DisasContext *s);
27
void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
26
28
uintptr_t retaddr);
27
/* We should have at some point before trying to access an FP register
29
#else
28
diff --git a/target/arm/translate.h b/target/arm/translate.h
30
@@ -XXX,XX +XXX,XX @@ static inline void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu,
31
uint16_t idxmap)
32
{
33
}
34
-static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
35
+static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr,
36
+ MemTxAttrs attrs)
37
{
38
}
39
#endif
40
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
41
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
42
--- a/accel/tcg/translate-all.c
30
--- a/target/arm/translate.h
43
+++ b/accel/tcg/translate-all.c
31
+++ b/target/arm/translate.h
44
@@ -XXX,XX +XXX,XX @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
32
@@ -XXX,XX +XXX,XX @@ static inline void gen_ss_advance(DisasContext *s)
45
}
46
47
#if !defined(CONFIG_USER_ONLY)
48
-void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
49
+void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs)
50
{
51
ram_addr_t ram_addr;
52
MemoryRegion *mr;
53
diff --git a/exec.c b/exec.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/exec.c
56
+++ b/exec.c
57
@@ -XXX,XX +XXX,XX @@ static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
58
if (phys != -1) {
59
/* Locks grabbed by tb_invalidate_phys_addr */
60
tb_invalidate_phys_addr(cpu->cpu_ases[asidx].as,
61
- phys | (pc & ~TARGET_PAGE_MASK));
62
+ phys | (pc & ~TARGET_PAGE_MASK), attrs);
63
}
33
}
64
}
34
}
65
#endif
35
66
diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c
36
+/*
37
+ * Given a VFP floating point constant encoded into an 8 bit immediate in an
38
+ * instruction, expand it to the actual constant value of the specified
39
+ * size, as per the VFPExpandImm() pseudocode in the Arm ARM.
40
+ */
41
+uint64_t vfp_expand_imm(int size, uint8_t imm8);
42
+
43
/* Vector operations shared between ARM and AArch64. */
44
extern const GVecGen3 mla_op[4];
45
extern const GVecGen3 mls_op[4];
46
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
67
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
68
--- a/target/xtensa/op_helper.c
48
--- a/target/arm/translate-a64.c
69
+++ b/target/xtensa/op_helper.c
49
+++ b/target/arm/translate-a64.c
70
@@ -XXX,XX +XXX,XX @@ static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr)
50
@@ -XXX,XX +XXX,XX @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
71
int ret = xtensa_get_physical_addr(env, false, vaddr, 2, 0,
72
&paddr, &page_size, &access);
73
if (ret == 0) {
74
- tb_invalidate_phys_addr(&address_space_memory, paddr);
75
+ tb_invalidate_phys_addr(&address_space_memory, paddr,
76
+ MEMTXATTRS_UNSPECIFIED);
77
}
51
}
78
}
52
}
79
53
54
-/* The imm8 encodes the sign bit, enough bits to represent an exponent in
55
- * the range 01....1xx to 10....0xx, and the most significant 4 bits of
56
- * the mantissa; see VFPExpandImm() in the v8 ARM ARM.
57
- */
58
-uint64_t vfp_expand_imm(int size, uint8_t imm8)
59
-{
60
- uint64_t imm;
61
-
62
- switch (size) {
63
- case MO_64:
64
- imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
65
- (extract32(imm8, 6, 1) ? 0x3fc0 : 0x4000) |
66
- extract32(imm8, 0, 6);
67
- imm <<= 48;
68
- break;
69
- case MO_32:
70
- imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
71
- (extract32(imm8, 6, 1) ? 0x3e00 : 0x4000) |
72
- (extract32(imm8, 0, 6) << 3);
73
- imm <<= 16;
74
- break;
75
- case MO_16:
76
- imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
77
- (extract32(imm8, 6, 1) ? 0x3000 : 0x4000) |
78
- (extract32(imm8, 0, 6) << 6);
79
- break;
80
- default:
81
- g_assert_not_reached();
82
- }
83
- return imm;
84
-}
85
-
86
/* Floating point immediate
87
* 31 30 29 28 24 23 22 21 20 13 12 10 9 5 4 0
88
* +---+---+---+-----------+------+---+------------+-------+------+------+
89
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/translate-vfp.inc.c
92
+++ b/target/arm/translate-vfp.inc.c
93
@@ -XXX,XX +XXX,XX @@
94
#include "decode-vfp.inc.c"
95
#include "decode-vfp-uncond.inc.c"
96
97
+/*
98
+ * The imm8 encodes the sign bit, enough bits to represent an exponent in
99
+ * the range 01....1xx to 10....0xx, and the most significant 4 bits of
100
+ * the mantissa; see VFPExpandImm() in the v8 ARM ARM.
101
+ */
102
+uint64_t vfp_expand_imm(int size, uint8_t imm8)
103
+{
104
+ uint64_t imm;
105
+
106
+ switch (size) {
107
+ case MO_64:
108
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
109
+ (extract32(imm8, 6, 1) ? 0x3fc0 : 0x4000) |
110
+ extract32(imm8, 0, 6);
111
+ imm <<= 48;
112
+ break;
113
+ case MO_32:
114
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
115
+ (extract32(imm8, 6, 1) ? 0x3e00 : 0x4000) |
116
+ (extract32(imm8, 0, 6) << 3);
117
+ imm <<= 16;
118
+ break;
119
+ case MO_16:
120
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
121
+ (extract32(imm8, 6, 1) ? 0x3000 : 0x4000) |
122
+ (extract32(imm8, 0, 6) << 6);
123
+ break;
124
+ default:
125
+ g_assert_not_reached();
126
+ }
127
+ return imm;
128
+}
129
+
130
/*
131
* Return the offset of a 16-bit half of the specified VFP single-precision
132
* register. If top is true, returns the top 16 bits; otherwise the bottom
80
--
133
--
81
2.17.1
134
2.20.1
82
135
83
136
diff view generated by jsdifflib
1
From: Shannon Zhao <zhaoshenglong@huawei.com>
1
The AArch32 VMOV (immediate) instruction uses the same VFP encoded
2
immediate format we already handle in vfp_expand_imm(). Use that
3
function rather than hand-decoding it.
2
4
3
acpi_data_push uses g_array_set_size to resize the memory size. If there
5
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
4
is no enough contiguous memory, the address will be changed. So previous
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
pointer could not be used any more. It must update the pointer and use
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
the new one.
8
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190613163917.28589-3-peter.maydell@linaro.org
10
---
11
target/arm/translate-vfp.inc.c | 28 ++++------------------------
12
target/arm/vfp.decode | 10 ++++++----
13
2 files changed, 10 insertions(+), 28 deletions(-)
7
14
8
Also, previous codes wrongly use le32 conversion of iort->node_offset
15
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
9
for subsequent computations that will result incorrect value if host is
10
not litlle endian. So use the non-converted one instead.
11
12
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
13
Reviewed-by: Eric Auger <eric.auger@redhat.com>
14
Message-id: 1527663951-14552-1-git-send-email-zhaoshenglong@huawei.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/arm/virt-acpi-build.c | 20 +++++++++++++++-----
18
1 file changed, 15 insertions(+), 5 deletions(-)
19
20
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/virt-acpi-build.c
17
--- a/target/arm/translate-vfp.inc.c
23
+++ b/hw/arm/virt-acpi-build.c
18
+++ b/target/arm/translate-vfp.inc.c
24
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
19
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
25
AcpiIortItsGroup *its;
20
uint32_t delta_d = 0;
26
AcpiIortTable *iort;
21
int veclen = s->vec_len;
27
AcpiIortSmmu3 *smmu;
22
TCGv_i32 fd;
28
- size_t node_size, iort_length, smmu_offset = 0;
23
- uint32_t n, i, vd;
29
+ size_t node_size, iort_node_offset, iort_length, smmu_offset = 0;
24
+ uint32_t vd;
30
AcpiIortRC *rc;
25
31
26
vd = a->vd;
32
iort = acpi_data_push(table_data, sizeof(*iort));
27
33
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
34
29
}
35
iort_length = sizeof(*iort);
36
iort->node_count = cpu_to_le32(nb_nodes);
37
- iort->node_offset = cpu_to_le32(sizeof(*iort));
38
+ /*
39
+ * Use a copy in case table_data->data moves during acpi_data_push
40
+ * operations.
41
+ */
42
+ iort_node_offset = sizeof(*iort);
43
+ iort->node_offset = cpu_to_le32(iort_node_offset);
44
45
/* ITS group node */
46
node_size = sizeof(*its) + sizeof(uint32_t);
47
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
48
int irq = vms->irqmap[VIRT_SMMU];
49
50
/* SMMUv3 node */
51
- smmu_offset = iort->node_offset + node_size;
52
+ smmu_offset = iort_node_offset + node_size;
53
node_size = sizeof(*smmu) + sizeof(*idmap);
54
iort_length += node_size;
55
smmu = acpi_data_push(table_data, node_size);
56
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
57
idmap->id_count = cpu_to_le32(0xFFFF);
58
idmap->output_base = 0;
59
/* output IORT node is the ITS group node (the first node) */
60
- idmap->output_reference = cpu_to_le32(iort->node_offset);
61
+ idmap->output_reference = cpu_to_le32(iort_node_offset);
62
}
30
}
63
31
64
/* Root Complex Node */
32
- n = (a->imm4h << 28) & 0x80000000;
65
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
33
- i = ((a->imm4h << 4) & 0x70) | a->imm4l;
66
idmap->output_reference = cpu_to_le32(smmu_offset);
34
- if (i & 0x40) {
67
} else {
35
- i |= 0x780;
68
/* output IORT node is the ITS group node (the first node) */
36
- } else {
69
- idmap->output_reference = cpu_to_le32(iort->node_offset);
37
- i |= 0x800;
70
+ idmap->output_reference = cpu_to_le32(iort_node_offset);
38
- }
39
- n |= i << 19;
40
-
41
- fd = tcg_temp_new_i32();
42
- tcg_gen_movi_i32(fd, n);
43
+ fd = tcg_const_i32(vfp_expand_imm(MO_32, a->imm));
44
45
for (;;) {
46
neon_store_reg32(fd, vd);
47
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
48
uint32_t delta_d = 0;
49
int veclen = s->vec_len;
50
TCGv_i64 fd;
51
- uint32_t n, i, vd;
52
+ uint32_t vd;
53
54
vd = a->vd;
55
56
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
57
}
71
}
58
}
72
59
73
+ /*
60
- n = (a->imm4h << 28) & 0x80000000;
74
+ * Update the pointer address in case table_data->data moves during above
61
- i = ((a->imm4h << 4) & 0x70) | a->imm4l;
75
+ * acpi_data_push operations.
62
- if (i & 0x40) {
76
+ */
63
- i |= 0x3f80;
77
+ iort = (AcpiIortTable *)(table_data->data + iort_start);
64
- } else {
78
iort->length = cpu_to_le32(iort_length);
65
- i |= 0x4000;
79
66
- }
80
build_header(linker, table_data, (void *)(table_data->data + iort_start),
67
- n |= i << 16;
68
-
69
- fd = tcg_temp_new_i64();
70
- tcg_gen_movi_i64(fd, ((uint64_t)n) << 32);
71
+ fd = tcg_const_i64(vfp_expand_imm(MO_64, a->imm));
72
73
for (;;) {
74
neon_store_reg64(fd, vd);
75
diff --git a/target/arm/vfp.decode b/target/arm/vfp.decode
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/vfp.decode
78
+++ b/target/arm/vfp.decode
79
@@ -XXX,XX +XXX,XX @@
80
%vmov_idx_b 21:1 5:2
81
%vmov_idx_h 21:1 6:1
82
83
+%vmov_imm 16:4 0:4
84
+
85
# VMOV scalar to general-purpose register; note that this does
86
# include some Neon cases.
87
VMOV_to_gp ---- 1110 u:1 1. 1 .... rt:4 1011 ... 1 0000 \
88
@@ -XXX,XX +XXX,XX @@ VFM_sp ---- 1110 1.10 .... .... 1010 . o2:1 . 0 .... \
89
VFM_dp ---- 1110 1.10 .... .... 1011 . o2:1 . 0 .... \
90
vm=%vm_dp vn=%vn_dp vd=%vd_dp o1=2
91
92
-VMOV_imm_sp ---- 1110 1.11 imm4h:4 .... 1010 0000 imm4l:4 \
93
- vd=%vd_sp
94
-VMOV_imm_dp ---- 1110 1.11 imm4h:4 .... 1011 0000 imm4l:4 \
95
- vd=%vd_dp
96
+VMOV_imm_sp ---- 1110 1.11 .... .... 1010 0000 .... \
97
+ vd=%vd_sp imm=%vmov_imm
98
+VMOV_imm_dp ---- 1110 1.11 .... .... 1011 0000 .... \
99
+ vd=%vd_dp imm=%vmov_imm
100
101
VMOV_reg_sp ---- 1110 1.11 0000 .... 1010 01.0 .... \
102
vd=%vd_sp vm=%vm_sp
81
--
103
--
82
2.17.1
104
2.20.1
83
105
84
106
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
Where Neon instructions are floating point operations, we
2
add MemTxAttrs as an argument to flatview_extend_translation().
2
mostly use the old VFP utility functions like gen_vfp_abs()
3
Its callers either have an attrs value to hand, or don't care
3
which work on the TCG globals cpu_F0s and cpu_F1s. The
4
and can use MEMTXATTRS_UNSPECIFIED.
4
Neon for-each-element loop conditionally loads the inputs
5
into either a plain old TCG temporary for most operations
6
or into cpu_F0s for float operations, and similarly stores
7
back either cpu_F0s or the temporary.
8
9
Switch NEON_2RM_VABS_F away from using cpu_F0s, and
10
update neon_2rm_is_float_op() accordingly.
5
11
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-7-peter.maydell@linaro.org
14
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Message-id: 20190613163917.28589-4-peter.maydell@linaro.org
10
---
16
---
11
exec.c | 15 ++++++++++-----
17
target/arm/translate.c | 19 ++++++++-----------
12
1 file changed, 10 insertions(+), 5 deletions(-)
18
1 file changed, 8 insertions(+), 11 deletions(-)
13
19
14
diff --git a/exec.c b/exec.c
20
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/exec.c
22
--- a/target/arm/translate.c
17
+++ b/exec.c
23
+++ b/target/arm/translate.c
18
@@ -XXX,XX +XXX,XX @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr,
24
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
19
25
return statusptr;
20
static hwaddr
26
}
21
flatview_extend_translation(FlatView *fv, hwaddr addr,
27
22
- hwaddr target_len,
28
-static inline void gen_vfp_abs(int dp)
23
- MemoryRegion *mr, hwaddr base, hwaddr len,
29
-{
24
- bool is_write)
30
- if (dp)
25
+ hwaddr target_len,
31
- gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
26
+ MemoryRegion *mr, hwaddr base, hwaddr len,
32
- else
27
+ bool is_write, MemTxAttrs attrs)
33
- gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
34
-}
35
-
36
static inline void gen_vfp_neg(int dp)
28
{
37
{
29
hwaddr done = 0;
38
if (dp)
30
hwaddr xlat;
39
@@ -XXX,XX +XXX,XX @@ static const uint8_t neon_3r_sizes[] = {
31
@@ -XXX,XX +XXX,XX @@ void *address_space_map(AddressSpace *as,
40
32
41
static int neon_2rm_is_float_op(int op)
33
memory_region_ref(mr);
42
{
34
*plen = flatview_extend_translation(fv, addr, len, mr, xlat,
43
- /* Return true if this neon 2reg-misc op is float-to-float */
35
- l, is_write);
44
- return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
36
+ l, is_write, attrs);
45
+ /*
37
ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
46
+ * Return true if this neon 2reg-misc op is float-to-float.
38
rcu_read_unlock();
47
+ * This is not a property of the operation but of our code --
39
48
+ * what we are asking here is "does the code for this case in
40
@@ -XXX,XX +XXX,XX @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
49
+ * the Neon for-each-pass loop use cpu_F0s?".
41
mr = cache->mrs.mr;
50
+ */
42
memory_region_ref(mr);
51
+ return (op == NEON_2RM_VNEG_F ||
43
if (memory_access_is_direct(mr, is_write)) {
52
(op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
44
+ /* We don't care about the memory attributes here as we're only
53
op == NEON_2RM_VRINTM ||
45
+ * doing this if we found actual RAM, which behaves the same
54
(op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
46
+ * regardless of attributes; so UNSPECIFIED is fine.
55
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
47
+ */
56
break;
48
l = flatview_extend_translation(cache->fv, addr, len, mr,
57
}
49
- cache->xlat, l, is_write);
58
case NEON_2RM_VABS_F:
50
+ cache->xlat, l, is_write,
59
- gen_vfp_abs(0);
51
+ MEMTXATTRS_UNSPECIFIED);
60
+ gen_helper_vfp_abss(tmp, tmp);
52
cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, &l, true);
61
break;
53
} else {
62
case NEON_2RM_VNEG_F:
54
cache->ptr = NULL;
63
gen_vfp_neg(0);
55
--
64
--
56
2.17.1
65
2.20.1
57
66
58
67
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
Switch NEON_2RM_VABS_F away from using cpu_F0s.
2
add MemTxAttrs as an argument to address_space_translate_iommu().
3
2
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180521140402.23318-14-peter.maydell@linaro.org
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190613163917.28589-5-peter.maydell@linaro.org
8
---
7
---
9
exec.c | 8 +++++---
8
target/arm/translate.c | 13 ++-----------
10
1 file changed, 5 insertions(+), 3 deletions(-)
9
1 file changed, 2 insertions(+), 11 deletions(-)
11
10
12
diff --git a/exec.c b/exec.c
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/exec.c
13
--- a/target/arm/translate.c
15
+++ b/exec.c
14
+++ b/target/arm/translate.c
16
@@ -XXX,XX +XXX,XX @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
15
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
17
* @is_write: whether the translation operation is for write
16
return statusptr;
18
* @is_mmio: whether this can be MMIO, set true if it can
19
* @target_as: the address space targeted by the IOMMU
20
+ * @attrs: transaction attributes
21
*
22
* This function is called from RCU critical section. It is the common
23
* part of flatview_do_translate and address_space_translate_cached.
24
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection address_space_translate_iommu(IOMMUMemoryRegion *iomm
25
hwaddr *page_mask_out,
26
bool is_write,
27
bool is_mmio,
28
- AddressSpace **target_as)
29
+ AddressSpace **target_as,
30
+ MemTxAttrs attrs)
31
{
32
MemoryRegionSection *section;
33
hwaddr page_mask = (hwaddr)-1;
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
35
return address_space_translate_iommu(iommu_mr, xlat,
36
plen_out, page_mask_out,
37
is_write, is_mmio,
38
- target_as);
39
+ target_as, attrs);
40
}
41
if (page_mask_out) {
42
/* Not behind an IOMMU, use default page size. */
43
@@ -XXX,XX +XXX,XX @@ static inline MemoryRegion *address_space_translate_cached(
44
45
section = address_space_translate_iommu(iommu_mr, xlat, plen,
46
NULL, is_write, true,
47
- &target_as);
48
+ &target_as, attrs);
49
return section.mr;
50
}
17
}
51
18
19
-static inline void gen_vfp_neg(int dp)
20
-{
21
- if (dp)
22
- gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
23
- else
24
- gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
25
-}
26
-
27
#define VFP_GEN_ITOF(name) \
28
static inline void gen_vfp_##name(int dp, int neon) \
29
{ \
30
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
31
* what we are asking here is "does the code for this case in
32
* the Neon for-each-pass loop use cpu_F0s?".
33
*/
34
- return (op == NEON_2RM_VNEG_F ||
35
- (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
36
+ return ((op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
37
op == NEON_2RM_VRINTM ||
38
(op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
39
op >= NEON_2RM_VRECPE_F);
40
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
41
gen_helper_vfp_abss(tmp, tmp);
42
break;
43
case NEON_2RM_VNEG_F:
44
- gen_vfp_neg(0);
45
+ gen_helper_vfp_negs(tmp, tmp);
46
break;
47
case NEON_2RM_VSWP:
48
tmp2 = neon_load_reg(rd, pass);
52
--
49
--
53
2.17.1
50
2.20.1
54
51
55
52
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
Switch NEON_2RM_VRINT* away from using cpu_F0s.
2
add MemTxAttrs as an argument to flatview_access_valid().
3
Its callers now all have an attrs value to hand, so we can
4
correct our earlier temporary use of MEMTXATTRS_UNSPECIFIED.
5
2
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-10-peter.maydell@linaro.org
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190613163917.28589-6-peter.maydell@linaro.org
10
---
7
---
11
exec.c | 12 +++++-------
8
target/arm/translate.c | 8 +++-----
12
1 file changed, 5 insertions(+), 7 deletions(-)
9
1 file changed, 3 insertions(+), 5 deletions(-)
13
10
14
diff --git a/exec.c b/exec.c
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/exec.c
13
--- a/target/arm/translate.c
17
+++ b/exec.c
14
+++ b/target/arm/translate.c
18
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
15
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
19
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
16
* what we are asking here is "does the code for this case in
20
const uint8_t *buf, int len);
17
* the Neon for-each-pass loop use cpu_F0s?".
21
static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
18
*/
22
- bool is_write);
19
- return ((op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
23
+ bool is_write, MemTxAttrs attrs);
20
- op == NEON_2RM_VRINTM ||
24
21
- (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
25
static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data,
22
+ return ((op >= NEON_2RM_VCVTAU && op <= NEON_2RM_VCVTMS) ||
26
unsigned len, MemTxAttrs attrs)
23
op >= NEON_2RM_VRECPE_F);
27
@@ -XXX,XX +XXX,XX @@ static bool subpage_accepts(void *opaque, hwaddr addr,
28
#endif
29
30
return flatview_access_valid(subpage->fv, addr + subpage->base,
31
- len, is_write);
32
+ len, is_write, attrs);
33
}
24
}
34
25
35
static const MemoryRegionOps subpage_ops = {
26
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
36
@@ -XXX,XX +XXX,XX @@ static void cpu_notify_map_clients(void)
27
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
37
}
28
gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
38
29
cpu_env);
39
static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
30
- gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
40
- bool is_write)
31
+ gen_helper_rints(tmp, tmp, fpstatus);
41
+ bool is_write, MemTxAttrs attrs)
32
gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
42
{
33
cpu_env);
43
MemoryRegion *mr;
34
tcg_temp_free_ptr(fpstatus);
44
hwaddr l, xlat;
35
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
45
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
36
case NEON_2RM_VRINTX:
46
mr = flatview_translate(fv, addr, &xlat, &l, is_write);
37
{
47
if (!memory_access_is_direct(mr, is_write)) {
38
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
48
l = memory_access_size(mr, l, addr);
39
- gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
49
- /* When our callers all have attrs we'll pass them through here */
40
+ gen_helper_rints_exact(tmp, tmp, fpstatus);
50
- if (!memory_region_access_valid(mr, xlat, l, is_write,
41
tcg_temp_free_ptr(fpstatus);
51
- MEMTXATTRS_UNSPECIFIED)) {
42
break;
52
+ if (!memory_region_access_valid(mr, xlat, l, is_write, attrs)) {
43
}
53
return false;
54
}
55
}
56
@@ -XXX,XX +XXX,XX @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr,
57
58
rcu_read_lock();
59
fv = address_space_to_flatview(as);
60
- result = flatview_access_valid(fv, addr, len, is_write);
61
+ result = flatview_access_valid(fv, addr, len, is_write, attrs);
62
rcu_read_unlock();
63
return result;
64
}
65
--
44
--
66
2.17.1
45
2.20.1
67
46
68
47
diff view generated by jsdifflib
1
From: Jan Kiszka <jan.kiszka@siemens.com>
1
Stop using cpu_F0s for the NEON_2RM_VCVT[ANPM][US] ops.
2
2
3
There was a nasty flip in identifying which register group an access is
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
targeting. The issue caused spuriously raised priorities of the guest
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
when handing CPUs over in the Jailhouse hypervisor.
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190613163917.28589-7-peter.maydell@linaro.org
7
---
8
target/arm/translate.c | 7 +++----
9
1 file changed, 3 insertions(+), 4 deletions(-)
6
10
7
Cc: qemu-stable@nongnu.org
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
8
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
9
Message-id: 28b927d3-da58-bce4-cc13-bfec7f9b1cb9@siemens.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/intc/arm_gicv3_cpuif.c | 12 ++++++------
14
1 file changed, 6 insertions(+), 6 deletions(-)
15
16
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/arm_gicv3_cpuif.c
13
--- a/target/arm/translate.c
19
+++ b/hw/intc/arm_gicv3_cpuif.c
14
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
15
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
21
{
16
* what we are asking here is "does the code for this case in
22
GICv3CPUState *cs = icc_cs_from_env(env);
17
* the Neon for-each-pass loop use cpu_F0s?".
23
int regno = ri->opc2 & 3;
18
*/
24
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
19
- return ((op >= NEON_2RM_VCVTAU && op <= NEON_2RM_VCVTMS) ||
25
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
20
- op >= NEON_2RM_VRECPE_F);
26
uint64_t value = cs->ich_apr[grp][regno];
21
+ return op >= NEON_2RM_VRECPE_F;
27
22
}
28
trace_gicv3_icv_ap_read(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
23
29
@@ -XXX,XX +XXX,XX @@ static void icv_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
24
static bool neon_2rm_is_v8_op(int op)
30
{
25
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
31
GICv3CPUState *cs = icc_cs_from_env(env);
26
cpu_env);
32
int regno = ri->opc2 & 3;
27
33
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
28
if (is_signed) {
34
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
29
- gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
35
30
+ gen_helper_vfp_tosls(tmp, tmp,
36
trace_gicv3_icv_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
31
tcg_shift, fpst);
37
32
} else {
38
@@ -XXX,XX +XXX,XX @@ static uint64_t icc_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
33
- gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
39
uint64_t value;
34
+ gen_helper_vfp_touls(tmp, tmp,
40
35
tcg_shift, fpst);
41
int regno = ri->opc2 & 3;
36
}
42
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
43
+ int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;
44
45
if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
46
return icv_ap_read(env, ri);
47
@@ -XXX,XX +XXX,XX @@ static void icc_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
48
GICv3CPUState *cs = icc_cs_from_env(env);
49
50
int regno = ri->opc2 & 3;
51
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
52
+ int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;
53
54
if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
55
icv_ap_write(env, ri, value);
56
@@ -XXX,XX +XXX,XX @@ static uint64_t ich_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
57
{
58
GICv3CPUState *cs = icc_cs_from_env(env);
59
int regno = ri->opc2 & 3;
60
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
61
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
62
uint64_t value;
63
64
value = cs->ich_apr[grp][regno];
65
@@ -XXX,XX +XXX,XX @@ static void ich_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
66
{
67
GICv3CPUState *cs = icc_cs_from_env(env);
68
int regno = ri->opc2 & 3;
69
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
70
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
71
72
trace_gicv3_ich_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
73
37
74
--
38
--
75
2.17.1
39
2.20.1
76
40
77
41
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
Stop using cpu_F0s for NEON_2RM_VRECPE_F and NEON_2RM_VRSQRTE_F.
2
add MemTxAttrs as an argument to address_space_translate()
3
and address_space_translate_cached(). Callers either have an
4
attrs value to hand, or don't care and can use MEMTXATTRS_UNSPECIFIED.
5
2
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-4-peter.maydell@linaro.org
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190613163917.28589-8-peter.maydell@linaro.org
10
---
7
---
11
include/exec/memory.h | 4 +++-
8
target/arm/translate.c | 6 +++---
12
accel/tcg/translate-all.c | 2 +-
9
1 file changed, 3 insertions(+), 3 deletions(-)
13
exec.c | 14 +++++++++-----
14
hw/vfio/common.c | 3 ++-
15
memory_ldst.inc.c | 18 +++++++++---------
16
target/riscv/helper.c | 2 +-
17
6 files changed, 25 insertions(+), 18 deletions(-)
18
10
19
diff --git a/include/exec/memory.h b/include/exec/memory.h
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
21
--- a/include/exec/memory.h
13
--- a/target/arm/translate.c
22
+++ b/include/exec/memory.h
14
+++ b/target/arm/translate.c
23
@@ -XXX,XX +XXX,XX @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
15
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
24
* #MemoryRegion.
16
* what we are asking here is "does the code for this case in
25
* @len: pointer to length
17
* the Neon for-each-pass loop use cpu_F0s?".
26
* @is_write: indicates the transfer direction
27
+ * @attrs: memory attributes
28
*/
29
MemoryRegion *flatview_translate(FlatView *fv,
30
hwaddr addr, hwaddr *xlat,
31
@@ -XXX,XX +XXX,XX @@ MemoryRegion *flatview_translate(FlatView *fv,
32
33
static inline MemoryRegion *address_space_translate(AddressSpace *as,
34
hwaddr addr, hwaddr *xlat,
35
- hwaddr *len, bool is_write)
36
+ hwaddr *len, bool is_write,
37
+ MemTxAttrs attrs)
38
{
39
return flatview_translate(address_space_to_flatview(as),
40
addr, xlat, len, is_write);
41
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/accel/tcg/translate-all.c
44
+++ b/accel/tcg/translate-all.c
45
@@ -XXX,XX +XXX,XX @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs)
46
hwaddr l = 1;
47
48
rcu_read_lock();
49
- mr = address_space_translate(as, addr, &addr, &l, false);
50
+ mr = address_space_translate(as, addr, &addr, &l, false, attrs);
51
if (!(memory_region_is_ram(mr)
52
|| memory_region_is_romd(mr))) {
53
rcu_read_unlock();
54
diff --git a/exec.c b/exec.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/exec.c
57
+++ b/exec.c
58
@@ -XXX,XX +XXX,XX @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
59
rcu_read_lock();
60
while (len > 0) {
61
l = len;
62
- mr = address_space_translate(as, addr, &addr1, &l, true);
63
+ mr = address_space_translate(as, addr, &addr1, &l, true,
64
+ MEMTXATTRS_UNSPECIFIED);
65
66
if (!(memory_region_is_ram(mr) ||
67
memory_region_is_romd(mr))) {
68
@@ -XXX,XX +XXX,XX @@ void address_space_cache_destroy(MemoryRegionCache *cache)
69
*/
70
static inline MemoryRegion *address_space_translate_cached(
71
MemoryRegionCache *cache, hwaddr addr, hwaddr *xlat,
72
- hwaddr *plen, bool is_write)
73
+ hwaddr *plen, bool is_write, MemTxAttrs attrs)
74
{
75
MemoryRegionSection section;
76
MemoryRegion *mr;
77
@@ -XXX,XX +XXX,XX @@ address_space_read_cached_slow(MemoryRegionCache *cache, hwaddr addr,
78
MemoryRegion *mr;
79
80
l = len;
81
- mr = address_space_translate_cached(cache, addr, &addr1, &l, false);
82
+ mr = address_space_translate_cached(cache, addr, &addr1, &l, false,
83
+ MEMTXATTRS_UNSPECIFIED);
84
flatview_read_continue(cache->fv,
85
addr, MEMTXATTRS_UNSPECIFIED, buf, len,
86
addr1, l, mr);
87
@@ -XXX,XX +XXX,XX @@ address_space_write_cached_slow(MemoryRegionCache *cache, hwaddr addr,
88
MemoryRegion *mr;
89
90
l = len;
91
- mr = address_space_translate_cached(cache, addr, &addr1, &l, true);
92
+ mr = address_space_translate_cached(cache, addr, &addr1, &l, true,
93
+ MEMTXATTRS_UNSPECIFIED);
94
flatview_write_continue(cache->fv,
95
addr, MEMTXATTRS_UNSPECIFIED, buf, len,
96
addr1, l, mr);
97
@@ -XXX,XX +XXX,XX @@ bool cpu_physical_memory_is_io(hwaddr phys_addr)
98
99
rcu_read_lock();
100
mr = address_space_translate(&address_space_memory,
101
- phys_addr, &phys_addr, &l, false);
102
+ phys_addr, &phys_addr, &l, false,
103
+ MEMTXATTRS_UNSPECIFIED);
104
105
res = !(memory_region_is_ram(mr) || memory_region_is_romd(mr));
106
rcu_read_unlock();
107
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/hw/vfio/common.c
110
+++ b/hw/vfio/common.c
111
@@ -XXX,XX +XXX,XX @@ static bool vfio_get_vaddr(IOMMUTLBEntry *iotlb, void **vaddr,
112
*/
18
*/
113
mr = address_space_translate(&address_space_memory,
19
- return op >= NEON_2RM_VRECPE_F;
114
iotlb->translated_addr,
20
+ return op >= NEON_2RM_VCVT_FS;
115
- &xlat, &len, writable);
21
}
116
+ &xlat, &len, writable,
22
117
+ MEMTXATTRS_UNSPECIFIED);
23
static bool neon_2rm_is_v8_op(int op)
118
if (!memory_region_is_ram(mr)) {
24
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
119
error_report("iommu map to non memory area %"HWADDR_PRIx"",
25
case NEON_2RM_VRECPE_F:
120
xlat);
26
{
121
diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c
27
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
122
index XXXXXXX..XXXXXXX 100644
28
- gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
123
--- a/memory_ldst.inc.c
29
+ gen_helper_recpe_f32(tmp, tmp, fpstatus);
124
+++ b/memory_ldst.inc.c
30
tcg_temp_free_ptr(fpstatus);
125
@@ -XXX,XX +XXX,XX @@ static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
31
break;
126
bool release_lock = false;
32
}
127
33
case NEON_2RM_VRSQRTE_F:
128
RCU_READ_LOCK();
34
{
129
- mr = TRANSLATE(addr, &addr1, &l, false);
35
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
130
+ mr = TRANSLATE(addr, &addr1, &l, false, attrs);
36
- gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
131
if (l < 4 || !IS_DIRECT(mr, false)) {
37
+ gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
132
release_lock |= prepare_mmio_access(mr);
38
tcg_temp_free_ptr(fpstatus);
133
39
break;
134
@@ -XXX,XX +XXX,XX @@ static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
40
}
135
bool release_lock = false;
136
137
RCU_READ_LOCK();
138
- mr = TRANSLATE(addr, &addr1, &l, false);
139
+ mr = TRANSLATE(addr, &addr1, &l, false, attrs);
140
if (l < 8 || !IS_DIRECT(mr, false)) {
141
release_lock |= prepare_mmio_access(mr);
142
143
@@ -XXX,XX +XXX,XX @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
144
bool release_lock = false;
145
146
RCU_READ_LOCK();
147
- mr = TRANSLATE(addr, &addr1, &l, false);
148
+ mr = TRANSLATE(addr, &addr1, &l, false, attrs);
149
if (!IS_DIRECT(mr, false)) {
150
release_lock |= prepare_mmio_access(mr);
151
152
@@ -XXX,XX +XXX,XX @@ static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
153
bool release_lock = false;
154
155
RCU_READ_LOCK();
156
- mr = TRANSLATE(addr, &addr1, &l, false);
157
+ mr = TRANSLATE(addr, &addr1, &l, false, attrs);
158
if (l < 2 || !IS_DIRECT(mr, false)) {
159
release_lock |= prepare_mmio_access(mr);
160
161
@@ -XXX,XX +XXX,XX @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
162
bool release_lock = false;
163
164
RCU_READ_LOCK();
165
- mr = TRANSLATE(addr, &addr1, &l, true);
166
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
167
if (l < 4 || !IS_DIRECT(mr, true)) {
168
release_lock |= prepare_mmio_access(mr);
169
170
@@ -XXX,XX +XXX,XX @@ static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
171
bool release_lock = false;
172
173
RCU_READ_LOCK();
174
- mr = TRANSLATE(addr, &addr1, &l, true);
175
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
176
if (l < 4 || !IS_DIRECT(mr, true)) {
177
release_lock |= prepare_mmio_access(mr);
178
179
@@ -XXX,XX +XXX,XX @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL,
180
bool release_lock = false;
181
182
RCU_READ_LOCK();
183
- mr = TRANSLATE(addr, &addr1, &l, true);
184
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
185
if (!IS_DIRECT(mr, true)) {
186
release_lock |= prepare_mmio_access(mr);
187
r = memory_region_dispatch_write(mr, addr1, val, 1, attrs);
188
@@ -XXX,XX +XXX,XX @@ static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
189
bool release_lock = false;
190
191
RCU_READ_LOCK();
192
- mr = TRANSLATE(addr, &addr1, &l, true);
193
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
194
if (l < 2 || !IS_DIRECT(mr, true)) {
195
release_lock |= prepare_mmio_access(mr);
196
197
@@ -XXX,XX +XXX,XX @@ static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
198
bool release_lock = false;
199
200
RCU_READ_LOCK();
201
- mr = TRANSLATE(addr, &addr1, &l, true);
202
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
203
if (l < 8 || !IS_DIRECT(mr, true)) {
204
release_lock |= prepare_mmio_access(mr);
205
206
diff --git a/target/riscv/helper.c b/target/riscv/helper.c
207
index XXXXXXX..XXXXXXX 100644
208
--- a/target/riscv/helper.c
209
+++ b/target/riscv/helper.c
210
@@ -XXX,XX +XXX,XX @@ restart:
211
MemoryRegion *mr;
212
hwaddr l = sizeof(target_ulong), addr1;
213
mr = address_space_translate(cs->as, pte_addr,
214
- &addr1, &l, false);
215
+ &addr1, &l, false, MEMTXATTRS_UNSPECIFIED);
216
if (memory_access_is_direct(mr, true)) {
217
target_ulong *pte_pa =
218
qemu_map_ram_ptr(mr->ram_block, addr1);
219
--
41
--
220
2.17.1
42
2.20.1
221
43
222
44
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Stop using cpu_F0s for the Neon f32/s32 VCVT operations.
2
Since this is the last user of cpu_F0s in the Neon 2rm-op
3
loop, we can remove the handling code for it too.
2
4
3
Depending on the host abi, float16, aka uint16_t, values are
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
passed and returned either zero-extended in the host register
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
or with garbage at the top of the host register.
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190613163917.28589-9-peter.maydell@linaro.org
9
---
10
target/arm/translate.c | 82 ++++++++++++------------------------------
11
1 file changed, 22 insertions(+), 60 deletions(-)
6
12
7
The tcg code generator has so far been assuming garbage, as that
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
8
matches the x86 abi, but this is incorrect for other host abis.
9
Further, target/arm has so far been assuming zero-extended results,
10
so that it may store the 16-bit value into a 32-bit slot with the
11
high 16-bits already clear.
12
13
Rectify both problems by mapping "f16" in the helper definition
14
to uint32_t instead of (a typedef for) uint16_t. This forces
15
the host compiler to assume garbage in the upper 16 bits on input
16
and to zero-extend the result on output.
17
18
Cc: qemu-stable@nongnu.org
19
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
22
Message-id: 20180522175629.24932-1-richard.henderson@linaro.org
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
---
26
include/exec/helper-head.h | 2 +-
27
target/arm/helper-a64.c | 35 +++++++++--------
28
target/arm/helper.c | 80 +++++++++++++++++++-------------------
29
3 files changed, 59 insertions(+), 58 deletions(-)
30
31
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
32
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
33
--- a/include/exec/helper-head.h
15
--- a/target/arm/translate.c
34
+++ b/include/exec/helper-head.h
16
+++ b/target/arm/translate.c
35
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
36
#define dh_ctype_int int
18
return statusptr;
37
#define dh_ctype_i64 uint64_t
38
#define dh_ctype_s64 int64_t
39
-#define dh_ctype_f16 float16
40
+#define dh_ctype_f16 uint32_t
41
#define dh_ctype_f32 float32
42
#define dh_ctype_f64 float64
43
#define dh_ctype_ptr void *
44
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/helper-a64.c
47
+++ b/target/arm/helper-a64.c
48
@@ -XXX,XX +XXX,XX @@ static inline uint32_t float_rel_to_flags(int res)
49
return flags;
50
}
19
}
51
20
52
-uint64_t HELPER(vfp_cmph_a64)(float16 x, float16 y, void *fp_status)
21
-#define VFP_GEN_ITOF(name) \
53
+uint64_t HELPER(vfp_cmph_a64)(uint32_t x, uint32_t y, void *fp_status)
22
-static inline void gen_vfp_##name(int dp, int neon) \
23
-{ \
24
- TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
25
- if (dp) { \
26
- gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
27
- } else { \
28
- gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
29
- } \
30
- tcg_temp_free_ptr(statusptr); \
31
-}
32
-
33
-VFP_GEN_ITOF(uito)
34
-VFP_GEN_ITOF(sito)
35
-#undef VFP_GEN_ITOF
36
-
37
-#define VFP_GEN_FTOI(name) \
38
-static inline void gen_vfp_##name(int dp, int neon) \
39
-{ \
40
- TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
41
- if (dp) { \
42
- gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
43
- } else { \
44
- gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
45
- } \
46
- tcg_temp_free_ptr(statusptr); \
47
-}
48
-
49
-VFP_GEN_FTOI(touiz)
50
-VFP_GEN_FTOI(tosiz)
51
-#undef VFP_GEN_FTOI
52
-
53
#define VFP_GEN_FIX(name, round) \
54
static inline void gen_vfp_##name(int dp, int shift, int neon) \
55
{ \
56
@@ -XXX,XX +XXX,XX @@ static const uint8_t neon_3r_sizes[] = {
57
#define NEON_2RM_VCVT_SF 62
58
#define NEON_2RM_VCVT_UF 63
59
60
-static int neon_2rm_is_float_op(int op)
61
-{
62
- /*
63
- * Return true if this neon 2reg-misc op is float-to-float.
64
- * This is not a property of the operation but of our code --
65
- * what we are asking here is "does the code for this case in
66
- * the Neon for-each-pass loop use cpu_F0s?".
67
- */
68
- return op >= NEON_2RM_VCVT_FS;
69
-}
70
-
71
static bool neon_2rm_is_v8_op(int op)
54
{
72
{
55
return float_rel_to_flags(float16_compare_quiet(x, y, fp_status));
73
/* Return true if this neon 2reg-misc op is ARMv8 and up */
56
}
74
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
57
75
default:
58
-uint64_t HELPER(vfp_cmpeh_a64)(float16 x, float16 y, void *fp_status)
76
elementwise:
59
+uint64_t HELPER(vfp_cmpeh_a64)(uint32_t x, uint32_t y, void *fp_status)
77
for (pass = 0; pass < (q ? 4 : 2); pass++) {
60
{
78
- if (neon_2rm_is_float_op(op)) {
61
return float_rel_to_flags(float16_compare(x, y, fp_status));
79
- tcg_gen_ld_f32(cpu_F0s, cpu_env,
62
}
80
- neon_reg_offset(rm, pass));
63
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_cgt_f64)(float64 a, float64 b, void *fpstp)
81
- tmp = NULL;
64
#define float64_three make_float64(0x4008000000000000ULL)
82
- } else {
65
#define float64_one_point_five make_float64(0x3FF8000000000000ULL)
83
- tmp = neon_load_reg(rm, pass);
66
84
- }
67
-float16 HELPER(recpsf_f16)(float16 a, float16 b, void *fpstp)
85
+ tmp = neon_load_reg(rm, pass);
68
+uint32_t HELPER(recpsf_f16)(uint32_t a, uint32_t b, void *fpstp)
86
switch (op) {
69
{
87
case NEON_2RM_VREV32:
70
float_status *fpst = fpstp;
88
switch (size) {
71
89
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
72
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpsf_f64)(float64 a, float64 b, void *fpstp)
90
break;
73
return float64_muladd(a, b, float64_two, 0, fpst);
91
}
74
}
92
case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
75
93
- gen_vfp_sito(0, 1);
76
-float16 HELPER(rsqrtsf_f16)(float16 a, float16 b, void *fpstp)
94
+ {
77
+uint32_t HELPER(rsqrtsf_f16)(uint32_t a, uint32_t b, void *fpstp)
95
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
78
{
96
+ gen_helper_vfp_sitos(tmp, tmp, fpstatus);
79
float_status *fpst = fpstp;
97
+ tcg_temp_free_ptr(fpstatus);
80
98
break;
81
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_addlp_u16)(uint64_t a)
99
+ }
82
}
100
case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
83
101
- gen_vfp_uito(0, 1);
84
/* Floating-point reciprocal exponent - see FPRecpX in ARM ARM */
102
+ {
85
-float16 HELPER(frecpx_f16)(float16 a, void *fpstp)
103
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
86
+uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
104
+ gen_helper_vfp_uitos(tmp, tmp, fpstatus);
87
{
105
+ tcg_temp_free_ptr(fpstatus);
88
float_status *fpst = fpstp;
106
break;
89
uint16_t val16, sbit;
107
+ }
90
@@ -XXX,XX +XXX,XX @@ void HELPER(casp_be_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
108
case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
91
#define ADVSIMD_HELPER(name, suffix) HELPER(glue(glue(advsimd_, name), suffix))
109
- gen_vfp_tosiz(0, 1);
92
110
+ {
93
#define ADVSIMD_HALFOP(name) \
111
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
94
-float16 ADVSIMD_HELPER(name, h)(float16 a, float16 b, void *fpstp) \
112
+ gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
95
+uint32_t ADVSIMD_HELPER(name, h)(uint32_t a, uint32_t b, void *fpstp) \
113
+ tcg_temp_free_ptr(fpstatus);
96
{ \
114
break;
97
float_status *fpst = fpstp; \
115
+ }
98
return float16_ ## name(a, b, fpst); \
116
case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
99
@@ -XXX,XX +XXX,XX @@ ADVSIMD_HALFOP(mulx)
117
- gen_vfp_touiz(0, 1);
100
ADVSIMD_TWOHALFOP(mulx)
118
+ {
101
119
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
102
/* fused multiply-accumulate */
120
+ gen_helper_vfp_touizs(tmp, tmp, fpstatus);
103
-float16 HELPER(advsimd_muladdh)(float16 a, float16 b, float16 c, void *fpstp)
121
+ tcg_temp_free_ptr(fpstatus);
104
+uint32_t HELPER(advsimd_muladdh)(uint32_t a, uint32_t b, uint32_t c,
122
break;
105
+ void *fpstp)
123
+ }
106
{
124
default:
107
float_status *fpst = fpstp;
125
/* Reserved op values were caught by the
108
return float16_muladd(a, b, c, 0, fpst);
126
* neon_2rm_sizes[] check earlier.
109
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_muladd2h)(uint32_t two_a, uint32_t two_b,
127
*/
110
128
abort();
111
#define ADVSIMD_CMPRES(test) (test) ? 0xffff : 0
129
}
112
130
- if (neon_2rm_is_float_op(op)) {
113
-uint32_t HELPER(advsimd_ceq_f16)(float16 a, float16 b, void *fpstp)
131
- tcg_gen_st_f32(cpu_F0s, cpu_env,
114
+uint32_t HELPER(advsimd_ceq_f16)(uint32_t a, uint32_t b, void *fpstp)
132
- neon_reg_offset(rd, pass));
115
{
133
- } else {
116
float_status *fpst = fpstp;
134
- neon_store_reg(rd, pass, tmp);
117
int compare = float16_compare_quiet(a, b, fpst);
135
- }
118
return ADVSIMD_CMPRES(compare == float_relation_equal);
136
+ neon_store_reg(rd, pass, tmp);
119
}
137
}
120
138
break;
121
-uint32_t HELPER(advsimd_cge_f16)(float16 a, float16 b, void *fpstp)
139
}
122
+uint32_t HELPER(advsimd_cge_f16)(uint32_t a, uint32_t b, void *fpstp)
123
{
124
float_status *fpst = fpstp;
125
int compare = float16_compare(a, b, fpst);
126
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_cge_f16)(float16 a, float16 b, void *fpstp)
127
compare == float_relation_equal);
128
}
129
130
-uint32_t HELPER(advsimd_cgt_f16)(float16 a, float16 b, void *fpstp)
131
+uint32_t HELPER(advsimd_cgt_f16)(uint32_t a, uint32_t b, void *fpstp)
132
{
133
float_status *fpst = fpstp;
134
int compare = float16_compare(a, b, fpst);
135
return ADVSIMD_CMPRES(compare == float_relation_greater);
136
}
137
138
-uint32_t HELPER(advsimd_acge_f16)(float16 a, float16 b, void *fpstp)
139
+uint32_t HELPER(advsimd_acge_f16)(uint32_t a, uint32_t b, void *fpstp)
140
{
141
float_status *fpst = fpstp;
142
float16 f0 = float16_abs(a);
143
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_acge_f16)(float16 a, float16 b, void *fpstp)
144
compare == float_relation_equal);
145
}
146
147
-uint32_t HELPER(advsimd_acgt_f16)(float16 a, float16 b, void *fpstp)
148
+uint32_t HELPER(advsimd_acgt_f16)(uint32_t a, uint32_t b, void *fpstp)
149
{
150
float_status *fpst = fpstp;
151
float16 f0 = float16_abs(a);
152
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_acgt_f16)(float16 a, float16 b, void *fpstp)
153
}
154
155
/* round to integral */
156
-float16 HELPER(advsimd_rinth_exact)(float16 x, void *fp_status)
157
+uint32_t HELPER(advsimd_rinth_exact)(uint32_t x, void *fp_status)
158
{
159
return float16_round_to_int(x, fp_status);
160
}
161
162
-float16 HELPER(advsimd_rinth)(float16 x, void *fp_status)
163
+uint32_t HELPER(advsimd_rinth)(uint32_t x, void *fp_status)
164
{
165
int old_flags = get_float_exception_flags(fp_status), new_flags;
166
float16 ret;
167
@@ -XXX,XX +XXX,XX @@ float16 HELPER(advsimd_rinth)(float16 x, void *fp_status)
168
* setting the mode appropriately before calling the helper.
169
*/
170
171
-uint32_t HELPER(advsimd_f16tosinth)(float16 a, void *fpstp)
172
+uint32_t HELPER(advsimd_f16tosinth)(uint32_t a, void *fpstp)
173
{
174
float_status *fpst = fpstp;
175
176
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_f16tosinth)(float16 a, void *fpstp)
177
return float16_to_int16(a, fpst);
178
}
179
180
-uint32_t HELPER(advsimd_f16touinth)(float16 a, void *fpstp)
181
+uint32_t HELPER(advsimd_f16touinth)(uint32_t a, void *fpstp)
182
{
183
float_status *fpst = fpstp;
184
185
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_f16touinth)(float16 a, void *fpstp)
186
* Square Root and Reciprocal square root
187
*/
188
189
-float16 HELPER(sqrt_f16)(float16 a, void *fpstp)
190
+uint32_t HELPER(sqrt_f16)(uint32_t a, void *fpstp)
191
{
192
float_status *s = fpstp;
193
194
diff --git a/target/arm/helper.c b/target/arm/helper.c
195
index XXXXXXX..XXXXXXX 100644
196
--- a/target/arm/helper.c
197
+++ b/target/arm/helper.c
198
@@ -XXX,XX +XXX,XX @@ DO_VFP_cmp(d, float64)
199
200
/* Integer to float and float to integer conversions */
201
202
-#define CONV_ITOF(name, fsz, sign) \
203
- float##fsz HELPER(name)(uint32_t x, void *fpstp) \
204
-{ \
205
- float_status *fpst = fpstp; \
206
- return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
207
+#define CONV_ITOF(name, ftype, fsz, sign) \
208
+ftype HELPER(name)(uint32_t x, void *fpstp) \
209
+{ \
210
+ float_status *fpst = fpstp; \
211
+ return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
212
}
213
214
-#define CONV_FTOI(name, fsz, sign, round) \
215
-uint32_t HELPER(name)(float##fsz x, void *fpstp) \
216
-{ \
217
- float_status *fpst = fpstp; \
218
- if (float##fsz##_is_any_nan(x)) { \
219
- float_raise(float_flag_invalid, fpst); \
220
- return 0; \
221
- } \
222
- return float##fsz##_to_##sign##int32##round(x, fpst); \
223
+#define CONV_FTOI(name, ftype, fsz, sign, round) \
224
+uint32_t HELPER(name)(ftype x, void *fpstp) \
225
+{ \
226
+ float_status *fpst = fpstp; \
227
+ if (float##fsz##_is_any_nan(x)) { \
228
+ float_raise(float_flag_invalid, fpst); \
229
+ return 0; \
230
+ } \
231
+ return float##fsz##_to_##sign##int32##round(x, fpst); \
232
}
233
234
-#define FLOAT_CONVS(name, p, fsz, sign) \
235
-CONV_ITOF(vfp_##name##to##p, fsz, sign) \
236
-CONV_FTOI(vfp_to##name##p, fsz, sign, ) \
237
-CONV_FTOI(vfp_to##name##z##p, fsz, sign, _round_to_zero)
238
+#define FLOAT_CONVS(name, p, ftype, fsz, sign) \
239
+ CONV_ITOF(vfp_##name##to##p, ftype, fsz, sign) \
240
+ CONV_FTOI(vfp_to##name##p, ftype, fsz, sign, ) \
241
+ CONV_FTOI(vfp_to##name##z##p, ftype, fsz, sign, _round_to_zero)
242
243
-FLOAT_CONVS(si, h, 16, )
244
-FLOAT_CONVS(si, s, 32, )
245
-FLOAT_CONVS(si, d, 64, )
246
-FLOAT_CONVS(ui, h, 16, u)
247
-FLOAT_CONVS(ui, s, 32, u)
248
-FLOAT_CONVS(ui, d, 64, u)
249
+FLOAT_CONVS(si, h, uint32_t, 16, )
250
+FLOAT_CONVS(si, s, float32, 32, )
251
+FLOAT_CONVS(si, d, float64, 64, )
252
+FLOAT_CONVS(ui, h, uint32_t, 16, u)
253
+FLOAT_CONVS(ui, s, float32, 32, u)
254
+FLOAT_CONVS(ui, d, float64, 64, u)
255
256
#undef CONV_ITOF
257
#undef CONV_FTOI
258
@@ -XXX,XX +XXX,XX @@ static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst)
259
return float64_to_float16(float64_scalbn(f, -shift, fpst), true, fpst);
260
}
261
262
-float16 HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
263
+uint32_t HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
264
{
265
return do_postscale_fp16(int32_to_float64(x, fpst), shift, fpst);
266
}
267
268
-float16 HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
269
+uint32_t HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
270
{
271
return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst);
272
}
273
274
-float16 HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
275
+uint32_t HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
276
{
277
return do_postscale_fp16(int64_to_float64(x, fpst), shift, fpst);
278
}
279
280
-float16 HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
281
+uint32_t HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
282
{
283
return do_postscale_fp16(uint64_to_float64(x, fpst), shift, fpst);
284
}
285
@@ -XXX,XX +XXX,XX @@ static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst)
286
}
287
}
288
289
-uint32_t HELPER(vfp_toshh)(float16 x, uint32_t shift, void *fpst)
290
+uint32_t HELPER(vfp_toshh)(uint32_t x, uint32_t shift, void *fpst)
291
{
292
return float64_to_int16(do_prescale_fp16(x, shift, fpst), fpst);
293
}
294
295
-uint32_t HELPER(vfp_touhh)(float16 x, uint32_t shift, void *fpst)
296
+uint32_t HELPER(vfp_touhh)(uint32_t x, uint32_t shift, void *fpst)
297
{
298
return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst);
299
}
300
301
-uint32_t HELPER(vfp_toslh)(float16 x, uint32_t shift, void *fpst)
302
+uint32_t HELPER(vfp_toslh)(uint32_t x, uint32_t shift, void *fpst)
303
{
304
return float64_to_int32(do_prescale_fp16(x, shift, fpst), fpst);
305
}
306
307
-uint32_t HELPER(vfp_toulh)(float16 x, uint32_t shift, void *fpst)
308
+uint32_t HELPER(vfp_toulh)(uint32_t x, uint32_t shift, void *fpst)
309
{
310
return float64_to_uint32(do_prescale_fp16(x, shift, fpst), fpst);
311
}
312
313
-uint64_t HELPER(vfp_tosqh)(float16 x, uint32_t shift, void *fpst)
314
+uint64_t HELPER(vfp_tosqh)(uint32_t x, uint32_t shift, void *fpst)
315
{
316
return float64_to_int64(do_prescale_fp16(x, shift, fpst), fpst);
317
}
318
319
-uint64_t HELPER(vfp_touqh)(float16 x, uint32_t shift, void *fpst)
320
+uint64_t HELPER(vfp_touqh)(uint32_t x, uint32_t shift, void *fpst)
321
{
322
return float64_to_uint64(do_prescale_fp16(x, shift, fpst), fpst);
323
}
324
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(set_neon_rmode)(uint32_t rmode, CPUARMState *env)
325
}
326
327
/* Half precision conversions. */
328
-float32 HELPER(vfp_fcvt_f16_to_f32)(float16 a, void *fpstp, uint32_t ahp_mode)
329
+float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, void *fpstp, uint32_t ahp_mode)
330
{
331
/* Squash FZ16 to 0 for the duration of conversion. In this case,
332
* it would affect flushing input denormals.
333
@@ -XXX,XX +XXX,XX @@ float32 HELPER(vfp_fcvt_f16_to_f32)(float16 a, void *fpstp, uint32_t ahp_mode)
334
return r;
335
}
336
337
-float16 HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
338
+uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
339
{
340
/* Squash FZ16 to 0 for the duration of conversion. In this case,
341
* it would affect flushing output denormals.
342
@@ -XXX,XX +XXX,XX @@ float16 HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
343
return r;
344
}
345
346
-float64 HELPER(vfp_fcvt_f16_to_f64)(float16 a, void *fpstp, uint32_t ahp_mode)
347
+float64 HELPER(vfp_fcvt_f16_to_f64)(uint32_t a, void *fpstp, uint32_t ahp_mode)
348
{
349
/* Squash FZ16 to 0 for the duration of conversion. In this case,
350
* it would affect flushing input denormals.
351
@@ -XXX,XX +XXX,XX @@ float64 HELPER(vfp_fcvt_f16_to_f64)(float16 a, void *fpstp, uint32_t ahp_mode)
352
return r;
353
}
354
355
-float16 HELPER(vfp_fcvt_f64_to_f16)(float64 a, void *fpstp, uint32_t ahp_mode)
356
+uint32_t HELPER(vfp_fcvt_f64_to_f16)(float64 a, void *fpstp, uint32_t ahp_mode)
357
{
358
/* Squash FZ16 to 0 for the duration of conversion. In this case,
359
* it would affect flushing output denormals.
360
@@ -XXX,XX +XXX,XX @@ static bool round_to_inf(float_status *fpst, bool sign_bit)
361
g_assert_not_reached();
362
}
363
364
-float16 HELPER(recpe_f16)(float16 input, void *fpstp)
365
+uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
366
{
367
float_status *fpst = fpstp;
368
float16 f16 = float16_squash_input_denormal(input, fpst);
369
@@ -XXX,XX +XXX,XX @@ static uint64_t recip_sqrt_estimate(int *exp , int exp_off, uint64_t frac)
370
return extract64(estimate, 0, 8) << 44;
371
}
372
373
-float16 HELPER(rsqrte_f16)(float16 input, void *fpstp)
374
+uint32_t HELPER(rsqrte_f16)(uint32_t input, void *fpstp)
375
{
376
float_status *s = fpstp;
377
float16 f16 = float16_squash_input_denormal(input, s);
378
--
140
--
379
2.17.1
141
2.20.1
380
142
381
143
diff view generated by jsdifflib
1
Add entries to MAINTAINERS to cover the newer MPS2 boards and
1
Stop using cpu_F0s in the Neon VCVT fixed-point operations.
2
the new devices they use.
3
2
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20180518153157.14899-1-peter.maydell@linaro.org
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190613163917.28589-10-peter.maydell@linaro.org
6
---
7
---
7
MAINTAINERS | 9 +++++++--
8
target/arm/translate.c | 62 +++++++++++++++++++-----------------------
8
1 file changed, 7 insertions(+), 2 deletions(-)
9
1 file changed, 28 insertions(+), 34 deletions(-)
9
10
10
diff --git a/MAINTAINERS b/MAINTAINERS
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
11
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
12
--- a/MAINTAINERS
13
--- a/target/arm/translate.c
13
+++ b/MAINTAINERS
14
+++ b/target/arm/translate.c
14
@@ -XXX,XX +XXX,XX @@ F: hw/timer/cmsdk-apb-timer.c
15
@@ -XXX,XX +XXX,XX @@ static const char * const regnames[] =
15
F: include/hw/timer/cmsdk-apb-timer.h
16
/* Function prototypes for gen_ functions calling Neon helpers. */
16
F: hw/char/cmsdk-apb-uart.c
17
typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
17
F: include/hw/char/cmsdk-apb-uart.h
18
TCGv_i32, TCGv_i32);
18
+F: hw/misc/tz-ppc.c
19
+/* Function prototypes for gen_ functions for fix point conversions */
19
+F: include/hw/misc/tz-ppc.h
20
+typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
20
21
21
ARM cores
22
/* initialize TCG globals. */
22
M: Peter Maydell <peter.maydell@linaro.org>
23
void arm_translate_init(void)
23
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
24
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
24
L: qemu-arm@nongnu.org
25
return statusptr;
25
S: Maintained
26
}
26
F: hw/arm/mps2.c
27
27
-F: hw/misc/mps2-scc.c
28
-#define VFP_GEN_FIX(name, round) \
28
-F: include/hw/misc/mps2-scc.h
29
-static inline void gen_vfp_##name(int dp, int shift, int neon) \
29
+F: hw/arm/mps2-tz.c
30
-{ \
30
+F: hw/misc/mps2-*.c
31
- TCGv_i32 tmp_shift = tcg_const_i32(shift); \
31
+F: include/hw/misc/mps2-*.h
32
- TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
32
+F: hw/arm/iotkit.c
33
- if (dp) { \
33
+F: include/hw/arm/iotkit.h
34
- gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
34
35
- statusptr); \
35
Musicpal
36
- } else { \
36
M: Jan Kiszka <jan.kiszka@web.de>
37
- gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
38
- statusptr); \
39
- } \
40
- tcg_temp_free_i32(tmp_shift); \
41
- tcg_temp_free_ptr(statusptr); \
42
-}
43
-VFP_GEN_FIX(tosl, _round_to_zero)
44
-VFP_GEN_FIX(toul, _round_to_zero)
45
-VFP_GEN_FIX(slto, )
46
-VFP_GEN_FIX(ulto, )
47
-#undef VFP_GEN_FIX
48
-
49
static inline long vfp_reg_offset(bool dp, unsigned reg)
50
{
51
if (dp) {
52
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
53
}
54
} else if (op >= 14) {
55
/* VCVT fixed-point. */
56
+ TCGv_ptr fpst;
57
+ TCGv_i32 shiftv;
58
+ VFPGenFixPointFn *fn;
59
+
60
if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
61
return 1;
62
}
63
+
64
+ if (!(op & 1)) {
65
+ if (u) {
66
+ fn = gen_helper_vfp_ultos;
67
+ } else {
68
+ fn = gen_helper_vfp_sltos;
69
+ }
70
+ } else {
71
+ if (u) {
72
+ fn = gen_helper_vfp_touls_round_to_zero;
73
+ } else {
74
+ fn = gen_helper_vfp_tosls_round_to_zero;
75
+ }
76
+ }
77
+
78
/* We have already masked out the must-be-1 top bit of imm6,
79
* hence this 32-shift where the ARM ARM has 64-imm6.
80
*/
81
shift = 32 - shift;
82
+ fpst = get_fpstatus_ptr(1);
83
+ shiftv = tcg_const_i32(shift);
84
for (pass = 0; pass < (q ? 4 : 2); pass++) {
85
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
86
- if (!(op & 1)) {
87
- if (u)
88
- gen_vfp_ulto(0, shift, 1);
89
- else
90
- gen_vfp_slto(0, shift, 1);
91
- } else {
92
- if (u)
93
- gen_vfp_toul(0, shift, 1);
94
- else
95
- gen_vfp_tosl(0, shift, 1);
96
- }
97
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
98
+ TCGv_i32 tmpf = neon_load_reg(rm, pass);
99
+ fn(tmpf, tmpf, shiftv, fpst);
100
+ neon_store_reg(rd, pass, tmpf);
101
}
102
+ tcg_temp_free_ptr(fpst);
103
+ tcg_temp_free_i32(shiftv);
104
} else {
105
return 1;
106
}
37
--
107
--
38
2.17.1
108
2.20.1
39
109
40
110
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
Remove some old constructs from NEON_2RM_VCVT_F16_F32 code:
2
add MemTxAttrs as an argument to address_space_access_valid().
2
* don't use cpu_F0s
3
Its callers either have an attrs value to hand, or don't care
3
* don't use tcg_gen_ld_f32
4
and can use MEMTXATTRS_UNSPECIFIED.
5
4
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-6-peter.maydell@linaro.org
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190613163917.28589-11-peter.maydell@linaro.org
10
---
9
---
11
include/exec/memory.h | 4 +++-
10
target/arm/translate.c | 27 ++++++++++++---------------
12
include/sysemu/dma.h | 3 ++-
11
1 file changed, 12 insertions(+), 15 deletions(-)
13
exec.c | 3 ++-
14
target/s390x/diag.c | 6 ++++--
15
target/s390x/excp_helper.c | 3 ++-
16
target/s390x/mmu_helper.c | 3 ++-
17
target/s390x/sigp.c | 3 ++-
18
7 files changed, 17 insertions(+), 8 deletions(-)
19
12
20
diff --git a/include/exec/memory.h b/include/exec/memory.h
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
21
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
22
--- a/include/exec/memory.h
15
--- a/target/arm/translate.c
23
+++ b/include/exec/memory.h
16
+++ b/target/arm/translate.c
24
@@ -XXX,XX +XXX,XX @@ static inline MemoryRegion *address_space_translate(AddressSpace *as,
17
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
25
* @addr: address within that address space
18
return ret;
26
* @len: length of the area to be checked
27
* @is_write: indicates the transfer direction
28
+ * @attrs: memory attributes
29
*/
30
-bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write);
31
+bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len,
32
+ bool is_write, MemTxAttrs attrs);
33
34
/* address_space_map: map a physical memory region into a host virtual address
35
*
36
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/include/sysemu/dma.h
39
+++ b/include/sysemu/dma.h
40
@@ -XXX,XX +XXX,XX @@ static inline bool dma_memory_valid(AddressSpace *as,
41
DMADirection dir)
42
{
43
return address_space_access_valid(as, addr, len,
44
- dir == DMA_DIRECTION_FROM_DEVICE);
45
+ dir == DMA_DIRECTION_FROM_DEVICE,
46
+ MEMTXATTRS_UNSPECIFIED);
47
}
19
}
48
20
49
static inline int dma_memory_rw_relaxed(AddressSpace *as, dma_addr_t addr,
21
-#define tcg_gen_ld_f32 tcg_gen_ld_i32
50
diff --git a/exec.c b/exec.c
22
#define tcg_gen_st_f32 tcg_gen_st_i32
51
index XXXXXXX..XXXXXXX 100644
23
52
--- a/exec.c
24
#define ARM_CP_RW_BIT (1 << 20)
53
+++ b/exec.c
25
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
54
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
26
q || (rm & 1)) {
55
}
27
return 1;
56
28
}
57
bool address_space_access_valid(AddressSpace *as, hwaddr addr,
29
- tmp = tcg_temp_new_i32();
58
- int len, bool is_write)
30
- tmp2 = tcg_temp_new_i32();
59
+ int len, bool is_write,
31
fpst = get_fpstatus_ptr(true);
60
+ MemTxAttrs attrs)
32
ahp = get_ahp_flag();
61
{
33
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
62
FlatView *fv;
34
- gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
63
bool result;
35
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
64
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
36
- gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
65
index XXXXXXX..XXXXXXX 100644
37
+ tmp = neon_load_reg(rm, 0);
66
--- a/target/s390x/diag.c
38
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
67
+++ b/target/s390x/diag.c
39
+ tmp2 = neon_load_reg(rm, 1);
68
@@ -XXX,XX +XXX,XX @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
40
+ gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
69
return;
41
tcg_gen_shli_i32(tmp2, tmp2, 16);
70
}
42
tcg_gen_or_i32(tmp2, tmp2, tmp);
71
if (!address_space_access_valid(&address_space_memory, addr,
43
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
72
- sizeof(IplParameterBlock), false)) {
44
- gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
73
+ sizeof(IplParameterBlock), false,
45
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
74
+ MEMTXATTRS_UNSPECIFIED)) {
46
+ tcg_temp_free_i32(tmp);
75
s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
47
+ tmp = neon_load_reg(rm, 2);
76
return;
48
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
77
}
49
+ tmp3 = neon_load_reg(rm, 3);
78
@@ -XXX,XX +XXX,XX @@ out:
50
neon_store_reg(rd, 0, tmp2);
79
return;
51
- tmp2 = tcg_temp_new_i32();
80
}
52
- gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
81
if (!address_space_access_valid(&address_space_memory, addr,
53
- tcg_gen_shli_i32(tmp2, tmp2, 16);
82
- sizeof(IplParameterBlock), true)) {
54
- tcg_gen_or_i32(tmp2, tmp2, tmp);
83
+ sizeof(IplParameterBlock), true,
55
- neon_store_reg(rd, 1, tmp2);
84
+ MEMTXATTRS_UNSPECIFIED)) {
56
+ gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
85
s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
57
+ tcg_gen_shli_i32(tmp3, tmp3, 16);
86
return;
58
+ tcg_gen_or_i32(tmp3, tmp3, tmp);
87
}
59
+ neon_store_reg(rd, 1, tmp3);
88
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
60
tcg_temp_free_i32(tmp);
89
index XXXXXXX..XXXXXXX 100644
61
tcg_temp_free_i32(ahp);
90
--- a/target/s390x/excp_helper.c
62
tcg_temp_free_ptr(fpst);
91
+++ b/target/s390x/excp_helper.c
92
@@ -XXX,XX +XXX,XX @@ int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr orig_vaddr, int size,
93
94
/* check out of RAM access */
95
if (!address_space_access_valid(&address_space_memory, raddr,
96
- TARGET_PAGE_SIZE, rw)) {
97
+ TARGET_PAGE_SIZE, rw,
98
+ MEMTXATTRS_UNSPECIFIED)) {
99
DPRINTF("%s: raddr %" PRIx64 " > ram_size %" PRIx64 "\n", __func__,
100
(uint64_t)raddr, (uint64_t)ram_size);
101
trigger_pgm_exception(env, PGM_ADDRESSING, ILEN_AUTO);
102
diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/s390x/mmu_helper.c
105
+++ b/target/s390x/mmu_helper.c
106
@@ -XXX,XX +XXX,XX @@ static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
107
return ret;
108
}
109
if (!address_space_access_valid(&address_space_memory, pages[i],
110
- TARGET_PAGE_SIZE, is_write)) {
111
+ TARGET_PAGE_SIZE, is_write,
112
+ MEMTXATTRS_UNSPECIFIED)) {
113
trigger_access_exception(env, PGM_ADDRESSING, ILEN_AUTO, 0);
114
return -EFAULT;
115
}
116
diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/s390x/sigp.c
119
+++ b/target/s390x/sigp.c
120
@@ -XXX,XX +XXX,XX @@ static void sigp_set_prefix(CPUState *cs, run_on_cpu_data arg)
121
cpu_synchronize_state(cs);
122
123
if (!address_space_access_valid(&address_space_memory, addr,
124
- sizeof(struct LowCore), false)) {
125
+ sizeof(struct LowCore), false,
126
+ MEMTXATTRS_UNSPECIFIED)) {
127
set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
128
return;
129
}
130
--
63
--
131
2.17.1
64
2.20.1
132
65
133
66
diff view generated by jsdifflib
1
Add more detail to the documentation for memory_region_init_iommu()
1
Remove some old constructns from NEON_2RM_VCVT_F16_F32 code:
2
and other IOMMU-related functions and data structures.
2
* don't use CPU_F0s
3
* don't use tcg_gen_st_f32
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Message-id: 20190613163917.28589-12-peter.maydell@linaro.org
8
Message-id: 20180521140402.23318-2-peter.maydell@linaro.org
9
---
9
---
10
include/exec/memory.h | 105 ++++++++++++++++++++++++++++++++++++++----
10
target/arm/translate.c | 26 +++++++++++---------------
11
1 file changed, 95 insertions(+), 10 deletions(-)
11
1 file changed, 11 insertions(+), 15 deletions(-)
12
12
13
diff --git a/include/exec/memory.h b/include/exec/memory.h
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/exec/memory.h
15
--- a/target/arm/translate.c
16
+++ b/include/exec/memory.h
16
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ enum IOMMUMemoryRegionAttr {
17
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
18
IOMMU_ATTR_SPAPR_TCE_FD
18
return ret;
19
};
19
}
20
20
21
+/**
21
-#define tcg_gen_st_f32 tcg_gen_st_i32
22
+ * IOMMUMemoryRegionClass:
22
-
23
+ *
23
#define ARM_CP_RW_BIT (1 << 20)
24
+ * All IOMMU implementations need to subclass TYPE_IOMMU_MEMORY_REGION
24
25
+ * and provide an implementation of at least the @translate method here
25
/* Include the VFP decoder */
26
+ * to handle requests to the memory region. Other methods are optional.
26
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
27
+ *
27
tmp = neon_load_reg(rm, 0);
28
+ * The IOMMU implementation must use the IOMMU notifier infrastructure
28
tmp2 = neon_load_reg(rm, 1);
29
+ * to report whenever mappings are changed, by calling
29
tcg_gen_ext16u_i32(tmp3, tmp);
30
+ * memory_region_notify_iommu() (or, if necessary, by calling
30
- gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
31
+ * memory_region_notify_one() for each registered notifier).
31
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
32
+ */
32
- tcg_gen_shri_i32(tmp3, tmp, 16);
33
typedef struct IOMMUMemoryRegionClass {
33
- gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
34
/* private */
34
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
35
struct DeviceClass parent_class;
35
- tcg_temp_free_i32(tmp);
36
36
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
37
/*
37
+ neon_store_reg(rd, 0, tmp3);
38
- * Return a TLB entry that contains a given address. Flag should
38
+ tcg_gen_shri_i32(tmp, tmp, 16);
39
- * be the access permission of this translation operation. We can
39
+ gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
40
- * set flag to IOMMU_NONE to mean that we don't need any
40
+ neon_store_reg(rd, 1, tmp);
41
- * read/write permission checks, like, when for region replay.
41
+ tmp3 = tcg_temp_new_i32();
42
+ * Return a TLB entry that contains a given address.
42
tcg_gen_ext16u_i32(tmp3, tmp2);
43
+ *
43
- gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
44
+ * The IOMMUAccessFlags indicated via @flag are optional and may
44
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
45
+ * be specified as IOMMU_NONE to indicate that the caller needs
45
- tcg_gen_shri_i32(tmp3, tmp2, 16);
46
+ * the full translation information for both reads and writes. If
46
- gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
47
+ * the access flags are specified then the IOMMU implementation
47
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
48
+ * may use this as an optimization, to stop doing a page table
48
- tcg_temp_free_i32(tmp2);
49
+ * walk as soon as it knows that the requested permissions are not
49
- tcg_temp_free_i32(tmp3);
50
+ * allowed. If IOMMU_NONE is passed then the IOMMU must do the
50
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
51
+ * full page table walk and report the permissions in the returned
51
+ neon_store_reg(rd, 2, tmp3);
52
+ * IOMMUTLBEntry. (Note that this implies that an IOMMU may not
52
+ tcg_gen_shri_i32(tmp2, tmp2, 16);
53
+ * return different mappings for reads and writes.)
53
+ gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
54
+ *
54
+ neon_store_reg(rd, 3, tmp2);
55
+ * The returned information remains valid while the caller is
55
tcg_temp_free_i32(ahp);
56
+ * holding the big QEMU lock or is inside an RCU critical section;
56
tcg_temp_free_ptr(fpst);
57
+ * if the caller wishes to cache the mapping beyond that it must
57
break;
58
+ * register an IOMMU notifier so it can invalidate its cached
59
+ * information when the IOMMU mapping changes.
60
+ *
61
+ * @iommu: the IOMMUMemoryRegion
62
+ * @hwaddr: address to be translated within the memory region
63
+ * @flag: requested access permissions
64
*/
65
IOMMUTLBEntry (*translate)(IOMMUMemoryRegion *iommu, hwaddr addr,
66
IOMMUAccessFlags flag);
67
- /* Returns minimum supported page size */
68
+ /* Returns minimum supported page size in bytes.
69
+ * If this method is not provided then the minimum is assumed to
70
+ * be TARGET_PAGE_SIZE.
71
+ *
72
+ * @iommu: the IOMMUMemoryRegion
73
+ */
74
uint64_t (*get_min_page_size)(IOMMUMemoryRegion *iommu);
75
- /* Called when IOMMU Notifier flag changed */
76
+ /* Called when IOMMU Notifier flag changes (ie when the set of
77
+ * events which IOMMU users are requesting notification for changes).
78
+ * Optional method -- need not be provided if the IOMMU does not
79
+ * need to know exactly which events must be notified.
80
+ *
81
+ * @iommu: the IOMMUMemoryRegion
82
+ * @old_flags: events which previously needed to be notified
83
+ * @new_flags: events which now need to be notified
84
+ */
85
void (*notify_flag_changed)(IOMMUMemoryRegion *iommu,
86
IOMMUNotifierFlag old_flags,
87
IOMMUNotifierFlag new_flags);
88
- /* Set this up to provide customized IOMMU replay function */
89
+ /* Called to handle memory_region_iommu_replay().
90
+ *
91
+ * The default implementation of memory_region_iommu_replay() is to
92
+ * call the IOMMU translate method for every page in the address space
93
+ * with flag == IOMMU_NONE and then call the notifier if translate
94
+ * returns a valid mapping. If this method is implemented then it
95
+ * overrides the default behaviour, and must provide the full semantics
96
+ * of memory_region_iommu_replay(), by calling @notifier for every
97
+ * translation present in the IOMMU.
98
+ *
99
+ * Optional method -- an IOMMU only needs to provide this method
100
+ * if the default is inefficient or produces undesirable side effects.
101
+ *
102
+ * Note: this is not related to record-and-replay functionality.
103
+ */
104
void (*replay)(IOMMUMemoryRegion *iommu, IOMMUNotifier *notifier);
105
106
- /* Get IOMMU misc attributes */
107
- int (*get_attr)(IOMMUMemoryRegion *iommu, enum IOMMUMemoryRegionAttr,
108
+ /* Get IOMMU misc attributes. This is an optional method that
109
+ * can be used to allow users of the IOMMU to get implementation-specific
110
+ * information. The IOMMU implements this method to handle calls
111
+ * by IOMMU users to memory_region_iommu_get_attr() by filling in
112
+ * the arbitrary data pointer for any IOMMUMemoryRegionAttr values that
113
+ * the IOMMU supports. If the method is unimplemented then
114
+ * memory_region_iommu_get_attr() will always return -EINVAL.
115
+ *
116
+ * @iommu: the IOMMUMemoryRegion
117
+ * @attr: attribute being queried
118
+ * @data: memory to fill in with the attribute data
119
+ *
120
+ * Returns 0 on success, or a negative errno; in particular
121
+ * returns -EINVAL for unrecognized or unimplemented attribute types.
122
+ */
123
+ int (*get_attr)(IOMMUMemoryRegion *iommu, enum IOMMUMemoryRegionAttr attr,
124
void *data);
125
} IOMMUMemoryRegionClass;
126
127
@@ -XXX,XX +XXX,XX @@ static inline void memory_region_init_reservation(MemoryRegion *mr,
128
* An IOMMU region translates addresses and forwards accesses to a target
129
* memory region.
130
*
131
+ * The IOMMU implementation must define a subclass of TYPE_IOMMU_MEMORY_REGION.
132
+ * @_iommu_mr should be a pointer to enough memory for an instance of
133
+ * that subclass, @instance_size is the size of that subclass, and
134
+ * @mrtypename is its name. This function will initialize @_iommu_mr as an
135
+ * instance of the subclass, and its methods will then be called to handle
136
+ * accesses to the memory region. See the documentation of
137
+ * #IOMMUMemoryRegionClass for further details.
138
+ *
139
* @_iommu_mr: the #IOMMUMemoryRegion to be initialized
140
* @instance_size: the IOMMUMemoryRegion subclass instance size
141
* @mrtypename: the type name of the #IOMMUMemoryRegion
142
@@ -XXX,XX +XXX,XX @@ void memory_region_register_iommu_notifier(MemoryRegion *mr,
143
* a notifier with the minimum page granularity returned by
144
* mr->iommu_ops->get_page_size().
145
*
146
+ * Note: this is not related to record-and-replay functionality.
147
+ *
148
* @iommu_mr: the memory region to observe
149
* @n: the notifier to which to replay iommu mappings
150
*/
151
@@ -XXX,XX +XXX,XX @@ void memory_region_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n);
152
* memory_region_iommu_replay_all: replay existing IOMMU translations
153
* to all the notifiers registered.
154
*
155
+ * Note: this is not related to record-and-replay functionality.
156
+ *
157
* @iommu_mr: the memory region to observe
158
*/
159
void memory_region_iommu_replay_all(IOMMUMemoryRegion *iommu_mr);
160
@@ -XXX,XX +XXX,XX @@ void memory_region_unregister_iommu_notifier(MemoryRegion *mr,
161
* memory_region_iommu_get_attr: return an IOMMU attr if get_attr() is
162
* defined on the IOMMU.
163
*
164
- * Returns 0 if succeded, error code otherwise.
165
+ * Returns 0 on success, or a negative errno otherwise. In particular,
166
+ * -EINVAL indicates that the IOMMU does not support the requested
167
+ * attribute.
168
*
169
* @iommu_mr: the memory region
170
* @attr: the requested attribute
171
--
58
--
172
2.17.1
59
2.20.1
173
60
174
61
diff view generated by jsdifflib
1
The FRECPX instructions should (like most other floating point operations)
1
Remove the now unused TCG globals cpu_F0s, cpu_F0d, cpu_F1s, cpu_F1d.
2
honour the FPCR.FZ bit which specifies whether input denormals should
2
3
be flushed to zero (or FZ16 for the half-precision version).
3
cpu_M0 is still used by the iwmmxt code, and cpu_V0 and
4
We forgot to implement this, which doesn't affect the results (since
4
cpu_V1 are used by both iwmmxt and Neon.
5
the calculation doesn't actually care about the mantissa bits) but did
6
mean we were failing to set the FPSR.IDC bit.
7
5
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180521172712.19930-1-peter.maydell@linaro.org
8
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190613163917.28589-13-peter.maydell@linaro.org
11
---
10
---
12
target/arm/helper-a64.c | 6 ++++++
11
target/arm/translate.c | 12 ++----------
13
1 file changed, 6 insertions(+)
12
1 file changed, 2 insertions(+), 10 deletions(-)
14
13
15
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-a64.c
16
--- a/target/arm/translate.c
18
+++ b/target/arm/helper-a64.c
17
+++ b/target/arm/translate.c
19
@@ -XXX,XX +XXX,XX @@ float16 HELPER(frecpx_f16)(float16 a, void *fpstp)
18
@@ -XXX,XX +XXX,XX @@ TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
20
return nan;
19
TCGv_i64 cpu_exclusive_addr;
20
TCGv_i64 cpu_exclusive_val;
21
22
-/* FIXME: These should be removed. */
23
-static TCGv_i32 cpu_F0s, cpu_F1s;
24
-static TCGv_i64 cpu_F0d, cpu_F1d;
25
-
26
#include "exec/gen-icount.h"
27
28
static const char * const regnames[] =
29
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
30
dc->base.max_insns = MIN(dc->base.max_insns, bound);
21
}
31
}
22
32
23
+ a = float16_squash_input_denormal(a, fpst);
33
- cpu_F0s = tcg_temp_new_i32();
24
+
34
- cpu_F1s = tcg_temp_new_i32();
25
val16 = float16_val(a);
35
- cpu_F0d = tcg_temp_new_i64();
26
sbit = 0x8000 & val16;
36
- cpu_F1d = tcg_temp_new_i64();
27
exp = extract32(val16, 10, 5);
37
- cpu_V0 = cpu_F0d;
28
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
38
- cpu_V1 = cpu_F1d;
29
return nan;
39
+ cpu_V0 = tcg_temp_new_i64();
30
}
40
+ cpu_V1 = tcg_temp_new_i64();
31
41
/* FIXME: cpu_M0 can probably be the same as cpu_V0. */
32
+ a = float32_squash_input_denormal(a, fpst);
42
cpu_M0 = tcg_temp_new_i64();
33
+
43
}
34
val32 = float32_val(a);
35
sbit = 0x80000000ULL & val32;
36
exp = extract32(val32, 23, 8);
37
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
38
return nan;
39
}
40
41
+ a = float64_squash_input_denormal(a, fpst);
42
+
43
val64 = float64_val(a);
44
sbit = 0x8000000000000000ULL & val64;
45
exp = extract64(float64_val(a), 52, 11);
46
--
44
--
47
2.17.1
45
2.20.1
48
46
49
47
diff view generated by jsdifflib
Deleted patch
1
From: Shannon Zhao <zhaoshenglong@huawei.com>
2
1
3
It forgot to increase clroffset during the loop. So it only clear the
4
first 4 bytes.
5
6
Fixes: 367b9f527becdd20ddf116e17a3c0c2bbc486920
7
Cc: qemu-stable@nongnu.org
8
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
9
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Message-id: 1527047633-12368-1-git-send-email-zhaoshenglong@huawei.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/intc/arm_gicv3_kvm.c | 1 +
15
1 file changed, 1 insertion(+)
16
17
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/arm_gicv3_kvm.c
20
+++ b/hw/intc/arm_gicv3_kvm.c
21
@@ -XXX,XX +XXX,XX @@ static void kvm_dist_putbmp(GICv3State *s, uint32_t offset,
22
if (clroffset != 0) {
23
reg = 0;
24
kvm_gicd_access(s, clroffset, &reg, true);
25
+ clroffset += 4;
26
}
27
reg = *gic_bmp_ptr32(bmp, irq);
28
kvm_gicd_access(s, offset, &reg, true);
29
--
30
2.17.1
31
32
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
In several places cut and paste errors meant we were using the wrong
2
add MemTxAttrs as an argument to the MemoryRegion valid.accepts
2
type for the 'arg' struct in trans_ functions called by the
3
callback. We'll need this for subpage_accepts().
3
decodetree decoder, because we were using the _sp version of the
4
4
struct in the _dp function. These were harmless, because the two
5
We could take the approach we used with the read and write
5
structs were identical and so decodetree made them typedefs of the
6
callbacks and add new a new _with_attrs version, but since there
6
same underlying structure (and we'd have had a compile error if they
7
are so few implementations of the accepts hook we just change
7
were not harmless), but we should clean them up anyway.
8
them all.
9
8
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190614104457.24703-2-peter.maydell@linaro.org
13
Message-id: 20180521140402.23318-9-peter.maydell@linaro.org
14
---
12
---
15
include/exec/memory.h | 3 ++-
13
target/arm/translate-vfp.inc.c | 28 ++++++++++++++--------------
16
exec.c | 9 ++++++---
14
1 file changed, 14 insertions(+), 14 deletions(-)
17
hw/hppa/dino.c | 3 ++-
18
hw/nvram/fw_cfg.c | 12 ++++++++----
19
hw/scsi/esp.c | 3 ++-
20
hw/xen/xen_pt_msi.c | 3 ++-
21
memory.c | 5 +++--
22
7 files changed, 25 insertions(+), 13 deletions(-)
23
15
24
diff --git a/include/exec/memory.h b/include/exec/memory.h
16
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/include/exec/memory.h
18
--- a/target/arm/translate-vfp.inc.c
27
+++ b/include/exec/memory.h
19
+++ b/target/arm/translate-vfp.inc.c
28
@@ -XXX,XX +XXX,XX @@ struct MemoryRegionOps {
20
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
29
* as a machine check exception).
21
return true;
30
*/
31
bool (*accepts)(void *opaque, hwaddr addr,
32
- unsigned size, bool is_write);
33
+ unsigned size, bool is_write,
34
+ MemTxAttrs attrs);
35
} valid;
36
/* Internal implementation constraints: */
37
struct {
38
diff --git a/exec.c b/exec.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/exec.c
41
+++ b/exec.c
42
@@ -XXX,XX +XXX,XX @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
43
}
22
}
44
23
45
static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
24
-static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_sp *a)
46
- unsigned size, bool is_write)
25
+static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
47
+ unsigned size, bool is_write,
48
+ MemTxAttrs attrs)
49
{
26
{
50
return is_write;
27
TCGv_i32 tmp;
28
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
30
return true;
51
}
31
}
52
@@ -XXX,XX +XXX,XX @@ static MemTxResult subpage_write(void *opaque, hwaddr addr,
32
33
-static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_sp *a)
34
+static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
35
{
36
uint32_t offset;
37
TCGv_i32 addr;
38
@@ -XXX,XX +XXX,XX @@ static void gen_VMLA_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
39
tcg_temp_free_i64(tmp);
53
}
40
}
54
41
55
static bool subpage_accepts(void *opaque, hwaddr addr,
42
-static bool trans_VMLA_dp(DisasContext *s, arg_VMLA_sp *a)
56
- unsigned len, bool is_write)
43
+static bool trans_VMLA_dp(DisasContext *s, arg_VMLA_dp *a)
57
+ unsigned len, bool is_write,
58
+ MemTxAttrs attrs)
59
{
44
{
60
subpage_t *subpage = opaque;
45
return do_vfp_3op_dp(s, gen_VMLA_dp, a->vd, a->vn, a->vm, true);
61
#if defined(DEBUG_SUBPAGE)
62
@@ -XXX,XX +XXX,XX @@ static void readonly_mem_write(void *opaque, hwaddr addr,
63
}
46
}
64
47
@@ -XXX,XX +XXX,XX @@ static void gen_VMLS_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
65
static bool readonly_mem_accepts(void *opaque, hwaddr addr,
48
tcg_temp_free_i64(tmp);
66
- unsigned size, bool is_write)
49
}
67
+ unsigned size, bool is_write,
50
68
+ MemTxAttrs attrs)
51
-static bool trans_VMLS_dp(DisasContext *s, arg_VMLS_sp *a)
52
+static bool trans_VMLS_dp(DisasContext *s, arg_VMLS_dp *a)
69
{
53
{
70
return is_write;
54
return do_vfp_3op_dp(s, gen_VMLS_dp, a->vd, a->vn, a->vm, true);
71
}
55
}
72
diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c
56
@@ -XXX,XX +XXX,XX @@ static void gen_VNMLS_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
73
index XXXXXXX..XXXXXXX 100644
57
tcg_temp_free_i64(tmp);
74
--- a/hw/hppa/dino.c
75
+++ b/hw/hppa/dino.c
76
@@ -XXX,XX +XXX,XX @@ static void gsc_to_pci_forwarding(DinoState *s)
77
}
58
}
78
59
79
static bool dino_chip_mem_valid(void *opaque, hwaddr addr,
60
-static bool trans_VNMLS_dp(DisasContext *s, arg_VNMLS_sp *a)
80
- unsigned size, bool is_write)
61
+static bool trans_VNMLS_dp(DisasContext *s, arg_VNMLS_dp *a)
81
+ unsigned size, bool is_write,
82
+ MemTxAttrs attrs)
83
{
62
{
84
switch (addr) {
63
return do_vfp_3op_dp(s, gen_VNMLS_dp, a->vd, a->vn, a->vm, true);
85
case DINO_IAR0:
86
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/hw/nvram/fw_cfg.c
89
+++ b/hw/nvram/fw_cfg.c
90
@@ -XXX,XX +XXX,XX @@ static void fw_cfg_dma_mem_write(void *opaque, hwaddr addr,
91
}
64
}
92
65
@@ -XXX,XX +XXX,XX @@ static void gen_VNMLA_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
93
static bool fw_cfg_dma_mem_valid(void *opaque, hwaddr addr,
66
tcg_temp_free_i64(tmp);
94
- unsigned size, bool is_write)
67
}
95
+ unsigned size, bool is_write,
68
96
+ MemTxAttrs attrs)
69
-static bool trans_VNMLA_dp(DisasContext *s, arg_VNMLA_sp *a)
70
+static bool trans_VNMLA_dp(DisasContext *s, arg_VNMLA_dp *a)
97
{
71
{
98
return !is_write || ((size == 4 && (addr == 0 || addr == 4)) ||
72
return do_vfp_3op_dp(s, gen_VNMLA_dp, a->vd, a->vn, a->vm, true);
99
(size == 8 && addr == 0));
100
}
73
}
101
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VMUL_sp(DisasContext *s, arg_VMUL_sp *a)
102
static bool fw_cfg_data_mem_valid(void *opaque, hwaddr addr,
75
return do_vfp_3op_sp(s, gen_helper_vfp_muls, a->vd, a->vn, a->vm, false);
103
- unsigned size, bool is_write)
76
}
104
+ unsigned size, bool is_write,
77
105
+ MemTxAttrs attrs)
78
-static bool trans_VMUL_dp(DisasContext *s, arg_VMUL_sp *a)
79
+static bool trans_VMUL_dp(DisasContext *s, arg_VMUL_dp *a)
106
{
80
{
107
return addr == 0;
81
return do_vfp_3op_dp(s, gen_helper_vfp_muld, a->vd, a->vn, a->vm, false);
108
}
82
}
109
@@ -XXX,XX +XXX,XX @@ static void fw_cfg_ctl_mem_write(void *opaque, hwaddr addr,
83
@@ -XXX,XX +XXX,XX @@ static void gen_VNMUL_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
84
gen_helper_vfp_negd(vd, vd);
110
}
85
}
111
86
112
static bool fw_cfg_ctl_mem_valid(void *opaque, hwaddr addr,
87
-static bool trans_VNMUL_dp(DisasContext *s, arg_VNMUL_sp *a)
113
- unsigned size, bool is_write)
88
+static bool trans_VNMUL_dp(DisasContext *s, arg_VNMUL_dp *a)
114
+ unsigned size, bool is_write,
115
+ MemTxAttrs attrs)
116
{
89
{
117
return is_write && size == 2;
90
return do_vfp_3op_dp(s, gen_VNMUL_dp, a->vd, a->vn, a->vm, false);
118
}
91
}
119
@@ -XXX,XX +XXX,XX @@ static void fw_cfg_comb_write(void *opaque, hwaddr addr,
92
@@ -XXX,XX +XXX,XX @@ static bool trans_VADD_sp(DisasContext *s, arg_VADD_sp *a)
93
return do_vfp_3op_sp(s, gen_helper_vfp_adds, a->vd, a->vn, a->vm, false);
120
}
94
}
121
95
122
static bool fw_cfg_comb_valid(void *opaque, hwaddr addr,
96
-static bool trans_VADD_dp(DisasContext *s, arg_VADD_sp *a)
123
- unsigned size, bool is_write)
97
+static bool trans_VADD_dp(DisasContext *s, arg_VADD_dp *a)
124
+ unsigned size, bool is_write,
125
+ MemTxAttrs attrs)
126
{
98
{
127
return (size == 1) || (is_write && size == 2);
99
return do_vfp_3op_dp(s, gen_helper_vfp_addd, a->vd, a->vn, a->vm, false);
128
}
100
}
129
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VSUB_sp(DisasContext *s, arg_VSUB_sp *a)
130
index XXXXXXX..XXXXXXX 100644
102
return do_vfp_3op_sp(s, gen_helper_vfp_subs, a->vd, a->vn, a->vm, false);
131
--- a/hw/scsi/esp.c
132
+++ b/hw/scsi/esp.c
133
@@ -XXX,XX +XXX,XX @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
134
}
103
}
135
104
136
static bool esp_mem_accepts(void *opaque, hwaddr addr,
105
-static bool trans_VSUB_dp(DisasContext *s, arg_VSUB_sp *a)
137
- unsigned size, bool is_write)
106
+static bool trans_VSUB_dp(DisasContext *s, arg_VSUB_dp *a)
138
+ unsigned size, bool is_write,
139
+ MemTxAttrs attrs)
140
{
107
{
141
return (size == 1) || (is_write && size == 4);
108
return do_vfp_3op_dp(s, gen_helper_vfp_subd, a->vd, a->vn, a->vm, false);
142
}
109
}
143
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VDIV_sp(DisasContext *s, arg_VDIV_sp *a)
144
index XXXXXXX..XXXXXXX 100644
111
return do_vfp_3op_sp(s, gen_helper_vfp_divs, a->vd, a->vn, a->vm, false);
145
--- a/hw/xen/xen_pt_msi.c
146
+++ b/hw/xen/xen_pt_msi.c
147
@@ -XXX,XX +XXX,XX @@ static uint64_t pci_msix_read(void *opaque, hwaddr addr,
148
}
112
}
149
113
150
static bool pci_msix_accepts(void *opaque, hwaddr addr,
114
-static bool trans_VDIV_dp(DisasContext *s, arg_VDIV_sp *a)
151
- unsigned size, bool is_write)
115
+static bool trans_VDIV_dp(DisasContext *s, arg_VDIV_dp *a)
152
+ unsigned size, bool is_write,
153
+ MemTxAttrs attrs)
154
{
116
{
155
return !(addr & (size - 1));
117
return do_vfp_3op_dp(s, gen_helper_vfp_divd, a->vd, a->vn, a->vm, false);
156
}
118
}
157
diff --git a/memory.c b/memory.c
119
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_sp(DisasContext *s, arg_VFM_sp *a)
158
index XXXXXXX..XXXXXXX 100644
120
return true;
159
--- a/memory.c
160
+++ b/memory.c
161
@@ -XXX,XX +XXX,XX @@ static void unassigned_mem_write(void *opaque, hwaddr addr,
162
}
121
}
163
122
164
static bool unassigned_mem_accepts(void *opaque, hwaddr addr,
123
-static bool trans_VFM_dp(DisasContext *s, arg_VFM_sp *a)
165
- unsigned size, bool is_write)
124
+static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
166
+ unsigned size, bool is_write,
167
+ MemTxAttrs attrs)
168
{
125
{
169
return false;
126
/*
127
* VFNMA : fd = muladd(-fd, fn, fm)
128
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_sp(DisasContext *s, arg_VRINTR_sp *a)
129
return true;
170
}
130
}
171
@@ -XXX,XX +XXX,XX @@ bool memory_region_access_valid(MemoryRegion *mr,
131
172
access_size = MAX(MIN(size, access_size_max), access_size_min);
132
-static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_sp *a)
173
for (i = 0; i < size; i += access_size) {
133
+static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
174
if (!mr->ops->valid.accepts(mr->opaque, addr + i, access_size,
134
{
175
- is_write)) {
135
TCGv_ptr fpst;
176
+ is_write, attrs)) {
136
TCGv_i64 tmp;
177
return false;
137
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_sp(DisasContext *s, arg_VRINTZ_sp *a)
178
}
138
return true;
179
}
139
}
140
141
-static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_sp *a)
142
+static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
143
{
144
TCGv_ptr fpst;
145
TCGv_i64 tmp;
180
--
146
--
181
2.17.1
147
2.20.1
182
148
183
149
diff view generated by jsdifflib
1
In commit f0aff255700 we made cpacr_write() enforce that some CPACR
1
The architecture permits FPUs which have only single-precision
2
bits are RAZ/WI and some are RAO/WI for ARMv7 cores. Unfortunately
2
support, not double-precision; Cortex-M4 and Cortex-M33 are
3
we forgot to also update the register's reset value. The effect
3
both like that. Add the necessary checks on the MVFR0 FPDP
4
was that (a) a guest that read CPACR on reset would not see ones in
4
field so that we UNDEF any double-precision instructions on
5
the RAO bits, and (b) if you did a migration before the guest did
5
CPUs like this.
6
a write to the CPACR then the migration would fail because the
6
7
destination would enforce the RAO bits and then complain that they
7
Note that even if FPDP==0 the insns like VMOV-to/from-gpreg,
8
didn't match the zero value from the source.
8
VLDM/VSTM, VLDR/VSTR which take double precision registers
9
9
still exist.
10
Implement reset for the CPACR using a custom reset function
10
11
that just calls cpacr_write(), to avoid having to duplicate
12
the logic for which bits are RAO.
13
14
This bug would affect migration for TCG CPUs which are ARMv7
15
with VFP but without one of Neon or VFPv3.
16
17
Reported-by: Cédric Le Goater <clg@kaod.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Tested-by: Cédric Le Goater <clg@kaod.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20180522173713.26282-1-peter.maydell@linaro.org
13
Message-id: 20190614104457.24703-3-peter.maydell@linaro.org
21
---
14
---
22
target/arm/helper.c | 10 +++++++++-
15
target/arm/cpu.h | 6 +++
23
1 file changed, 9 insertions(+), 1 deletion(-)
16
target/arm/translate-vfp.inc.c | 84 ++++++++++++++++++++++++++++++++++
24
17
2 files changed, 90 insertions(+)
25
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/helper.c
21
--- a/target/arm/cpu.h
28
+++ b/target/arm/helper.c
22
+++ b/target/arm/cpu.h
29
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
23
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
30
env->cp15.cpacr_el1 = value;
24
return FIELD_EX64(id->mvfr0, MVFR0, FPSHVEC) > 0;
31
}
25
}
32
26
33
+static void cpacr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
27
+static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
34
+{
28
+{
35
+ /* Call cpacr_write() so that we reset with the correct RAO bits set
29
+ /* Return true if CPU supports double precision floating point */
36
+ * for our CPU features.
30
+ return FIELD_EX64(id->mvfr0, MVFR0, FPDP) > 0;
37
+ */
38
+ cpacr_write(env, ri, 0);
39
+}
31
+}
40
+
32
+
41
static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
33
/*
42
bool isread)
34
* We always set the FP and SIMD FP16 fields to indicate identical
43
{
35
* levels of support (assuming SIMD is implemented at all), so
44
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
36
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
45
{ .name = "CPACR", .state = ARM_CP_STATE_BOTH, .opc0 = 3,
37
index XXXXXXX..XXXXXXX 100644
46
.crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access,
38
--- a/target/arm/translate-vfp.inc.c
47
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1),
39
+++ b/target/arm/translate-vfp.inc.c
48
- .resetvalue = 0, .writefn = cpacr_write },
40
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
49
+ .resetfn = cpacr_reset, .writefn = cpacr_write },
41
((a->vm | a->vn | a->vd) & 0x10)) {
50
REGINFO_SENTINEL
42
return false;
51
};
43
}
52
44
+
45
+ if (dp && !dc_isar_feature(aa32_fpdp, s)) {
46
+ return false;
47
+ }
48
+
49
rd = a->vd;
50
rn = a->vn;
51
rm = a->vm;
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VMINMAXNM(DisasContext *s, arg_VMINMAXNM *a)
53
((a->vm | a->vn | a->vd) & 0x10)) {
54
return false;
55
}
56
+
57
+ if (dp && !dc_isar_feature(aa32_fpdp, s)) {
58
+ return false;
59
+ }
60
+
61
rd = a->vd;
62
rn = a->vn;
63
rm = a->vm;
64
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
65
((a->vm | a->vd) & 0x10)) {
66
return false;
67
}
68
+
69
+ if (dp && !dc_isar_feature(aa32_fpdp, s)) {
70
+ return false;
71
+ }
72
+
73
rd = a->vd;
74
rm = a->vm;
75
76
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
77
if (dp && !dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
78
return false;
79
}
80
+
81
+ if (dp && !dc_isar_feature(aa32_fpdp, s)) {
82
+ return false;
83
+ }
84
+
85
rd = a->vd;
86
rm = a->vm;
87
88
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
89
return false;
90
}
91
92
+ if (!dc_isar_feature(aa32_fpdp, s)) {
93
+ return false;
94
+ }
95
+
96
if (!dc_isar_feature(aa32_fpshvec, s) &&
97
(veclen != 0 || s->vec_stride != 0)) {
98
return false;
99
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
100
return false;
101
}
102
103
+ if (!dc_isar_feature(aa32_fpdp, s)) {
104
+ return false;
105
+ }
106
+
107
if (!dc_isar_feature(aa32_fpshvec, s) &&
108
(veclen != 0 || s->vec_stride != 0)) {
109
return false;
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_sp(DisasContext *s, arg_VFM_sp *a)
111
return false;
112
}
113
114
+ if (!dc_isar_feature(aa32_fpdp, s)) {
115
+ return false;
116
+ }
117
+
118
if (!vfp_access_check(s)) {
119
return true;
120
}
121
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
122
return false;
123
}
124
125
+ if (!dc_isar_feature(aa32_fpdp, s)) {
126
+ return false;
127
+ }
128
+
129
if (!dc_isar_feature(aa32_fpshvec, s) &&
130
(veclen != 0 || s->vec_stride != 0)) {
131
return false;
132
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
133
return false;
134
}
135
136
+ if (!dc_isar_feature(aa32_fpdp, s)) {
137
+ return false;
138
+ }
139
+
140
if (!vfp_access_check(s)) {
141
return true;
142
}
143
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
144
return false;
145
}
146
147
+ if (!dc_isar_feature(aa32_fpdp, s)) {
148
+ return false;
149
+ }
150
+
151
if (!vfp_access_check(s)) {
152
return true;
153
}
154
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
155
return false;
156
}
157
158
+ if (!dc_isar_feature(aa32_fpdp, s)) {
159
+ return false;
160
+ }
161
+
162
if (!vfp_access_check(s)) {
163
return true;
164
}
165
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
166
return false;
167
}
168
169
+ if (!dc_isar_feature(aa32_fpdp, s)) {
170
+ return false;
171
+ }
172
+
173
if (!vfp_access_check(s)) {
174
return true;
175
}
176
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
177
return false;
178
}
179
180
+ if (!dc_isar_feature(aa32_fpdp, s)) {
181
+ return false;
182
+ }
183
+
184
if (!vfp_access_check(s)) {
185
return true;
186
}
187
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
188
return false;
189
}
190
191
+ if (!dc_isar_feature(aa32_fpdp, s)) {
192
+ return false;
193
+ }
194
+
195
if (!vfp_access_check(s)) {
196
return true;
197
}
198
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
199
return false;
200
}
201
202
+ if (!dc_isar_feature(aa32_fpdp, s)) {
203
+ return false;
204
+ }
205
+
206
if (!vfp_access_check(s)) {
207
return true;
208
}
209
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
210
return false;
211
}
212
213
+ if (!dc_isar_feature(aa32_fpdp, s)) {
214
+ return false;
215
+ }
216
+
217
if (!vfp_access_check(s)) {
218
return true;
219
}
220
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
221
return false;
222
}
223
224
+ if (!dc_isar_feature(aa32_fpdp, s)) {
225
+ return false;
226
+ }
227
+
228
if (!vfp_access_check(s)) {
229
return true;
230
}
231
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
232
return false;
233
}
234
235
+ if (!dc_isar_feature(aa32_fpdp, s)) {
236
+ return false;
237
+ }
238
+
239
if (!vfp_access_check(s)) {
240
return true;
241
}
242
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
243
return false;
244
}
245
246
+ if (!dc_isar_feature(aa32_fpdp, s)) {
247
+ return false;
248
+ }
249
+
250
if (!vfp_access_check(s)) {
251
return true;
252
}
253
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
254
return false;
255
}
256
257
+ if (!dc_isar_feature(aa32_fpdp, s)) {
258
+ return false;
259
+ }
260
+
261
if (!vfp_access_check(s)) {
262
return true;
263
}
53
--
264
--
54
2.17.1
265
2.20.1
55
266
56
267
diff view generated by jsdifflib