1
Arm patch queue -- these are all bug fix patches but we might
1
Latest arm queue, half minor code cleanups and half minor
2
as well put them in to rc0...
2
bug fixes.
3
3
4
thanks
5
-- PMM
4
-- PMM
6
5
7
The following changes since commit 2c8cfc0b52b5a4d123c26c0b5fdf941be24805be:
6
The following changes since commit 5d0e5694470d2952b4f257bc985cac8c89b4fd92:
8
7
9
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2018-03-19 11:44:26 +0000)
8
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2019-06-17 11:55:14 +0100)
10
9
11
are available in the Git repository at:
10
are available in the Git repository at:
12
11
13
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180319
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190617
14
13
15
for you to fetch changes up to ff72cb6b46b95bb530787add5277c211af3d31c6:
14
for you to fetch changes up to 1120827fa182f0e76226df7ffe7a86598d1df54f:
16
15
17
hw/arm/raspi: Provide spin-loop code for AArch64 CPUs (2018-03-19 18:23:24 +0000)
16
target/arm: Only implement doubles if the FPU supports them (2019-06-17 15:15:06 +0100)
18
17
19
----------------------------------------------------------------
18
----------------------------------------------------------------
20
target-arm queue:
19
target-arm queue:
21
* fsl-imx6: Fix incorrect Ethernet interrupt defines
20
* support large kernel images in bootloader (by avoiding
22
* dump: Update correct kdump phys_base field for AArch64
21
putting the initrd over the top of them)
23
* char: i.MX: Add support for "TX complete" interrupt
22
* correctly disable FPU/DSP in the CPU for the mps2-an521, musca-a boards
24
* bcm2836/raspi: Fix various bugs resulting in panics trying
23
* arm_gicv3: Fix decoding of ID register range
25
to boot a Debian Linux kernel on raspi3
24
* arm_gicv3: GICD_TYPER.SecurityExtn is RAZ if GICD_CTLR.DS == 1
25
* some code cleanups following on from the VFP decodetree conversion
26
* Only implement doubles if the FPU supports them
27
(so we now correctly model Cortex-M4, -M33 as single precision only)
26
28
27
----------------------------------------------------------------
29
----------------------------------------------------------------
28
Andrey Smirnov (2):
30
Peter Maydell (24):
29
char: i.MX: Simplify imx_update()
31
hw/arm/boot: Don't assume RAM starts at address zero
30
char: i.MX: Add support for "TX complete" interrupt
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
31
55
32
Guenter Roeck (1):
56
include/hw/arm/armsse.h | 7 ++
33
fsl-imx6: Swap Ethernet interrupt defines
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(-)
34
73
35
Peter Maydell (9):
36
hw/arm/raspi: Don't do board-setup or secure-boot for raspi3
37
hw/arm/boot: assert that secure_boot and secure_board_setup are false for AArch64
38
hw/arm/boot: If booting a kernel in EL2, set SCR_EL3.HCE
39
hw/arm/bcm2386: Fix parent type of bcm2386
40
hw/arm/bcm2836: Rename bcm2836 type/struct to bcm283x
41
hw/arm/bcm2836: Create proper bcm2837 device
42
hw/arm/bcm2836: Use correct affinity values for BCM2837
43
hw/arm/bcm2836: Hardcode correct CPU type
44
hw/arm/raspi: Provide spin-loop code for AArch64 CPUs
45
46
Wei Huang (1):
47
dump: Update correct kdump phys_base field for AArch64
48
49
include/hw/arm/bcm2836.h | 31 +++++++++++++---
50
include/hw/arm/fsl-imx6.h | 4 +-
51
include/hw/char/imx_serial.h | 3 ++
52
dump.c | 14 +++++--
53
hw/arm/bcm2836.c | 87 +++++++++++++++++++++++++++++++-------------
54
hw/arm/boot.c | 12 ++++++
55
hw/arm/raspi.c | 77 +++++++++++++++++++++++++++++++--------
56
hw/char/imx_serial.c | 44 ++++++++++++++++------
57
hw/net/imx_fec.c | 28 +++++++++++++-
58
9 files changed, 237 insertions(+), 63 deletions(-)
59
diff view generated by jsdifflib
New patch
1
In the Arm kernel/initrd loading code, in some places we make the
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.
1
8
9
Correct the places which make this incorrect assumption.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Tested-by: Mark Rutland <mark.rutland@arm.com>
14
Message-id: 20190516144733.32399-2-peter.maydell@linaro.org
15
---
16
hw/arm/boot.c | 9 ++++-----
17
1 file changed, 4 insertions(+), 5 deletions(-)
18
19
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/boot.c
22
+++ b/hw/arm/boot.c
23
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
24
int elf_machine;
25
hwaddr entry;
26
static const ARMInsnFixup *primary_loader;
27
+ uint64_t ram_end = info->loader_start + info->ram_size;
28
29
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
30
primary_loader = bootloader_aarch64;
31
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
32
/* 32-bit ARM */
33
entry = info->loader_start + KERNEL_LOAD_ADDR;
34
kernel_size = load_image_targphys_as(info->kernel_filename, entry,
35
- info->ram_size - KERNEL_LOAD_ADDR,
36
- as);
37
+ ram_end - KERNEL_LOAD_ADDR, as);
38
is_linux = 1;
39
}
40
if (kernel_size < 0) {
41
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
42
if (info->initrd_filename) {
43
initrd_size = load_ramdisk_as(info->initrd_filename,
44
info->initrd_start,
45
- info->ram_size - info->initrd_start,
46
- as);
47
+ ram_end - info->initrd_start, as);
48
if (initrd_size < 0) {
49
initrd_size = load_image_targphys_as(info->initrd_filename,
50
info->initrd_start,
51
- info->ram_size -
52
+ ram_end -
53
info->initrd_start,
54
as);
55
}
56
--
57
2.20.1
58
59
diff view generated by jsdifflib
1
If we're directly booting a Linux kernel and the CPU supports both
1
We calculate the locations in memory where we want to put the
2
EL3 and EL2, we start the kernel in EL2, as it expects. We must also
2
initrd and the DTB based on the size of the kernel, since they
3
set the SCR_EL3.HCE bit in this situation, so that the HVC
3
come after it. Add some explicit checks that these aren't off the
4
instruction is enabled rather than UNDEFing. Otherwise at least some
4
end of RAM entirely.
5
kernels will panic when trying to initialize KVM in the guest.
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.)
6
9
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20180313153458.26822-4-peter.maydell@linaro.org
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Tested-by: Mark Rutland <mark.rutland@arm.com>
13
Message-id: 20190516144733.32399-3-peter.maydell@linaro.org
9
---
14
---
10
hw/arm/boot.c | 5 +++++
15
hw/arm/boot.c | 23 +++++++++++++++++++++++
11
1 file changed, 5 insertions(+)
16
1 file changed, 23 insertions(+)
12
17
13
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
18
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/boot.c
20
--- a/hw/arm/boot.c
16
+++ b/hw/arm/boot.c
21
+++ b/hw/arm/boot.c
17
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
22
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
18
assert(!info->secure_board_setup);
23
error_report("could not load kernel '%s'", info->kernel_filename);
19
}
24
exit(1);
20
25
}
21
+ if (arm_feature(env, ARM_FEATURE_EL2)) {
22
+ /* If we have EL2 then Linux expects the HVC insn to work */
23
+ env->cp15.scr_el3 |= SCR_HCE;
24
+ }
25
+
26
+
26
/* Set to non-secure if not a secure boot */
27
+ if (kernel_size > info->ram_size) {
27
if (!info->secure_boot &&
28
+ error_report("kernel '%s' is too large to fit in RAM "
28
(cs != first_cpu || !info->secure_board_setup)) {
29
+ "(kernel size %d, RAM size %" PRId64 ")",
30
+ info->kernel_filename, kernel_size, info->ram_size);
31
+ exit(1);
32
+ }
33
+
34
info->entry = entry;
35
if (is_linux) {
36
uint32_t fixupcontext[FIXUP_MAX];
37
38
if (info->initrd_filename) {
39
+
40
+ if (info->initrd_start >= ram_end) {
41
+ error_report("not enough space after kernel to load initrd");
42
+ exit(1);
43
+ }
44
+
45
initrd_size = load_ramdisk_as(info->initrd_filename,
46
info->initrd_start,
47
ram_end - info->initrd_start, as);
48
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
49
info->initrd_filename);
50
exit(1);
51
}
52
+ if (info->initrd_start + initrd_size > info->ram_size) {
53
+ error_report("could not load initrd '%s': "
54
+ "too big to fit into RAM after the kernel",
55
+ info->initrd_filename);
56
+ }
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 {
29
--
71
--
30
2.16.2
72
2.20.1
31
73
32
74
diff view generated by jsdifflib
1
Add some assertions that if we're about to boot an AArch64 kernel,
1
We currently put the initrd at the smaller of:
2
the board code has not mistakenly set either secure_boot or
2
* 128MB into RAM
3
secure_board_setup. It doesn't make sense to set secure_boot,
3
* halfway into the RAM
4
because all AArch64 kernels must be booted in non-secure mode.
4
(with the dtb following it).
5
5
6
It might in theory make sense to set secure_board_setup, but
6
However for large kernels this might mean that the kernel
7
we don't currently support that, because only the AArch32
7
overlaps the initrd. For some kinds of kernel (self-decompressing
8
bootloader[] code calls this hook; bootloader_aarch64[] does not.
8
32-bit kernels, and ELF images with a BSS section at the end)
9
Since we don't have a current need for this functionality, just
9
we don't know the exact size, but even there we have a
10
assert that we don't try to use it. If it's needed we'll add
10
minimum size. Put the initrd at least further into RAM than
11
it later.
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.
12
13
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Message-id: 20180313153458.26822-3-peter.maydell@linaro.org
16
Tested-by: Mark Rutland <mark.rutland@arm.com>
17
Message-id: 20190516144733.32399-4-peter.maydell@linaro.org
16
---
18
---
17
hw/arm/boot.c | 7 +++++++
19
hw/arm/boot.c | 34 ++++++++++++++++++++--------------
18
1 file changed, 7 insertions(+)
20
1 file changed, 20 insertions(+), 14 deletions(-)
19
21
20
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
22
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
21
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/boot.c
24
--- a/hw/arm/boot.c
23
+++ b/hw/arm/boot.c
25
+++ b/hw/arm/boot.c
24
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
26
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
25
} else {
27
if (info->nb_cpus == 0)
26
env->pstate = PSTATE_MODE_EL1h;
28
info->nb_cpus = 1;
27
}
29
28
+ /* AArch64 kernels never boot in secure mode */
30
- /*
29
+ assert(!info->secure_boot);
31
- * We want to put the initrd far enough into RAM that when the
30
+ /* This hook is only supported for AArch32 currently:
32
- * kernel is uncompressed it will not clobber the initrd. However
31
+ * bootloader_aarch64[] will not call the hook, and
33
- * on boards without much RAM we must ensure that we still leave
32
+ * the code above has already dropped us into EL2 or EL1.
34
- * enough room for a decent sized initrd, and on boards with large
33
+ */
35
- * amounts of RAM we must avoid the initrd being so far up in RAM
34
+ assert(!info->secure_board_setup);
36
- * that it is outside lowmem and inaccessible to the kernel.
35
}
37
- * So for boards with less than 256MB of RAM we put the initrd
36
38
- * halfway into RAM, and for boards with 256MB of RAM or more we put
37
/* Set to non-secure if not a secure boot */
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;
51
+
52
+ /*
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];
73
38
--
74
--
39
2.16.2
75
2.20.1
40
76
41
77
diff view generated by jsdifflib
New patch
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.
1
8
9
This means that we should be able to reliably load kernel images
10
which are larger than 128MB without accidentally putting the
11
initrd or dtb in locations that clash with the kernel itself.
12
13
Fixes: https://bugs.launchpad.net/qemu/+bug/1823998
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
19
---
20
hw/arm/boot.c | 17 +++++++++++++++--
21
1 file changed, 15 insertions(+), 2 deletions(-)
22
23
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/boot.c
26
+++ b/hw/arm/boot.c
27
@@ -XXX,XX +XXX,XX @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base,
28
hwaddr *entry, AddressSpace *as)
29
{
30
hwaddr kernel_load_offset = KERNEL64_LOAD_ADDR;
31
+ uint64_t kernel_size = 0;
32
uint8_t *buffer;
33
int size;
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.
55
+ */
56
+ if (kernel_size == 0) {
57
+ kernel_size = size;
58
+ }
59
+
60
*entry = mem_base + kernel_load_offset;
61
rom_add_blob_fixed_as(filename, buffer, size, *entry, as);
62
63
g_free(buffer);
64
65
- return size;
66
+ return kernel_size;
67
}
68
69
static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
70
--
71
2.20.1
72
73
diff view generated by jsdifflib
New patch
1
1
Allow VFP and neon to be disabled via a CPU property. As with
2
the "pmu" property, we only allow these features to be removed
3
from CPUs which have it by default, not added to CPUs which
4
don't have it.
5
6
The primary motivation here is to be able to optionally
7
create Cortex-M33 CPUs with no FPU, but we provide switches
8
for both VFP and Neon because the two interact:
9
* AArch64 can't have one without the other
10
* Some ID register fields only change if both are disabled
11
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
16
---
17
target/arm/cpu.h | 4 ++
18
target/arm/cpu.c | 150 +++++++++++++++++++++++++++++++++++++++++++++--
19
2 files changed, 148 insertions(+), 6 deletions(-)
20
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
24
+++ b/target/arm/cpu.h
25
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
26
bool has_el3;
27
/* CPU has PMU (Performance Monitor Unit) */
28
bool has_pmu;
29
+ /* CPU has VFP */
30
+ bool has_vfp;
31
+ /* CPU has Neon */
32
+ bool has_neon;
33
34
/* CPU has memory protection unit */
35
bool has_mpu;
36
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/cpu.c
39
+++ b/target/arm/cpu.c
40
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_cfgend_property =
41
static Property arm_cpu_has_pmu_property =
42
DEFINE_PROP_BOOL("pmu", ARMCPU, has_pmu, true);
43
44
+static Property arm_cpu_has_vfp_property =
45
+ DEFINE_PROP_BOOL("vfp", ARMCPU, has_vfp, true);
46
+
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);
225
--
226
2.20.1
227
228
diff view generated by jsdifflib
New patch
1
Allow the DSP extension to be disabled via a CPU property for
2
M-profile CPUs. (A and R-profile CPUs don't have this extension
3
as a defined separate optional architecture extension, so
4
they don't need the property.)
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20190517174046.11146-3-peter.maydell@linaro.org
10
---
11
target/arm/cpu.h | 2 ++
12
target/arm/cpu.c | 29 +++++++++++++++++++++++++++++
13
2 files changed, 31 insertions(+)
14
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
20
bool has_vfp;
21
/* CPU has Neon */
22
bool has_neon;
23
+ /* CPU has M-profile DSP extension */
24
+ bool has_dsp;
25
26
/* CPU has memory protection unit */
27
bool has_mpu;
28
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.c
31
+++ b/target/arm/cpu.c
32
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_has_vfp_property =
33
static Property arm_cpu_has_neon_property =
34
DEFINE_PROP_BOOL("neon", ARMCPU, has_neon, true);
35
36
+static Property arm_cpu_has_dsp_property =
37
+ DEFINE_PROP_BOOL("dsp", ARMCPU, has_dsp, true);
38
+
39
static Property arm_cpu_has_mpu_property =
40
DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true);
41
42
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
43
}
44
}
45
46
+ if (arm_feature(&cpu->env, ARM_FEATURE_M) &&
47
+ arm_feature(&cpu->env, ARM_FEATURE_THUMB_DSP)) {
48
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_has_dsp_property,
49
+ &error_abort);
50
+ }
51
+
52
if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) {
53
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property,
54
&error_abort);
55
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
56
cpu->isar.mvfr0 = u;
57
}
58
59
+ if (arm_feature(env, ARM_FEATURE_M) && !cpu->has_dsp) {
60
+ uint32_t u;
61
+
62
+ unset_feature(env, ARM_FEATURE_THUMB_DSP);
63
+
64
+ u = cpu->isar.id_isar1;
65
+ u = FIELD_DP32(u, ID_ISAR1, EXTEND, 1);
66
+ cpu->isar.id_isar1 = u;
67
+
68
+ u = cpu->isar.id_isar2;
69
+ u = FIELD_DP32(u, ID_ISAR2, MULTU, 1);
70
+ u = FIELD_DP32(u, ID_ISAR2, MULTS, 1);
71
+ cpu->isar.id_isar2 = u;
72
+
73
+ u = cpu->isar.id_isar3;
74
+ u = FIELD_DP32(u, ID_ISAR3, SIMD, 1);
75
+ u = FIELD_DP32(u, ID_ISAR3, SATURATE, 0);
76
+ cpu->isar.id_isar3 = u;
77
+ }
78
+
79
/* Some features automatically imply others: */
80
if (arm_feature(env, ARM_FEATURE_V8)) {
81
if (arm_feature(env, ARM_FEATURE_M)) {
82
--
83
2.20.1
84
85
diff view generated by jsdifflib
New patch
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.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20190517174046.11146-4-peter.maydell@linaro.org
9
---
10
include/hw/arm/armv7m.h | 4 ++++
11
hw/arm/armv7m.c | 18 ++++++++++++++++++
12
2 files changed, 22 insertions(+)
13
14
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/armv7m.h
17
+++ b/include/hw/arm/armv7m.h
18
@@ -XXX,XX +XXX,XX @@ typedef struct {
19
* devices will be automatically layered on top of this view.)
20
* + Property "idau": IDAU interface (forwarded to CPU object)
21
* + Property "init-svtor": secure VTOR reset value (forwarded to CPU object)
22
+ * + Property "vfp": enable VFP (forwarded to CPU object)
23
+ * + Property "dsp": enable DSP (forwarded to CPU object)
24
* + Property "enable-bitband": expose bitbanded IO
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
}
43
}
44
+ if (object_property_find(OBJECT(s->cpu), "vfp", NULL)) {
45
+ object_property_set_bool(OBJECT(s->cpu), s->vfp,
46
+ "vfp", &err);
47
+ if (err != NULL) {
48
+ error_propagate(errp, err);
49
+ return;
50
+ }
51
+ }
52
+ if (object_property_find(OBJECT(s->cpu), "dsp", NULL)) {
53
+ object_property_set_bool(OBJECT(s->cpu), s->dsp,
54
+ "dsp", &err);
55
+ if (err != NULL) {
56
+ error_propagate(errp, err);
57
+ return;
58
+ }
59
+ }
60
61
/*
62
* Tell the CPU where the NVIC is; it will fail realize if it doesn't
63
@@ -XXX,XX +XXX,XX @@ static Property armv7m_properties[] = {
64
DEFINE_PROP_BOOL("enable-bitband", ARMv7MState, enable_bitband, false),
65
DEFINE_PROP_BOOL("start-powered-off", ARMv7MState, start_powered_off,
66
false),
67
+ DEFINE_PROP_BOOL("vfp", ARMv7MState, vfp, true),
68
+ DEFINE_PROP_BOOL("dsp", ARMv7MState, dsp, true),
69
DEFINE_PROP_END_OF_LIST(),
70
};
71
72
--
73
2.20.1
74
75
diff view generated by jsdifflib
1
The BCM2837 sets the Aff1 field of the MPIDR affinity values for the
1
The SSE-200 hardware has configurable integration settings which
2
CPUs to 0, whereas the BCM2836 uses 0xf. Set this correctly, as it
2
determine whether its two CPUs have the FPU and DSP:
3
is required for Linux to boot.
3
* CPU0_FPU (default 0)
4
* CPU0_DSP (default 0)
5
* CPU1_FPU (default 1)
6
* CPU1_DSP (default 1)
7
8
Similarly, the IoTKit has settings for its single CPU:
9
* CPU0_FPU (default 1)
10
* CPU0_DSP (default 1)
11
12
Of our four boards that use either the IoTKit or the SSE-200:
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.
4
26
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
28
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
29
Message-id: 20190517174046.11146-5-peter.maydell@linaro.org
8
Message-id: 20180313153458.26822-8-peter.maydell@linaro.org
9
---
30
---
10
hw/arm/bcm2836.c | 11 +++++++----
31
include/hw/arm/armsse.h | 7 +++++
11
1 file changed, 7 insertions(+), 4 deletions(-)
32
hw/arm/armsse.c | 58 ++++++++++++++++++++++++++++++++---------
33
hw/arm/musca.c | 8 ++++++
34
3 files changed, 61 insertions(+), 12 deletions(-)
12
35
13
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
36
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
14
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/bcm2836.c
38
--- a/include/hw/arm/armsse.h
16
+++ b/hw/arm/bcm2836.c
39
+++ b/include/hw/arm/armsse.h
17
@@ -XXX,XX +XXX,XX @@
40
@@ -XXX,XX +XXX,XX @@
18
41
* address of each SRAM bank (and thus the total amount of internal SRAM)
19
struct BCM283XInfo {
42
* + QOM property "init-svtor" sets the initial value of the CPU SVTOR register
20
const char *name;
43
* (where it expects to load the PC and SP from the vector table on reset)
21
+ int clusterid;
44
+ * + QOM properties "CPU0_FPU", "CPU0_DSP", "CPU1_FPU" and "CPU1_DSP" which
45
+ * set whether the CPUs have the FPU and DSP features present. The default
46
+ * (matching the hardware) is that for CPU0 in an IoTKit and CPU1 in an
47
+ * SSE-200 both are present; CPU0 in an SSE-200 has neither.
48
+ * Since the IoTKit has only one CPU, it does not have the CPU1_* properties.
49
* + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts for CPU 0,
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
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/armsse.c
64
+++ b/hw/arm/armsse.c
65
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
66
bool has_cachectrl;
67
bool has_cpusecctrl;
68
bool has_cpuid;
69
+ Property *props;
70
+};
71
+
72
+static Property iotkit_properties[] = {
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()
22
};
96
};
23
97
24
static const BCM283XInfo bcm283x_socs[] = {
98
static const ARMSSEInfo armsse_variants[] = {
25
{
99
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
26
.name = TYPE_BCM2836,
100
.has_cachectrl = false,
27
+ .clusterid = 0xf,
101
.has_cpusecctrl = false,
102
.has_cpuid = false,
103
+ .props = iotkit_properties,
28
},
104
},
29
{
105
{
30
.name = TYPE_BCM2837,
106
.name = TYPE_SSE200,
31
+ .clusterid = 0x0,
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,
32
},
112
},
33
};
113
};
34
114
35
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
115
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
36
static void bcm2836_realize(DeviceState *dev, Error **errp)
116
return;
117
}
118
}
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)
37
{
151
{
38
BCM283XState *s = BCM283X(dev);
152
ARMSSE *s = ARMSSE(dev);
39
+ BCM283XClass *bc = BCM283X_GET_CLASS(dev);
153
@@ -XXX,XX +XXX,XX @@ static void armsse_class_init(ObjectClass *klass, void *data)
40
+ const BCM283XInfo *info = bc->info;
154
DeviceClass *dc = DEVICE_CLASS(klass);
41
Object *obj;
155
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
42
Error *err = NULL;
156
ARMSSEClass *asc = ARMSSE_CLASS(klass);
43
int n;
157
+ const ARMSSEInfo *info = data;
44
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
158
45
qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
159
dc->realize = armsse_realize;
46
160
dc->vmsd = &armsse_vmstate;
47
for (n = 0; n < BCM283X_NCPUS; n++) {
161
- dc->props = armsse_properties;
48
- /* Mirror bcm2836, which has clusterid set to 0xf
162
+ dc->props = info->props;
49
- * TODO: this should be converted to a property of ARM_CPU
163
dc->reset = armsse_reset;
50
- */
164
iic->check = armsse_idau_check;
51
- s->cpus[n].mp_affinity = 0xF00 | n;
165
- asc->info = data;
52
+ /* TODO: this should be converted to a property of ARM_CPU */
166
+ asc->info = info;
53
+ s->cpus[n].mp_affinity = (info->clusterid << 8) | n;
167
}
54
168
55
/* set periphbase/CBAR value for CPU-local registers */
169
static const TypeInfo armsse_info = {
56
object_property_set_int(OBJECT(&s->cpus[n]),
170
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
171
index XXXXXXX..XXXXXXX 100644
172
--- a/hw/arm/musca.c
173
+++ b/hw/arm/musca.c
174
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
175
qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
176
qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
177
qdev_prop_set_uint32(ssedev, "MAINCLK", SYSCLK_FRQ);
178
+ /*
179
+ * Musca-A takes the default SSE-200 FPU/DSP settings (ie no for
180
+ * CPU0 and yes for CPU1); Musca-B1 explicitly enables them for CPU0.
181
+ */
182
+ if (mmc->type == MUSCA_B1) {
183
+ qdev_prop_set_bit(ssedev, "CPU0_FPU", true);
184
+ qdev_prop_set_bit(ssedev, "CPU0_DSP", true);
185
+ }
186
object_property_set_bool(OBJECT(&mms->sse), true, "realized",
187
&error_fatal);
188
57
--
189
--
58
2.16.2
190
2.20.1
59
191
60
192
diff view generated by jsdifflib
New patch
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.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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(-)
12
13
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/arm_gicv3_dist.c
16
+++ b/hw/intc/arm_gicv3_dist.c
17
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicd_readl(GICv3State *s, hwaddr offset,
18
}
19
return MEMTX_OK;
20
}
21
- case GICD_IDREGS ... GICD_IDREGS + 0x1f:
22
+ case GICD_IDREGS ... GICD_IDREGS + 0x2f:
23
/* ID registers */
24
*data = gicv3_idreg(offset - GICD_IDREGS);
25
return MEMTX_OK;
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 "
57
--
58
2.20.1
59
60
diff view generated by jsdifflib
New patch
1
The GICv3 specification says that the GICD_TYPER.SecurityExtn bit
2
is RAZ if GICD_CTLR.DS is 1. We were incorrectly making it RAZ
3
if the security extension is unsupported. "Security extension
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.
1
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20190524124248.28394-3-peter.maydell@linaro.org
10
---
11
hw/intc/arm_gicv3_dist.c | 8 +++++++-
12
1 file changed, 7 insertions(+), 1 deletion(-)
13
14
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/arm_gicv3_dist.c
17
+++ b/hw/intc/arm_gicv3_dist.c
18
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicd_readl(GICv3State *s, hwaddr offset,
19
* ITLinesNumber == (num external irqs / 32) - 1
20
*/
21
int itlinesnumber = ((s->num_irq - GIC_INTERNAL) / 32) - 1;
22
+ /*
23
+ * SecurityExtn must be RAZ if GICD_CTLR.DS == 1, and
24
+ * "security extensions not supported" always implies DS == 1,
25
+ * so we only need to check the DS bit.
26
+ */
27
+ bool sec_extn = !(s->gicd_ctlr & GICD_CTLR_DS);
28
29
- *data = (1 << 25) | (1 << 24) | (s->security_extn << 10) |
30
+ *data = (1 << 25) | (1 << 24) | (sec_extn << 10) |
31
(0xf << 19) | itlinesnumber;
32
return MEMTX_OK;
33
}
34
--
35
2.20.1
36
37
diff view generated by jsdifflib
New patch
1
We want to use vfp_expand_imm() in the AArch32 VFP decode;
2
move it from the a64-only header/source file to the
3
AArch32 one (which is always compiled even for AArch64).
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190613163917.28589-2-peter.maydell@linaro.org
9
---
10
target/arm/translate-a64.h | 1 -
11
target/arm/translate.h | 7 +++++++
12
target/arm/translate-a64.c | 32 --------------------------------
13
target/arm/translate-vfp.inc.c | 33 +++++++++++++++++++++++++++++++++
14
4 files changed, 40 insertions(+), 33 deletions(-)
15
16
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.h
19
+++ b/target/arm/translate-a64.h
20
@@ -XXX,XX +XXX,XX @@ void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v);
21
TCGv_ptr get_fpstatus_ptr(bool);
22
bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
23
unsigned int imms, unsigned int immr);
24
-uint64_t vfp_expand_imm(int size, uint8_t imm8);
25
bool sve_access_check(DisasContext *s);
26
27
/* We should have at some point before trying to access an FP register
28
diff --git a/target/arm/translate.h b/target/arm/translate.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate.h
31
+++ b/target/arm/translate.h
32
@@ -XXX,XX +XXX,XX @@ static inline void gen_ss_advance(DisasContext *s)
33
}
34
}
35
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
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate-a64.c
49
+++ b/target/arm/translate-a64.c
50
@@ -XXX,XX +XXX,XX @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
51
}
52
}
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
133
--
134
2.20.1
135
136
diff view generated by jsdifflib
New patch
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.
1
4
5
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
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(-)
14
15
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-vfp.inc.c
18
+++ b/target/arm/translate-vfp.inc.c
19
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
20
uint32_t delta_d = 0;
21
int veclen = s->vec_len;
22
TCGv_i32 fd;
23
- uint32_t n, i, vd;
24
+ uint32_t vd;
25
26
vd = a->vd;
27
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
29
}
30
}
31
32
- n = (a->imm4h << 28) & 0x80000000;
33
- i = ((a->imm4h << 4) & 0x70) | a->imm4l;
34
- if (i & 0x40) {
35
- i |= 0x780;
36
- } else {
37
- i |= 0x800;
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
}
58
}
59
60
- n = (a->imm4h << 28) & 0x80000000;
61
- i = ((a->imm4h << 4) & 0x70) | a->imm4l;
62
- if (i & 0x40) {
63
- i |= 0x3f80;
64
- } else {
65
- i |= 0x4000;
66
- }
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
103
--
104
2.20.1
105
106
diff view generated by jsdifflib
New patch
1
Where Neon instructions are floating point operations, we
2
mostly use the old VFP utility functions like gen_vfp_abs()
3
which work on the TCG globals cpu_F0s and cpu_F1s. The
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.
1
8
9
Switch NEON_2RM_VABS_F away from using cpu_F0s, and
10
update neon_2rm_is_float_op() accordingly.
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Message-id: 20190613163917.28589-4-peter.maydell@linaro.org
16
---
17
target/arm/translate.c | 19 ++++++++-----------
18
1 file changed, 8 insertions(+), 11 deletions(-)
19
20
diff --git a/target/arm/translate.c b/target/arm/translate.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/translate.c
23
+++ b/target/arm/translate.c
24
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
25
return statusptr;
26
}
27
28
-static inline void gen_vfp_abs(int dp)
29
-{
30
- if (dp)
31
- gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
32
- else
33
- gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
34
-}
35
-
36
static inline void gen_vfp_neg(int dp)
37
{
38
if (dp)
39
@@ -XXX,XX +XXX,XX @@ static const uint8_t neon_3r_sizes[] = {
40
41
static int neon_2rm_is_float_op(int op)
42
{
43
- /* Return true if this neon 2reg-misc op is float-to-float */
44
- return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
45
+ /*
46
+ * Return true if this neon 2reg-misc op is float-to-float.
47
+ * This is not a property of the operation but of our code --
48
+ * what we are asking here is "does the code for this case in
49
+ * the Neon for-each-pass loop use cpu_F0s?".
50
+ */
51
+ return (op == NEON_2RM_VNEG_F ||
52
(op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
53
op == NEON_2RM_VRINTM ||
54
(op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
55
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
56
break;
57
}
58
case NEON_2RM_VABS_F:
59
- gen_vfp_abs(0);
60
+ gen_helper_vfp_abss(tmp, tmp);
61
break;
62
case NEON_2RM_VNEG_F:
63
gen_vfp_neg(0);
64
--
65
2.20.1
66
67
diff view generated by jsdifflib
1
The TypeInfo and state struct for bcm2386 disagree about what the
1
Switch NEON_2RM_VABS_F away from using cpu_F0s.
2
parent class is -- the TypeInfo says it's TYPE_SYS_BUS_DEVICE,
3
but the BCM2386State struct only defines the parent_obj field
4
as DeviceState. This would have caused problems if anything
5
actually tried to treat the object as a TYPE_SYS_BUS_DEVICE.
6
Fix the TypeInfo to use TYPE_DEVICE as the parent, since we don't
7
need any of the additional functionality TYPE_SYS_BUS_DEVICE
8
provides.
9
2
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Message-id: 20180313153458.26822-5-peter.maydell@linaro.org
6
Message-id: 20190613163917.28589-5-peter.maydell@linaro.org
14
---
7
---
15
hw/arm/bcm2836.c | 2 +-
8
target/arm/translate.c | 13 ++-----------
16
1 file changed, 1 insertion(+), 1 deletion(-)
9
1 file changed, 2 insertions(+), 11 deletions(-)
17
10
18
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/bcm2836.c
13
--- a/target/arm/translate.c
21
+++ b/hw/arm/bcm2836.c
14
+++ b/target/arm/translate.c
22
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
15
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
23
16
return statusptr;
24
static const TypeInfo bcm2836_type_info = {
17
}
25
.name = TYPE_BCM2836,
18
26
- .parent = TYPE_SYS_BUS_DEVICE,
19
-static inline void gen_vfp_neg(int dp)
27
+ .parent = TYPE_DEVICE,
20
-{
28
.instance_size = sizeof(BCM2836State),
21
- if (dp)
29
.instance_init = bcm2836_init,
22
- gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
30
.class_init = bcm2836_class_init,
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);
31
--
49
--
32
2.16.2
50
2.20.1
33
51
34
52
diff view generated by jsdifflib
1
The raspi3 has AArch64 CPUs, which means that our smpboot
1
Switch NEON_2RM_VRINT* away from using cpu_F0s.
2
code for keeping the secondary CPUs in a pen needs to have
3
a version for A64 as well as A32. Without this, the
4
secondary CPUs go into an infinite loop of taking undefined
5
instruction exceptions.
6
2
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180313153458.26822-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
hw/arm/raspi.c | 41 ++++++++++++++++++++++++++++++++++++++++-
8
target/arm/translate.c | 8 +++-----
12
1 file changed, 40 insertions(+), 1 deletion(-)
9
1 file changed, 3 insertions(+), 5 deletions(-)
13
10
14
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.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/hw/arm/raspi.c
13
--- a/target/arm/translate.c
17
+++ b/hw/arm/raspi.c
14
+++ b/target/arm/translate.c
18
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
19
#define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */
16
* what we are asking here is "does the code for this case in
20
#define FIRMWARE_ADDR_2 0x8000 /* Pi 2 loads kernel.img here by default */
17
* the Neon for-each-pass loop use cpu_F0s?".
21
#define FIRMWARE_ADDR_3 0x80000 /* Pi 3 loads kernel.img here by default */
18
*/
22
+#define SPINTABLE_ADDR 0xd8 /* Pi 3 bootloader spintable */
19
- return ((op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
23
20
- op == NEON_2RM_VRINTM ||
24
/* Table of Linux board IDs for different Pi versions */
21
- (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
25
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
22
+ return ((op >= NEON_2RM_VCVTAU && op <= NEON_2RM_VCVTMS) ||
26
@@ -XXX,XX +XXX,XX @@ static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
23
op >= NEON_2RM_VRECPE_F);
27
info->smp_loader_start);
28
}
24
}
29
25
30
+static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
26
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
31
+{
27
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
32
+ /* Unlike the AArch32 version we don't need to call the board setup hook.
28
gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
33
+ * The mechanism for doing the spin-table is also entirely different.
29
cpu_env);
34
+ * We must have four 64-bit fields at absolute addresses
30
- gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
35
+ * 0xd8, 0xe0, 0xe8, 0xf0 in RAM, which are the flag variables for
31
+ gen_helper_rints(tmp, tmp, fpstatus);
36
+ * our CPUs, and which we must ensure are zero initialized before
32
gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
37
+ * the primary CPU goes into the kernel. We put these variables inside
33
cpu_env);
38
+ * a rom blob, so that the reset for ROM contents zeroes them for us.
34
tcg_temp_free_ptr(fpstatus);
39
+ */
35
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
40
+ static const uint32_t smpboot[] = {
36
case NEON_2RM_VRINTX:
41
+ 0xd2801b05, /* mov x5, 0xd8 */
37
{
42
+ 0xd53800a6, /* mrs x6, mpidr_el1 */
38
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
43
+ 0x924004c6, /* and x6, x6, #0x3 */
39
- gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
44
+ 0xd503205f, /* spin: wfe */
40
+ gen_helper_rints_exact(tmp, tmp, fpstatus);
45
+ 0xf86678a4, /* ldr x4, [x5,x6,lsl #3] */
41
tcg_temp_free_ptr(fpstatus);
46
+ 0xb4ffffc4, /* cbz x4, spin */
42
break;
47
+ 0xd2800000, /* mov x0, #0x0 */
43
}
48
+ 0xd2800001, /* mov x1, #0x0 */
49
+ 0xd2800002, /* mov x2, #0x0 */
50
+ 0xd2800003, /* mov x3, #0x0 */
51
+ 0xd61f0080, /* br x4 */
52
+ };
53
+
54
+ static const uint64_t spintables[] = {
55
+ 0, 0, 0, 0
56
+ };
57
+
58
+ rom_add_blob_fixed("raspi_smpboot", smpboot, sizeof(smpboot),
59
+ info->smp_loader_start);
60
+ rom_add_blob_fixed("raspi_spintables", spintables, sizeof(spintables),
61
+ SPINTABLE_ADDR);
62
+}
63
+
64
static void write_board_setup(ARMCPU *cpu, const struct arm_boot_info *info)
65
{
66
arm_write_secure_board_setup_dummy_smc(cpu, info, MVBAR_ADDR);
67
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
68
/* Pi2 and Pi3 requires SMP setup */
69
if (version >= 2) {
70
binfo.smp_loader_start = SMPBOOT_ADDR;
71
- binfo.write_secondary_boot = write_smpboot;
72
+ if (version == 2) {
73
+ binfo.write_secondary_boot = write_smpboot;
74
+ } else {
75
+ binfo.write_secondary_boot = write_smpboot64;
76
+ }
77
binfo.secondary_cpu_reset_hook = reset_secondary;
78
}
79
80
--
44
--
81
2.16.2
45
2.20.1
82
46
83
47
diff view generated by jsdifflib
1
The bcm2837 is pretty similar to the bcm2836, but it does have
1
Stop using cpu_F0s for the NEON_2RM_VCVT[ANPM][US] ops.
2
some differences. Notably, the MPIDR affinity aff1 values it
3
sets for the CPUs are 0x0, rather than the 0xf that the bcm2836
4
uses, and if this is wrong Linux will not boot.
5
6
Rather than trying to have one device with properties that
7
configure it differently for the two cases, create two
8
separate QOM devices for the two SoCs. We use the same approach
9
as hw/arm/aspeed_soc.c and share code and have a data table
10
that might differ per-SoC. For the moment the two types don't
11
actually have different behaviour.
12
2
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20180313153458.26822-7-peter.maydell@linaro.org
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190613163917.28589-7-peter.maydell@linaro.org
16
---
7
---
17
include/hw/arm/bcm2836.h | 19 +++++++++++++++++++
8
target/arm/translate.c | 7 +++----
18
hw/arm/bcm2836.c | 37 ++++++++++++++++++++++++++++++++-----
9
1 file changed, 3 insertions(+), 4 deletions(-)
19
hw/arm/raspi.c | 3 ++-
20
3 files changed, 53 insertions(+), 6 deletions(-)
21
10
22
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
23
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/arm/bcm2836.h
13
--- a/target/arm/translate.c
25
+++ b/include/hw/arm/bcm2836.h
14
+++ b/target/arm/translate.c
26
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
27
16
* what we are asking here is "does the code for this case in
28
#define BCM283X_NCPUS 4
17
* the Neon for-each-pass loop use cpu_F0s?".
29
18
*/
30
+/* These type names are for specific SoCs; other than instantiating
19
- return ((op >= NEON_2RM_VCVTAU && op <= NEON_2RM_VCVTMS) ||
31
+ * them, code using these devices should always handle them via the
20
- op >= NEON_2RM_VRECPE_F);
32
+ * BCM283x base class, so they have no BCM2836(obj) etc macros.
21
+ return op >= NEON_2RM_VRECPE_F;
33
+ */
34
+#define TYPE_BCM2836 "bcm2836"
35
+#define TYPE_BCM2837 "bcm2837"
36
+
37
typedef struct BCM283XState {
38
/*< private >*/
39
DeviceState parent_obj;
40
@@ -XXX,XX +XXX,XX @@ typedef struct BCM283XState {
41
BCM2835PeripheralState peripherals;
42
} BCM283XState;
43
44
+typedef struct BCM283XInfo BCM283XInfo;
45
+
46
+typedef struct BCM283XClass {
47
+ DeviceClass parent_class;
48
+ const BCM283XInfo *info;
49
+} BCM283XClass;
50
+
51
+#define BCM283X_CLASS(klass) \
52
+ OBJECT_CLASS_CHECK(BCM283XClass, (klass), TYPE_BCM283X)
53
+#define BCM283X_GET_CLASS(obj) \
54
+ OBJECT_GET_CLASS(BCM283XClass, (obj), TYPE_BCM283X)
55
+
56
#endif /* BCM2836_H */
57
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/arm/bcm2836.c
60
+++ b/hw/arm/bcm2836.c
61
@@ -XXX,XX +XXX,XX @@
62
/* "QA7" (Pi2) interrupt controller and mailboxes etc. */
63
#define BCM2836_CONTROL_BASE 0x40000000
64
65
+struct BCM283XInfo {
66
+ const char *name;
67
+};
68
+
69
+static const BCM283XInfo bcm283x_socs[] = {
70
+ {
71
+ .name = TYPE_BCM2836,
72
+ },
73
+ {
74
+ .name = TYPE_BCM2837,
75
+ },
76
+};
77
+
78
static void bcm2836_init(Object *obj)
79
{
80
BCM283XState *s = BCM283X(obj);
81
@@ -XXX,XX +XXX,XX @@ static Property bcm2836_props[] = {
82
DEFINE_PROP_END_OF_LIST()
83
};
84
85
-static void bcm2836_class_init(ObjectClass *oc, void *data)
86
+static void bcm283x_class_init(ObjectClass *oc, void *data)
87
{
88
DeviceClass *dc = DEVICE_CLASS(oc);
89
+ BCM283XClass *bc = BCM283X_CLASS(oc);
90
91
- dc->props = bcm2836_props;
92
+ bc->info = data;
93
dc->realize = bcm2836_realize;
94
+ dc->props = bcm2836_props;
95
}
22
}
96
23
97
-static const TypeInfo bcm2836_type_info = {
24
static bool neon_2rm_is_v8_op(int op)
98
+static const TypeInfo bcm283x_type_info = {
25
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
99
.name = TYPE_BCM283X,
26
cpu_env);
100
.parent = TYPE_DEVICE,
27
101
.instance_size = sizeof(BCM283XState),
28
if (is_signed) {
102
.instance_init = bcm2836_init,
29
- gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
103
- .class_init = bcm2836_class_init,
30
+ gen_helper_vfp_tosls(tmp, tmp,
104
+ .class_size = sizeof(BCM283XClass),
31
tcg_shift, fpst);
105
+ .abstract = true,
32
} else {
106
};
33
- gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
107
34
+ gen_helper_vfp_touls(tmp, tmp,
108
static void bcm2836_register_types(void)
35
tcg_shift, fpst);
109
{
36
}
110
- type_register_static(&bcm2836_type_info);
111
+ int i;
112
+
113
+ type_register_static(&bcm283x_type_info);
114
+ for (i = 0; i < ARRAY_SIZE(bcm283x_socs); i++) {
115
+ TypeInfo ti = {
116
+ .name = bcm283x_socs[i].name,
117
+ .parent = TYPE_BCM283X,
118
+ .class_init = bcm283x_class_init,
119
+ .class_data = (void *) &bcm283x_socs[i],
120
+ };
121
+ type_register(&ti);
122
+ }
123
}
124
125
type_init(bcm2836_register_types)
126
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/arm/raspi.c
129
+++ b/hw/arm/raspi.c
130
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
131
BusState *bus;
132
DeviceState *carddev;
133
134
- object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM283X);
135
+ object_initialize(&s->soc, sizeof(s->soc),
136
+ version == 3 ? TYPE_BCM2837 : TYPE_BCM2836);
137
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
138
&error_abort);
139
37
140
--
38
--
141
2.16.2
39
2.20.1
142
40
143
41
diff view generated by jsdifflib
1
Now we have separate types for BCM2386 and BCM2387, we might as well
1
Stop using cpu_F0s for NEON_2RM_VRECPE_F and NEON_2RM_VRSQRTE_F.
2
just hard-code the CPU type they use rather than having it passed
3
through as an object property. This then lets us put the initialization
4
of the CPU object in init rather than realize.
5
6
Note that this change means that it's no longer possible on
7
the command line to use -cpu to ask for a different kind of
8
CPU than the SoC supports. This was never a supported thing to
9
do anyway; we were just not sanity-checking the command line.
10
11
This does require us to only build the bcm2837 object on
12
TARGET_AARCH64 configs, since otherwise it won't instantiate
13
due to the missing cortex-a53 device and "make check" will fail.
14
2
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
18
Message-id: 20180313153458.26822-9-peter.maydell@linaro.org
6
Message-id: 20190613163917.28589-8-peter.maydell@linaro.org
19
---
7
---
20
hw/arm/bcm2836.c | 24 +++++++++++++++---------
8
target/arm/translate.c | 6 +++---
21
hw/arm/raspi.c | 2 --
9
1 file changed, 3 insertions(+), 3 deletions(-)
22
2 files changed, 15 insertions(+), 11 deletions(-)
23
10
24
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
25
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/bcm2836.c
13
--- a/target/arm/translate.c
27
+++ b/hw/arm/bcm2836.c
14
+++ b/target/arm/translate.c
28
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static int neon_2rm_is_float_op(int op)
29
16
* what we are asking here is "does the code for this case in
30
struct BCM283XInfo {
17
* the Neon for-each-pass loop use cpu_F0s?".
31
const char *name;
18
*/
32
+ const char *cpu_type;
19
- return op >= NEON_2RM_VRECPE_F;
33
int clusterid;
20
+ return op >= NEON_2RM_VCVT_FS;
34
};
35
36
static const BCM283XInfo bcm283x_socs[] = {
37
{
38
.name = TYPE_BCM2836,
39
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"),
40
.clusterid = 0xf,
41
},
42
+#ifdef TARGET_AARCH64
43
{
44
.name = TYPE_BCM2837,
45
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a53"),
46
.clusterid = 0x0,
47
},
48
+#endif
49
};
50
51
static void bcm2836_init(Object *obj)
52
{
53
BCM283XState *s = BCM283X(obj);
54
+ BCM283XClass *bc = BCM283X_GET_CLASS(obj);
55
+ const BCM283XInfo *info = bc->info;
56
+ int n;
57
+
58
+ for (n = 0; n < BCM283X_NCPUS; n++) {
59
+ object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
60
+ info->cpu_type);
61
+ object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
62
+ &error_abort);
63
+ }
64
65
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
66
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
67
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
68
69
/* common peripherals from bcm2835 */
70
71
- obj = OBJECT(dev);
72
- for (n = 0; n < BCM283X_NCPUS; n++) {
73
- object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
74
- s->cpu_type);
75
- object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
76
- &error_abort);
77
- }
78
-
79
obj = object_property_get_link(OBJECT(dev), "ram", &err);
80
if (obj == NULL) {
81
error_setg(errp, "%s: required ram link not found: %s",
82
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
83
}
21
}
84
22
85
static Property bcm2836_props[] = {
23
static bool neon_2rm_is_v8_op(int op)
86
- DEFINE_PROP_STRING("cpu-type", BCM283XState, cpu_type),
24
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
87
DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus,
25
case NEON_2RM_VRECPE_F:
88
BCM283X_NCPUS),
26
{
89
DEFINE_PROP_END_OF_LIST()
27
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
90
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
28
- gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
91
index XXXXXXX..XXXXXXX 100644
29
+ gen_helper_recpe_f32(tmp, tmp, fpstatus);
92
--- a/hw/arm/raspi.c
30
tcg_temp_free_ptr(fpstatus);
93
+++ b/hw/arm/raspi.c
31
break;
94
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
32
}
95
/* Setup the SOC */
33
case NEON_2RM_VRSQRTE_F:
96
object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
34
{
97
&error_abort);
35
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
98
- object_property_set_str(OBJECT(&s->soc), machine->cpu_type, "cpu-type",
36
- gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
99
- &error_abort);
37
+ gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
100
object_property_set_int(OBJECT(&s->soc), smp_cpus, "enabled-cpus",
38
tcg_temp_free_ptr(fpstatus);
101
&error_abort);
39
break;
102
int board_rev = version == 3 ? 0xa02082 : 0xa21041;
40
}
103
--
41
--
104
2.16.2
42
2.20.1
105
43
106
44
diff view generated by jsdifflib
1
For the rpi1 and 2 we want to boot the Linux kernel via some
1
Stop using cpu_F0s for the Neon f32/s32 VCVT operations.
2
custom setup code that makes sure that the SMC instruction
2
Since this is the last user of cpu_F0s in the Neon 2rm-op
3
acts as a no-op, because it's used for cache maintenance.
3
loop, we can remove the handling code for it too.
4
The rpi3 boots AArch64 kernels, which don't need SMC for
5
cache maintenance and always expect to be booted non-secure.
6
Don't fill in the aarch32-specific parts of the binfo struct.
7
4
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20180313153458.26822-2-peter.maydell@linaro.org
8
Message-id: 20190613163917.28589-9-peter.maydell@linaro.org
12
---
9
---
13
hw/arm/raspi.c | 17 +++++++++++++----
10
target/arm/translate.c | 82 ++++++++++++------------------------------
14
1 file changed, 13 insertions(+), 4 deletions(-)
11
1 file changed, 22 insertions(+), 60 deletions(-)
15
12
16
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/raspi.c
15
--- a/target/arm/translate.c
19
+++ b/hw/arm/raspi.c
16
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
17
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
21
binfo.board_id = raspi_boardid[version];
18
return statusptr;
22
binfo.ram_size = ram_size;
19
}
23
binfo.nb_cpus = smp_cpus;
20
24
- binfo.board_setup_addr = BOARDSETUP_ADDR;
21
-#define VFP_GEN_ITOF(name) \
25
- binfo.write_board_setup = write_board_setup;
22
-static inline void gen_vfp_##name(int dp, int neon) \
26
- binfo.secure_board_setup = true;
23
-{ \
27
- binfo.secure_boot = true;
24
- TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
28
+
25
- if (dp) { \
29
+ if (version <= 2) {
26
- gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
30
+ /* The rpi1 and 2 require some custom setup code to run in Secure
27
- } else { \
31
+ * mode before booting a kernel (to set up the SMC vectors so
28
- gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
32
+ * that we get a no-op SMC; this is used by Linux to call the
29
- } \
33
+ * firmware for some cache maintenance operations.
30
- tcg_temp_free_ptr(statusptr); \
34
+ * The rpi3 doesn't need this.
31
-}
35
+ */
32
-
36
+ binfo.board_setup_addr = BOARDSETUP_ADDR;
33
-VFP_GEN_ITOF(uito)
37
+ binfo.write_board_setup = write_board_setup;
34
-VFP_GEN_ITOF(sito)
38
+ binfo.secure_board_setup = true;
35
-#undef VFP_GEN_ITOF
39
+ binfo.secure_boot = true;
36
-
40
+ }
37
-#define VFP_GEN_FTOI(name) \
41
38
-static inline void gen_vfp_##name(int dp, int neon) \
42
/* Pi2 and Pi3 requires SMP setup */
39
-{ \
43
if (version >= 2) {
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)
72
{
73
/* Return true if this neon 2reg-misc op is ARMv8 and up */
74
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
75
default:
76
elementwise:
77
for (pass = 0; pass < (q ? 4 : 2); pass++) {
78
- if (neon_2rm_is_float_op(op)) {
79
- tcg_gen_ld_f32(cpu_F0s, cpu_env,
80
- neon_reg_offset(rm, pass));
81
- tmp = NULL;
82
- } else {
83
- tmp = neon_load_reg(rm, pass);
84
- }
85
+ tmp = neon_load_reg(rm, pass);
86
switch (op) {
87
case NEON_2RM_VREV32:
88
switch (size) {
89
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
90
break;
91
}
92
case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
93
- gen_vfp_sito(0, 1);
94
+ {
95
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
96
+ gen_helper_vfp_sitos(tmp, tmp, fpstatus);
97
+ tcg_temp_free_ptr(fpstatus);
98
break;
99
+ }
100
case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
101
- gen_vfp_uito(0, 1);
102
+ {
103
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
104
+ gen_helper_vfp_uitos(tmp, tmp, fpstatus);
105
+ tcg_temp_free_ptr(fpstatus);
106
break;
107
+ }
108
case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
109
- gen_vfp_tosiz(0, 1);
110
+ {
111
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
112
+ gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
113
+ tcg_temp_free_ptr(fpstatus);
114
break;
115
+ }
116
case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
117
- gen_vfp_touiz(0, 1);
118
+ {
119
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
120
+ gen_helper_vfp_touizs(tmp, tmp, fpstatus);
121
+ tcg_temp_free_ptr(fpstatus);
122
break;
123
+ }
124
default:
125
/* Reserved op values were caught by the
126
* neon_2rm_sizes[] check earlier.
127
*/
128
abort();
129
}
130
- if (neon_2rm_is_float_op(op)) {
131
- tcg_gen_st_f32(cpu_F0s, cpu_env,
132
- neon_reg_offset(rd, pass));
133
- } else {
134
- neon_store_reg(rd, pass, tmp);
135
- }
136
+ neon_store_reg(rd, pass, tmp);
137
}
138
break;
139
}
44
--
140
--
45
2.16.2
141
2.20.1
46
142
47
143
diff view generated by jsdifflib
1
From: Wei Huang <wei@redhat.com>
1
Stop using cpu_F0s in the Neon VCVT fixed-point operations.
2
2
3
For guest kernel that supports KASLR, the load address can change every
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
time when guest VM runs. To find the physical base address correctly,
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
current QEMU dump searches VMCOREINFO for the string "NUMBER(phys_base)=".
5
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
However this string pattern is only available on x86_64. AArch64 uses a
6
Message-id: 20190613163917.28589-10-peter.maydell@linaro.org
7
different field, called "NUMBER(PHYS_OFFSET)=". This patch makes sure
7
---
8
QEMU dump uses the correct string on AArch64.
8
target/arm/translate.c | 62 +++++++++++++++++++-----------------------
9
1 file changed, 28 insertions(+), 34 deletions(-)
9
10
10
Signed-off-by: Wei Huang <wei@redhat.com>
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
11
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
12
Message-id: 1520615003-20869-1-git-send-email-wei@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
dump.c | 14 +++++++++++---
16
1 file changed, 11 insertions(+), 3 deletions(-)
17
18
diff --git a/dump.c b/dump.c
19
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
20
--- a/dump.c
13
--- a/target/arm/translate.c
21
+++ b/dump.c
14
+++ b/target/arm/translate.c
22
@@ -XXX,XX +XXX,XX @@ static void vmcoreinfo_update_phys_base(DumpState *s)
15
@@ -XXX,XX +XXX,XX @@ static const char * const regnames[] =
23
16
/* Function prototypes for gen_ functions calling Neon helpers. */
24
lines = g_strsplit((char *)vmci, "\n", -1);
17
typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
25
for (i = 0; lines[i]; i++) {
18
TCGv_i32, TCGv_i32);
26
- if (g_str_has_prefix(lines[i], "NUMBER(phys_base)=")) {
19
+/* Function prototypes for gen_ functions for fix point conversions */
27
- if (qemu_strtou64(lines[i] + 18, NULL, 16,
20
+typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
28
+ const char *prefix = NULL;
21
22
/* initialize TCG globals. */
23
void arm_translate_init(void)
24
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr get_fpstatus_ptr(int neon)
25
return statusptr;
26
}
27
28
-#define VFP_GEN_FIX(name, round) \
29
-static inline void gen_vfp_##name(int dp, int shift, int neon) \
30
-{ \
31
- TCGv_i32 tmp_shift = tcg_const_i32(shift); \
32
- TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
33
- if (dp) { \
34
- gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
35
- statusptr); \
36
- } else { \
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;
29
+
59
+
30
+ if (s->dump_info.d_machine == EM_X86_64) {
60
if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
31
+ prefix = "NUMBER(phys_base)=";
61
return 1;
32
+ } else if (s->dump_info.d_machine == EM_AARCH64) {
62
}
33
+ prefix = "NUMBER(PHYS_OFFSET)=";
34
+ }
35
+
63
+
36
+ if (prefix && g_str_has_prefix(lines[i], prefix)) {
64
+ if (!(op & 1)) {
37
+ if (qemu_strtou64(lines[i] + strlen(prefix), NULL, 16,
65
+ if (u) {
38
&phys_base) < 0) {
66
+ fn = gen_helper_vfp_ultos;
39
- warn_report("Failed to read NUMBER(phys_base)=");
67
+ } else {
40
+ warn_report("Failed to read %s", prefix);
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);
41
} else {
104
} else {
42
s->dump_info.phys_base = phys_base;
105
return 1;
43
}
106
}
44
--
107
--
45
2.16.2
108
2.20.1
46
109
47
110
diff view generated by jsdifflib
1
Our BCM2836 type is really a generic one that can be any of
1
Remove some old constructs from NEON_2RM_VCVT_F16_F32 code:
2
the bcm283x family. Rename it accordingly. We change only
2
* don't use cpu_F0s
3
the names which are visible via the header file to the
3
* don't use tcg_gen_ld_f32
4
rest of the QEMU code, leaving private function names
5
in bcm2836.c as they are.
6
7
This is a preliminary to making bcm283x be an abstract
8
parent class to specific types for the bcm2836 and bcm2837.
9
4
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Message-id: 20180313153458.26822-6-peter.maydell@linaro.org
8
Message-id: 20190613163917.28589-11-peter.maydell@linaro.org
14
---
9
---
15
include/hw/arm/bcm2836.h | 12 ++++++------
10
target/arm/translate.c | 27 ++++++++++++---------------
16
hw/arm/bcm2836.c | 17 +++++++++--------
11
1 file changed, 12 insertions(+), 15 deletions(-)
17
hw/arm/raspi.c | 16 ++++++++--------
18
3 files changed, 23 insertions(+), 22 deletions(-)
19
12
20
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.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/hw/arm/bcm2836.h
15
--- a/target/arm/translate.c
23
+++ b/include/hw/arm/bcm2836.h
16
+++ b/target/arm/translate.c
24
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
25
#include "hw/arm/bcm2835_peripherals.h"
18
return ret;
26
#include "hw/intc/bcm2836_control.h"
27
28
-#define TYPE_BCM2836 "bcm2836"
29
-#define BCM2836(obj) OBJECT_CHECK(BCM2836State, (obj), TYPE_BCM2836)
30
+#define TYPE_BCM283X "bcm283x"
31
+#define BCM283X(obj) OBJECT_CHECK(BCM283XState, (obj), TYPE_BCM283X)
32
33
-#define BCM2836_NCPUS 4
34
+#define BCM283X_NCPUS 4
35
36
-typedef struct BCM2836State {
37
+typedef struct BCM283XState {
38
/*< private >*/
39
DeviceState parent_obj;
40
/*< public >*/
41
@@ -XXX,XX +XXX,XX @@ typedef struct BCM2836State {
42
char *cpu_type;
43
uint32_t enabled_cpus;
44
45
- ARMCPU cpus[BCM2836_NCPUS];
46
+ ARMCPU cpus[BCM283X_NCPUS];
47
BCM2836ControlState control;
48
BCM2835PeripheralState peripherals;
49
-} BCM2836State;
50
+} BCM283XState;
51
52
#endif /* BCM2836_H */
53
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/bcm2836.c
56
+++ b/hw/arm/bcm2836.c
57
@@ -XXX,XX +XXX,XX @@
58
59
static void bcm2836_init(Object *obj)
60
{
61
- BCM2836State *s = BCM2836(obj);
62
+ BCM283XState *s = BCM283X(obj);
63
64
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
65
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
66
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
67
68
static void bcm2836_realize(DeviceState *dev, Error **errp)
69
{
70
- BCM2836State *s = BCM2836(dev);
71
+ BCM283XState *s = BCM283X(dev);
72
Object *obj;
73
Error *err = NULL;
74
int n;
75
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
76
/* common peripherals from bcm2835 */
77
78
obj = OBJECT(dev);
79
- for (n = 0; n < BCM2836_NCPUS; n++) {
80
+ for (n = 0; n < BCM283X_NCPUS; n++) {
81
object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
82
s->cpu_type);
83
object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
84
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
85
sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 1,
86
qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
87
88
- for (n = 0; n < BCM2836_NCPUS; n++) {
89
+ for (n = 0; n < BCM283X_NCPUS; n++) {
90
/* Mirror bcm2836, which has clusterid set to 0xf
91
* TODO: this should be converted to a property of ARM_CPU
92
*/
93
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
94
}
19
}
95
20
96
static Property bcm2836_props[] = {
21
-#define tcg_gen_ld_f32 tcg_gen_ld_i32
97
- DEFINE_PROP_STRING("cpu-type", BCM2836State, cpu_type),
22
#define tcg_gen_st_f32 tcg_gen_st_i32
98
- DEFINE_PROP_UINT32("enabled-cpus", BCM2836State, enabled_cpus, BCM2836_NCPUS),
23
99
+ DEFINE_PROP_STRING("cpu-type", BCM283XState, cpu_type),
24
#define ARM_CP_RW_BIT (1 << 20)
100
+ DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus,
25
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
101
+ BCM283X_NCPUS),
26
q || (rm & 1)) {
102
DEFINE_PROP_END_OF_LIST()
27
return 1;
103
};
28
}
104
29
- tmp = tcg_temp_new_i32();
105
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
30
- tmp2 = tcg_temp_new_i32();
106
}
31
fpst = get_fpstatus_ptr(true);
107
32
ahp = get_ahp_flag();
108
static const TypeInfo bcm2836_type_info = {
33
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
109
- .name = TYPE_BCM2836,
34
- gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
110
+ .name = TYPE_BCM283X,
35
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
111
.parent = TYPE_DEVICE,
36
- gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
112
- .instance_size = sizeof(BCM2836State),
37
+ tmp = neon_load_reg(rm, 0);
113
+ .instance_size = sizeof(BCM283XState),
38
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
114
.instance_init = bcm2836_init,
39
+ tmp2 = neon_load_reg(rm, 1);
115
.class_init = bcm2836_class_init,
40
+ gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
116
};
41
tcg_gen_shli_i32(tmp2, tmp2, 16);
117
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
42
tcg_gen_or_i32(tmp2, tmp2, tmp);
118
index XXXXXXX..XXXXXXX 100644
43
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
119
--- a/hw/arm/raspi.c
44
- gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
120
+++ b/hw/arm/raspi.c
45
- tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
121
@@ -XXX,XX +XXX,XX @@
46
+ tcg_temp_free_i32(tmp);
122
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
47
+ tmp = neon_load_reg(rm, 2);
123
48
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
124
typedef struct RasPiState {
49
+ tmp3 = neon_load_reg(rm, 3);
125
- BCM2836State soc;
50
neon_store_reg(rd, 0, tmp2);
126
+ BCM283XState soc;
51
- tmp2 = tcg_temp_new_i32();
127
MemoryRegion ram;
52
- gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
128
} RasPiState;
53
- tcg_gen_shli_i32(tmp2, tmp2, 16);
129
54
- tcg_gen_or_i32(tmp2, tmp2, tmp);
130
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
55
- neon_store_reg(rd, 1, tmp2);
131
BusState *bus;
56
+ gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
132
DeviceState *carddev;
57
+ tcg_gen_shli_i32(tmp3, tmp3, 16);
133
58
+ tcg_gen_or_i32(tmp3, tmp3, tmp);
134
- object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM2836);
59
+ neon_store_reg(rd, 1, tmp3);
135
+ object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM283X);
60
tcg_temp_free_i32(tmp);
136
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
61
tcg_temp_free_i32(ahp);
137
&error_abort);
62
tcg_temp_free_ptr(fpst);
138
139
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_init(MachineClass *mc)
140
mc->no_floppy = 1;
141
mc->no_cdrom = 1;
142
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
143
- mc->max_cpus = BCM2836_NCPUS;
144
- mc->min_cpus = BCM2836_NCPUS;
145
- mc->default_cpus = BCM2836_NCPUS;
146
+ mc->max_cpus = BCM283X_NCPUS;
147
+ mc->min_cpus = BCM283X_NCPUS;
148
+ mc->default_cpus = BCM283X_NCPUS;
149
mc->default_ram_size = 1024 * 1024 * 1024;
150
mc->ignore_memory_transaction_failures = true;
151
};
152
@@ -XXX,XX +XXX,XX @@ static void raspi3_machine_init(MachineClass *mc)
153
mc->no_floppy = 1;
154
mc->no_cdrom = 1;
155
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a53");
156
- mc->max_cpus = BCM2836_NCPUS;
157
- mc->min_cpus = BCM2836_NCPUS;
158
- mc->default_cpus = BCM2836_NCPUS;
159
+ mc->max_cpus = BCM283X_NCPUS;
160
+ mc->min_cpus = BCM283X_NCPUS;
161
+ mc->default_cpus = BCM283X_NCPUS;
162
mc->default_ram_size = 1024 * 1024 * 1024;
163
}
164
DEFINE_MACHINE("raspi3", raspi3_machine_init)
165
--
63
--
166
2.16.2
64
2.20.1
167
65
168
66
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
Remove some old constructns from NEON_2RM_VCVT_F16_F32 code:
2
* don't use CPU_F0s
3
* don't use tcg_gen_st_f32
2
4
3
Add support for "TX complete"/TXDC interrupt generate by real HW since
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
it is needed to support guests other than Linux.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190613163917.28589-12-peter.maydell@linaro.org
9
---
10
target/arm/translate.c | 26 +++++++++++---------------
11
1 file changed, 11 insertions(+), 15 deletions(-)
5
12
6
Based on the patch by Bill Paul as found here:
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
7
https://bugs.launchpad.net/qemu/+bug/1753314
8
9
Cc: qemu-devel@nongnu.org
10
Cc: qemu-arm@nongnu.org
11
Cc: Bill Paul <wpaul@windriver.com>
12
Cc: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Bill Paul <wpaul@windriver.com>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
15
Message-id: 20180315191141.6789-2-andrew.smirnov@gmail.com
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
include/hw/char/imx_serial.h | 3 +++
20
hw/char/imx_serial.c | 20 +++++++++++++++++---
21
2 files changed, 20 insertions(+), 3 deletions(-)
22
23
diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
24
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/char/imx_serial.h
15
--- a/target/arm/translate.c
26
+++ b/include/hw/char/imx_serial.h
16
+++ b/target/arm/translate.c
27
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
28
#define UCR2_RXEN (1<<1) /* Receiver enable */
18
return ret;
29
#define UCR2_SRST (1<<0) /* Reset complete */
19
}
30
20
31
+#define UCR4_TCEN BIT(3) /* TX complete interrupt enable */
21
-#define tcg_gen_st_f32 tcg_gen_st_i32
32
+
22
-
33
#define UTS1_TXEMPTY (1<<6)
23
#define ARM_CP_RW_BIT (1 << 20)
34
#define UTS1_RXEMPTY (1<<5)
24
35
#define UTS1_TXFULL (1<<4)
25
/* Include the VFP decoder */
36
@@ -XXX,XX +XXX,XX @@ typedef struct IMXSerialState {
26
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
37
uint32_t ubmr;
27
tmp = neon_load_reg(rm, 0);
38
uint32_t ubrc;
28
tmp2 = neon_load_reg(rm, 1);
39
uint32_t ucr3;
29
tcg_gen_ext16u_i32(tmp3, tmp);
40
+ uint32_t ucr4;
30
- gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
41
31
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
42
qemu_irq irq;
32
- tcg_gen_shri_i32(tmp3, tmp, 16);
43
CharBackend chr;
33
- gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
44
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
34
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
45
index XXXXXXX..XXXXXXX 100644
35
- tcg_temp_free_i32(tmp);
46
--- a/hw/char/imx_serial.c
36
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
47
+++ b/hw/char/imx_serial.c
37
+ neon_store_reg(rd, 0, tmp3);
48
@@ -XXX,XX +XXX,XX @@
38
+ tcg_gen_shri_i32(tmp, tmp, 16);
49
39
+ gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
50
static const VMStateDescription vmstate_imx_serial = {
40
+ neon_store_reg(rd, 1, tmp);
51
.name = TYPE_IMX_SERIAL,
41
+ tmp3 = tcg_temp_new_i32();
52
- .version_id = 1,
42
tcg_gen_ext16u_i32(tmp3, tmp2);
53
- .minimum_version_id = 1,
43
- gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
54
+ .version_id = 2,
44
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
55
+ .minimum_version_id = 2,
45
- tcg_gen_shri_i32(tmp3, tmp2, 16);
56
.fields = (VMStateField[]) {
46
- gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
57
VMSTATE_INT32(readbuff, IMXSerialState),
47
- tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
58
VMSTATE_UINT32(usr1, IMXSerialState),
48
- tcg_temp_free_i32(tmp2);
59
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
49
- tcg_temp_free_i32(tmp3);
60
VMSTATE_UINT32(ubmr, IMXSerialState),
50
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
61
VMSTATE_UINT32(ubrc, IMXSerialState),
51
+ neon_store_reg(rd, 2, tmp3);
62
VMSTATE_UINT32(ucr3, IMXSerialState),
52
+ tcg_gen_shri_i32(tmp2, tmp2, 16);
63
+ VMSTATE_UINT32(ucr4, IMXSerialState),
53
+ gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
64
VMSTATE_END_OF_LIST()
54
+ neon_store_reg(rd, 3, tmp2);
65
},
55
tcg_temp_free_i32(ahp);
66
};
56
tcg_temp_free_ptr(fpst);
67
@@ -XXX,XX +XXX,XX @@ static void imx_update(IMXSerialState *s)
57
break;
68
* unfortunately.
69
*/
70
mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
71
+ /*
72
+ * TCEN and TXDC are both bit 3
73
+ */
74
+ mask |= s->ucr4 & UCR4_TCEN;
75
+
76
usr2 = s->usr2 & mask;
77
78
qemu_set_irq(s->irq, usr1 || usr2);
79
@@ -XXX,XX +XXX,XX @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset,
80
return s->ucr3;
81
82
case 0x23: /* UCR4 */
83
+ return s->ucr4;
84
+
85
case 0x29: /* BRM Incremental */
86
return 0x0; /* TODO */
87
88
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
89
* qemu_chr_fe_write and background I/O callbacks */
90
qemu_chr_fe_write_all(&s->chr, &ch, 1);
91
s->usr1 &= ~USR1_TRDY;
92
+ s->usr2 &= ~USR2_TXDC;
93
imx_update(s);
94
s->usr1 |= USR1_TRDY;
95
+ s->usr2 |= USR2_TXDC;
96
imx_update(s);
97
}
98
break;
99
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
100
s->ucr3 = value & 0xffff;
101
break;
102
103
- case 0x2d: /* UTS1 */
104
case 0x23: /* UCR4 */
105
+ s->ucr4 = value & 0xffff;
106
+ imx_update(s);
107
+ break;
108
+
109
+ case 0x2d: /* UTS1 */
110
qemu_log_mask(LOG_UNIMP, "[%s]%s: Unimplemented reg 0x%"
111
HWADDR_PRIx "\n", TYPE_IMX_SERIAL, __func__, offset);
112
/* TODO */
113
--
58
--
114
2.16.2
59
2.20.1
115
60
116
61
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
Remove the now unused TCG globals cpu_F0s, cpu_F0d, cpu_F1s, cpu_F1d.
2
2
3
The sabrelite machine model used by qemu-system-arm is based on the
3
cpu_M0 is still used by the iwmmxt code, and cpu_V0 and
4
Freescale/NXP i.MX6Q processor. This SoC has an on-board ethernet
4
cpu_V1 are used by both iwmmxt and Neon.
5
controller which is supported in QEMU using the imx_fec.c module
6
(actually called imx.enet for this model.)
7
5
8
The include/hw/arm/fsm-imx6.h file defines the interrupt vectors for the
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
imx.enet device like this:
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190613163917.28589-13-peter.maydell@linaro.org
10
---
11
target/arm/translate.c | 12 ++----------
12
1 file changed, 2 insertions(+), 10 deletions(-)
10
13
11
#define FSL_IMX6_ENET_MAC_1588_IRQ 118
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
#define FSL_IMX6_ENET_MAC_IRQ 119
13
14
According to https://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf,
15
page 225, in Table 3-1. ARM Cortex A9 domain interrupt summary,
16
interrupts are as follows.
17
18
150 ENET MAC 0 IRQ
19
151 ENET MAC 0 1588 Timer interrupt
20
21
where
22
23
150 - 32 == 118
24
151 - 32 == 119
25
26
In other words, the vector definitions in the fsl-imx6.h file are reversed.
27
28
Fixing the interrupts alone causes problems with older Linux kernels:
29
The Ethernet interface will fail to probe with Linux v4.9 and earlier.
30
Linux v4.1 and earlier will crash due to a bug in Ethernet driver probe
31
error handling. This is a Linux kernel problem, not a qemu problem:
32
the Linux kernel only worked by accident since it requested both interrupts.
33
34
For backward compatibility, generate the Ethernet interrupt on both interrupt
35
lines. This was shown to work from all Linux kernel releases starting with
36
v3.16.
37
38
Link: https://bugs.launchpad.net/qemu/+bug/1753309
39
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
40
Message-id: 1520723090-22130-1-git-send-email-linux@roeck-us.net
41
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
---
44
include/hw/arm/fsl-imx6.h | 4 ++--
45
hw/net/imx_fec.c | 28 +++++++++++++++++++++++++++-
46
2 files changed, 29 insertions(+), 3 deletions(-)
47
48
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
49
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
50
--- a/include/hw/arm/fsl-imx6.h
16
--- a/target/arm/translate.c
51
+++ b/include/hw/arm/fsl-imx6.h
17
+++ b/target/arm/translate.c
52
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX6State {
18
@@ -XXX,XX +XXX,XX @@ TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
53
#define FSL_IMX6_HDMI_MASTER_IRQ 115
19
TCGv_i64 cpu_exclusive_addr;
54
#define FSL_IMX6_HDMI_CEC_IRQ 116
20
TCGv_i64 cpu_exclusive_val;
55
#define FSL_IMX6_MLB150_LOW_IRQ 117
21
56
-#define FSL_IMX6_ENET_MAC_1588_IRQ 118
22
-/* FIXME: These should be removed. */
57
-#define FSL_IMX6_ENET_MAC_IRQ 119
23
-static TCGv_i32 cpu_F0s, cpu_F1s;
58
+#define FSL_IMX6_ENET_MAC_IRQ 118
24
-static TCGv_i64 cpu_F0d, cpu_F1d;
59
+#define FSL_IMX6_ENET_MAC_1588_IRQ 119
25
-
60
#define FSL_IMX6_PCIE1_IRQ 120
26
#include "exec/gen-icount.h"
61
#define FSL_IMX6_PCIE2_IRQ 121
27
62
#define FSL_IMX6_PCIE3_IRQ 122
28
static const char * const regnames[] =
63
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
29
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
64
index XXXXXXX..XXXXXXX 100644
30
dc->base.max_insns = MIN(dc->base.max_insns, bound);
65
--- a/hw/net/imx_fec.c
31
}
66
+++ b/hw/net/imx_fec.c
32
67
@@ -XXX,XX +XXX,XX @@ static void imx_enet_write_bd(IMXENETBufDesc *bd, dma_addr_t addr)
33
- cpu_F0s = tcg_temp_new_i32();
68
34
- cpu_F1s = tcg_temp_new_i32();
69
static void imx_eth_update(IMXFECState *s)
35
- cpu_F0d = tcg_temp_new_i64();
70
{
36
- cpu_F1d = tcg_temp_new_i64();
71
- if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_TS_TIMER) {
37
- cpu_V0 = cpu_F0d;
72
+ /*
38
- cpu_V1 = cpu_F1d;
73
+ * Previous versions of qemu had the ENET_INT_MAC and ENET_INT_TS_TIMER
39
+ cpu_V0 = tcg_temp_new_i64();
74
+ * interrupts swapped. This worked with older versions of Linux (4.14
40
+ cpu_V1 = tcg_temp_new_i64();
75
+ * and older) since Linux associated both interrupt lines with Ethernet
41
/* FIXME: cpu_M0 can probably be the same as cpu_V0. */
76
+ * MAC interrupts. Specifically,
42
cpu_M0 = tcg_temp_new_i64();
77
+ * - Linux 4.15 and later have separate interrupt handlers for the MAC and
43
}
78
+ * timer interrupts. Those versions of Linux fail with versions of QEMU
79
+ * with swapped interrupt assignments.
80
+ * - In linux 4.14, both interrupt lines were registered with the Ethernet
81
+ * MAC interrupt handler. As a result, all versions of qemu happen to
82
+ * work, though that is accidental.
83
+ * - In Linux 4.9 and older, the timer interrupt was registered directly
84
+ * with the Ethernet MAC interrupt handler. The MAC interrupt was
85
+ * redirected to a GPIO interrupt to work around erratum ERR006687.
86
+ * This was implemented using the SOC's IOMUX block. In qemu, this GPIO
87
+ * interrupt never fired since IOMUX is currently not supported in qemu.
88
+ * Linux instead received MAC interrupts on the timer interrupt.
89
+ * As a result, qemu versions with the swapped interrupt assignment work,
90
+ * albeit accidentally, but qemu versions with the correct interrupt
91
+ * assignment fail.
92
+ *
93
+ * To ensure that all versions of Linux work, generate ENET_INT_MAC
94
+ * interrrupts on both interrupt lines. This should be changed if and when
95
+ * qemu supports IOMUX.
96
+ */
97
+ if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] &
98
+ (ENET_INT_MAC | ENET_INT_TS_TIMER)) {
99
qemu_set_irq(s->irq[1], 1);
100
} else {
101
qemu_set_irq(s->irq[1], 0);
102
--
44
--
103
2.16.2
45
2.20.1
104
46
105
47
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
In several places cut and paste errors meant we were using the wrong
2
type for the 'arg' struct in trans_ functions called by the
3
decodetree decoder, because we were using the _sp version of the
4
struct in the _dp function. These were harmless, because the two
5
structs were identical and so decodetree made them typedefs of the
6
same underlying structure (and we'd have had a compile error if they
7
were not harmless), but we should clean them up anyway.
2
8
3
Code of imx_update() is slightly confusing since the "flags" variable
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
doesn't really corespond to anything in real hardware and server as a
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
kitchensink accumulating events normally reported via USR1 and USR2
11
Message-id: 20190614104457.24703-2-peter.maydell@linaro.org
6
registers.
12
---
13
target/arm/translate-vfp.inc.c | 28 ++++++++++++++--------------
14
1 file changed, 14 insertions(+), 14 deletions(-)
7
15
8
Change the code to explicitly evaluate state of interrupts reported
16
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
9
via USR1 and USR2 against corresponding masking bits and use the to
10
detemine if IRQ line should be asserted or not.
11
12
NOTE: Check for UTS1_TXEMPTY being set has been dropped for two
13
reasons:
14
15
1. Emulation code implements a single character FIFO, so this flag
16
will always be set since characters are trasmitted as a part of
17
the code emulating "push" into the FIFO
18
19
2. imx_update() is really just a function doing ORing and maksing
20
of reported events, so checking for UTS1_TXEMPTY should happen,
21
if it's ever really needed should probably happen outside of
22
it.
23
24
Cc: qemu-devel@nongnu.org
25
Cc: qemu-arm@nongnu.org
26
Cc: Bill Paul <wpaul@windriver.com>
27
Cc: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
29
Message-id: 20180315191141.6789-1-andrew.smirnov@gmail.com
30
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
---
33
hw/char/imx_serial.c | 24 ++++++++++++++++--------
34
1 file changed, 16 insertions(+), 8 deletions(-)
35
36
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
37
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/char/imx_serial.c
18
--- a/target/arm/translate-vfp.inc.c
39
+++ b/hw/char/imx_serial.c
19
+++ b/target/arm/translate-vfp.inc.c
40
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
20
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
41
21
return true;
42
static void imx_update(IMXSerialState *s)
22
}
23
24
-static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_sp *a)
25
+static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
43
{
26
{
44
- uint32_t flags;
27
TCGv_i32 tmp;
45
+ uint32_t usr1;
28
46
+ uint32_t usr2;
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
47
+ uint32_t mask;
30
return true;
48
49
- flags = (s->usr1 & s->ucr1) & (USR1_TRDY|USR1_RRDY);
50
- if (s->ucr1 & UCR1_TXMPTYEN) {
51
- flags |= (s->uts1 & UTS1_TXEMPTY);
52
- } else {
53
- flags &= ~USR1_TRDY;
54
- }
55
+ /*
56
+ * Lucky for us TRDY and RRDY has the same offset in both USR1 and
57
+ * UCR1, so we can get away with something as simple as the
58
+ * following:
59
+ */
60
+ usr1 = s->usr1 & s->ucr1 & (USR1_TRDY | USR1_RRDY);
61
+ /*
62
+ * Bits that we want in USR2 are not as conveniently laid out,
63
+ * unfortunately.
64
+ */
65
+ mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
66
+ usr2 = s->usr2 & mask;
67
68
- qemu_set_irq(s->irq, !!flags);
69
+ qemu_set_irq(s->irq, usr1 || usr2);
70
}
31
}
71
32
72
static void imx_serial_reset(IMXSerialState *s)
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);
40
}
41
42
-static bool trans_VMLA_dp(DisasContext *s, arg_VMLA_sp *a)
43
+static bool trans_VMLA_dp(DisasContext *s, arg_VMLA_dp *a)
44
{
45
return do_vfp_3op_dp(s, gen_VMLA_dp, a->vd, a->vn, a->vm, true);
46
}
47
@@ -XXX,XX +XXX,XX @@ static void gen_VMLS_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
48
tcg_temp_free_i64(tmp);
49
}
50
51
-static bool trans_VMLS_dp(DisasContext *s, arg_VMLS_sp *a)
52
+static bool trans_VMLS_dp(DisasContext *s, arg_VMLS_dp *a)
53
{
54
return do_vfp_3op_dp(s, gen_VMLS_dp, a->vd, a->vn, a->vm, true);
55
}
56
@@ -XXX,XX +XXX,XX @@ static void gen_VNMLS_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
57
tcg_temp_free_i64(tmp);
58
}
59
60
-static bool trans_VNMLS_dp(DisasContext *s, arg_VNMLS_sp *a)
61
+static bool trans_VNMLS_dp(DisasContext *s, arg_VNMLS_dp *a)
62
{
63
return do_vfp_3op_dp(s, gen_VNMLS_dp, a->vd, a->vn, a->vm, true);
64
}
65
@@ -XXX,XX +XXX,XX @@ static void gen_VNMLA_dp(TCGv_i64 vd, TCGv_i64 vn, TCGv_i64 vm, TCGv_ptr fpst)
66
tcg_temp_free_i64(tmp);
67
}
68
69
-static bool trans_VNMLA_dp(DisasContext *s, arg_VNMLA_sp *a)
70
+static bool trans_VNMLA_dp(DisasContext *s, arg_VNMLA_dp *a)
71
{
72
return do_vfp_3op_dp(s, gen_VNMLA_dp, a->vd, a->vn, a->vm, true);
73
}
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VMUL_sp(DisasContext *s, arg_VMUL_sp *a)
75
return do_vfp_3op_sp(s, gen_helper_vfp_muls, a->vd, a->vn, a->vm, false);
76
}
77
78
-static bool trans_VMUL_dp(DisasContext *s, arg_VMUL_sp *a)
79
+static bool trans_VMUL_dp(DisasContext *s, arg_VMUL_dp *a)
80
{
81
return do_vfp_3op_dp(s, gen_helper_vfp_muld, a->vd, a->vn, a->vm, false);
82
}
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);
85
}
86
87
-static bool trans_VNMUL_dp(DisasContext *s, arg_VNMUL_sp *a)
88
+static bool trans_VNMUL_dp(DisasContext *s, arg_VNMUL_dp *a)
89
{
90
return do_vfp_3op_dp(s, gen_VNMUL_dp, a->vd, a->vn, a->vm, false);
91
}
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);
94
}
95
96
-static bool trans_VADD_dp(DisasContext *s, arg_VADD_sp *a)
97
+static bool trans_VADD_dp(DisasContext *s, arg_VADD_dp *a)
98
{
99
return do_vfp_3op_dp(s, gen_helper_vfp_addd, a->vd, a->vn, a->vm, false);
100
}
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VSUB_sp(DisasContext *s, arg_VSUB_sp *a)
102
return do_vfp_3op_sp(s, gen_helper_vfp_subs, a->vd, a->vn, a->vm, false);
103
}
104
105
-static bool trans_VSUB_dp(DisasContext *s, arg_VSUB_sp *a)
106
+static bool trans_VSUB_dp(DisasContext *s, arg_VSUB_dp *a)
107
{
108
return do_vfp_3op_dp(s, gen_helper_vfp_subd, a->vd, a->vn, a->vm, false);
109
}
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VDIV_sp(DisasContext *s, arg_VDIV_sp *a)
111
return do_vfp_3op_sp(s, gen_helper_vfp_divs, a->vd, a->vn, a->vm, false);
112
}
113
114
-static bool trans_VDIV_dp(DisasContext *s, arg_VDIV_sp *a)
115
+static bool trans_VDIV_dp(DisasContext *s, arg_VDIV_dp *a)
116
{
117
return do_vfp_3op_dp(s, gen_helper_vfp_divd, a->vd, a->vn, a->vm, false);
118
}
119
@@ -XXX,XX +XXX,XX @@ static bool trans_VFM_sp(DisasContext *s, arg_VFM_sp *a)
120
return true;
121
}
122
123
-static bool trans_VFM_dp(DisasContext *s, arg_VFM_sp *a)
124
+static bool trans_VFM_dp(DisasContext *s, arg_VFM_dp *a)
125
{
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;
130
}
131
132
-static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_sp *a)
133
+static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
134
{
135
TCGv_ptr fpst;
136
TCGv_i64 tmp;
137
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_sp(DisasContext *s, arg_VRINTZ_sp *a)
138
return true;
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;
73
--
146
--
74
2.16.2
147
2.20.1
75
148
76
149
diff view generated by jsdifflib
New patch
1
1
The architecture permits FPUs which have only single-precision
2
support, not double-precision; Cortex-M4 and Cortex-M33 are
3
both like that. Add the necessary checks on the MVFR0 FPDP
4
field so that we UNDEF any double-precision instructions on
5
CPUs like this.
6
7
Note that even if FPDP==0 the insns like VMOV-to/from-gpreg,
8
VLDM/VSTM, VLDR/VSTR which take double precision registers
9
still exist.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190614104457.24703-3-peter.maydell@linaro.org
14
---
15
target/arm/cpu.h | 6 +++
16
target/arm/translate-vfp.inc.c | 84 ++++++++++++++++++++++++++++++++++
17
2 files changed, 90 insertions(+)
18
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
24
return FIELD_EX64(id->mvfr0, MVFR0, FPSHVEC) > 0;
25
}
26
27
+static inline bool isar_feature_aa32_fpdp(const ARMISARegisters *id)
28
+{
29
+ /* Return true if CPU supports double precision floating point */
30
+ return FIELD_EX64(id->mvfr0, MVFR0, FPDP) > 0;
31
+}
32
+
33
/*
34
* We always set the FP and SIMD FP16 fields to indicate identical
35
* levels of support (assuming SIMD is implemented at all), so
36
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-vfp.inc.c
39
+++ b/target/arm/translate-vfp.inc.c
40
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
41
((a->vm | a->vn | a->vd) & 0x10)) {
42
return false;
43
}
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
}
264
--
265
2.20.1
266
267
diff view generated by jsdifflib