1
Arm queue -- mostly the first slice of my Musca patches.
1
Hi; here's the first target-arm pullreq for the 7.0 cycle.
2
2
3
thanks
3
thanks
4
-- PMM
4
-- PMM
5
5
6
The following changes since commit fc3dbb90f2eb069801bfb4cfe9cbc83cf9c5f4a9:
6
The following changes since commit 76b56fdfc9fa43ec6e5986aee33f108c6c6a511e:
7
7
8
Merge remote-tracking branch 'remotes/jnsnow/tags/bitmaps-pull-request' into staging (2019-02-21 13:09:33 +0000)
8
Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2021-12-14 12:46:18 -0800)
9
9
10
are available in the Git repository at:
10
are available in the Git repository at:
11
11
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190221
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20211215
13
13
14
for you to fetch changes up to 3733f80308d2a7f23f5e39b039e0547aba6c07f1:
14
for you to fetch changes up to aed176558806674d030a8305d989d4e6a5073359:
15
15
16
hw/arm/armsse: Make 0x5... alias region work for per-CPU devices (2019-02-21 18:17:48 +0000)
16
tests/acpi: add expected blob for VIOT test on virt machine (2021-12-15 10:35:26 +0000)
17
17
18
----------------------------------------------------------------
18
----------------------------------------------------------------
19
target-arm queue:
19
target-arm queue:
20
* Model the Arm "Musca" development boards: "musca-a" and "musca-b1"
20
* ITS: error reporting cleanup
21
* Implement the ARMv8.3-JSConv extension
21
* aspeed: improve documentation
22
* v8M MPU should use background region as default, not always
22
* Fix STM32F2XX USART data register readout
23
* Stop unintentional sign extension in pmu_init
23
* allow emulated GICv3 to be disabled in non-TCG builds
24
* fix exception priority for singlestep, misaligned PC, bp, etc
25
* Correct calculation of tlb range invalidate length
26
* npcm7xx_emc: fix missing queue_flush
27
* virt: Add VIOT ACPI table for virtio-iommu
28
* target/i386: Use assert() to sanity-check b1 in SSE decode
29
* Don't include qemu-common unnecessarily
24
30
25
----------------------------------------------------------------
31
----------------------------------------------------------------
26
Aaron Lindsay OS (1):
32
Alex Bennée (1):
27
target/arm: Stop unintentional sign extension in pmu_init
33
hw/intc: clean-up error reporting for failed ITS cmd
28
34
29
Peter Maydell (16):
35
Jean-Philippe Brucker (8):
30
hw/arm/armsse: Fix memory leak in error-exit path
36
hw/arm/virt-acpi-build: Add VIOT table for virtio-iommu
31
target/arm: v8M MPU should use background region as default, not always
37
hw/arm/virt: Remove device tree restriction for virtio-iommu
32
hw/misc/tz-ppc: Support having unused ports in the middle of the range
38
hw/arm/virt: Reject instantiation of multiple IOMMUs
33
hw/timer/pl031: Allow use as an embedded-struct device
39
hw/arm/virt: Use object_property_set instead of qdev_prop_set
34
hw/timer/pl031: Convert to using trace events
40
tests/acpi: allow updates of VIOT expected data files
35
hw/char/pl011: Allow use as an embedded-struct device
41
tests/acpi: add test case for VIOT
36
hw/char/pl011: Support all interrupt lines
42
tests/acpi: add expected blobs for VIOT test on q35 machine
37
hw/char/pl011: Use '0x' prefix when logging hex numbers
43
tests/acpi: add expected blob for VIOT test on virt machine
38
hw/arm/armsse: Document SRAM_ADDR_WIDTH property in header comment
39
hw/arm/armsse: Allow boards to specify init-svtor
40
hw/arm/musca.c: Implement models of the Musca-A and -B1 boards
41
hw/arm/musca: Add PPCs
42
hw/arm/musca: Add MPCs
43
hw/arm/musca: Wire up PL031 RTC
44
hw/arm/musca: Wire up PL011 UARTs
45
hw/arm/armsse: Make 0x5... alias region work for per-CPU devices
46
44
47
Richard Henderson (4):
45
Joel Stanley (4):
48
target/arm: Restructure disas_fp_int_conv
46
docs: aspeed: Add new boards
49
target/arm: Split out vfp_helper.c
47
docs: aspeed: Update OpenBMC image URL
50
target/arm: Rearrange Floating-point data-processing (2 regs)
48
docs: aspeed: Give an example of booting a kernel
51
target/arm: Implement ARMv8.3-JSConv
49
docs: aspeed: ADC is now modelled
52
50
53
hw/arm/Makefile.objs | 1 +
51
Olivier Hériveaux (1):
54
target/arm/Makefile.objs | 2 +-
52
Fix STM32F2XX USART data register readout
55
include/hw/arm/armsse.h | 7 +-
56
include/hw/char/pl011.h | 34 ++
57
include/hw/misc/tz-ppc.h | 8 +-
58
include/hw/timer/pl031.h | 44 ++
59
target/arm/cpu.h | 10 +
60
target/arm/helper.h | 3 +
61
hw/arm/armsse.c | 44 +-
62
hw/arm/musca.c | 669 ++++++++++++++++++++++
63
hw/char/pl011.c | 81 +--
64
hw/misc/tz-ppc.c | 32 ++
65
hw/timer/pl031.c | 80 ++-
66
target/arm/cpu.c | 1 +
67
target/arm/cpu64.c | 2 +
68
target/arm/helper.c | 1072 +----------------------------------
69
target/arm/translate-a64.c | 120 ++--
70
target/arm/translate.c | 237 ++++----
71
target/arm/vfp_helper.c | 1176 +++++++++++++++++++++++++++++++++++++++
72
MAINTAINERS | 7 +
73
default-configs/arm-softmmu.mak | 1 +
74
hw/timer/trace-events | 6 +
75
22 files changed, 2307 insertions(+), 1330 deletions(-)
76
create mode 100644 include/hw/timer/pl031.h
77
create mode 100644 hw/arm/musca.c
78
create mode 100644 target/arm/vfp_helper.c
79
53
54
Patrick Venture (1):
55
hw/net: npcm7xx_emc fix missing queue_flush
56
57
Peter Maydell (6):
58
target/i386: Use assert() to sanity-check b1 in SSE decode
59
include/hw/i386: Don't include qemu-common.h in .h files
60
target/hexagon/cpu.h: don't include qemu-common.h
61
target/rx/cpu.h: Don't include qemu-common.h
62
hw/arm: Don't include qemu-common.h unnecessarily
63
target/arm: Correct calculation of tlb range invalidate length
64
65
Philippe Mathieu-Daudé (2):
66
hw/intc/arm_gicv3: Extract gicv3_set_gicv3state from arm_gicv3_cpuif.c
67
hw/intc/arm_gicv3: Introduce CONFIG_ARM_GIC_TCG Kconfig selector
68
69
Richard Henderson (10):
70
target/arm: Hoist pc_next to a local variable in aarch64_tr_translate_insn
71
target/arm: Hoist pc_next to a local variable in arm_tr_translate_insn
72
target/arm: Hoist pc_next to a local variable in thumb_tr_translate_insn
73
target/arm: Split arm_pre_translate_insn
74
target/arm: Advance pc for arch single-step exception
75
target/arm: Split compute_fsr_fsc out of arm_deliver_fault
76
target/arm: Take an exception if PC is misaligned
77
target/arm: Assert thumb pc is aligned
78
target/arm: Suppress bp for exceptions with more priority
79
tests/tcg: Add arm and aarch64 pc alignment tests
80
81
docs/system/arm/aspeed.rst | 26 ++++++++++++----
82
include/hw/i386/microvm.h | 1 -
83
include/hw/i386/x86.h | 1 -
84
target/arm/helper.h | 1 +
85
target/arm/syndrome.h | 5 +++
86
target/hexagon/cpu.h | 1 -
87
target/rx/cpu.h | 1 -
88
hw/arm/boot.c | 1 -
89
hw/arm/digic_boards.c | 1 -
90
hw/arm/highbank.c | 1 -
91
hw/arm/npcm7xx_boards.c | 1 -
92
hw/arm/sbsa-ref.c | 1 -
93
hw/arm/stm32f405_soc.c | 1 -
94
hw/arm/vexpress.c | 1 -
95
hw/arm/virt-acpi-build.c | 7 +++++
96
hw/arm/virt.c | 21 ++++++-------
97
hw/char/stm32f2xx_usart.c | 3 +-
98
hw/intc/arm_gicv3.c | 2 +-
99
hw/intc/arm_gicv3_cpuif.c | 10 +-----
100
hw/intc/arm_gicv3_cpuif_common.c | 22 +++++++++++++
101
hw/intc/arm_gicv3_its.c | 39 +++++++++++++++--------
102
hw/net/npcm7xx_emc.c | 18 +++++------
103
hw/virtio/virtio-iommu-pci.c | 12 ++------
104
linux-user/aarch64/cpu_loop.c | 46 ++++++++++++++++------------
105
linux-user/hexagon/cpu_loop.c | 1 +
106
target/arm/debug_helper.c | 23 ++++++++++++++
107
target/arm/gdbstub.c | 9 ++++--
108
target/arm/helper.c | 6 ++--
109
target/arm/machine.c | 10 ++++++
110
target/arm/tlb_helper.c | 63 ++++++++++++++++++++++++++++----------
111
target/arm/translate-a64.c | 23 ++++++++++++--
112
target/arm/translate.c | 58 ++++++++++++++++++++++++++---------
113
target/i386/tcg/translate.c | 12 ++------
114
tests/qtest/bios-tables-test.c | 38 +++++++++++++++++++++++
115
tests/tcg/aarch64/pcalign-a64.c | 37 ++++++++++++++++++++++
116
tests/tcg/arm/pcalign-a32.c | 46 ++++++++++++++++++++++++++++
117
hw/arm/Kconfig | 1 +
118
hw/intc/Kconfig | 5 +++
119
hw/intc/meson.build | 11 ++++---
120
tests/data/acpi/q35/DSDT.viot | Bin 0 -> 9398 bytes
121
tests/data/acpi/q35/VIOT.viot | Bin 0 -> 112 bytes
122
tests/data/acpi/virt/VIOT | Bin 0 -> 88 bytes
123
tests/tcg/aarch64/Makefile.target | 4 +--
124
tests/tcg/arm/Makefile.target | 4 +++
125
44 files changed, 429 insertions(+), 145 deletions(-)
126
create mode 100644 hw/intc/arm_gicv3_cpuif_common.c
127
create mode 100644 tests/tcg/aarch64/pcalign-a64.c
128
create mode 100644 tests/tcg/arm/pcalign-a32.c
129
create mode 100644 tests/data/acpi/q35/DSDT.viot
130
create mode 100644 tests/data/acpi/q35/VIOT.viot
131
create mode 100644 tests/data/acpi/virt/VIOT
132
diff view generated by jsdifflib
New patch
1
From: Alex Bennée <alex.bennee@linaro.org>
1
2
3
While trying to debug a GIC ITS failure I saw some guest errors that
4
had poor formatting as well as leaving me confused as to what failed.
5
As most of the checks aren't possible without a valid dte split that
6
check apart and then check the other conditions in steps. This avoids
7
us relying on undefined data.
8
9
I still get a failure with the current kvm-unit-tests but at least I
10
know (partially) why now:
11
12
Exception return from AArch64 EL1 to AArch64 EL1 PC 0x40080588
13
PASS: gicv3: its-trigger: inv/invall: dev2/eventid=20 now triggers an LPI
14
ITS: MAPD devid=2 size = 0x8 itt=0x40430000 valid=0
15
INT dev_id=2 event_id=20
16
process_its_cmd: invalid command attributes: invalid dte: 0 for 2 (MEM_TX: 0)
17
PASS: gicv3: its-trigger: mapd valid=false: no LPI after device unmap
18
SUMMARY: 6 tests, 1 unexpected failures
19
20
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Message-id: 20211112170454.3158925-1-alex.bennee@linaro.org
23
Cc: Shashi Mallela <shashi.mallela@linaro.org>
24
Cc: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
27
hw/intc/arm_gicv3_its.c | 39 +++++++++++++++++++++++++++------------
28
1 file changed, 27 insertions(+), 12 deletions(-)
29
30
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/intc/arm_gicv3_its.c
33
+++ b/hw/intc/arm_gicv3_its.c
34
@@ -XXX,XX +XXX,XX @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
35
if (res != MEMTX_OK) {
36
return result;
37
}
38
+ } else {
39
+ qemu_log_mask(LOG_GUEST_ERROR,
40
+ "%s: invalid command attributes: "
41
+ "invalid dte: %"PRIx64" for %d (MEM_TX: %d)\n",
42
+ __func__, dte, devid, res);
43
+ return result;
44
}
45
46
- if ((devid > s->dt.maxids.max_devids) || !dte_valid || !ite_valid ||
47
- !cte_valid || (eventid > max_eventid)) {
48
+
49
+ /*
50
+ * In this implementation, in case of guest errors we ignore the
51
+ * command and move onto the next command in the queue.
52
+ */
53
+ if (devid > s->dt.maxids.max_devids) {
54
qemu_log_mask(LOG_GUEST_ERROR,
55
- "%s: invalid command attributes "
56
- "devid %d or eventid %d or invalid dte %d or"
57
- "invalid cte %d or invalid ite %d\n",
58
- __func__, devid, eventid, dte_valid, cte_valid,
59
- ite_valid);
60
- /*
61
- * in this implementation, in case of error
62
- * we ignore this command and move onto the next
63
- * command in the queue
64
- */
65
+ "%s: invalid command attributes: devid %d>%d",
66
+ __func__, devid, s->dt.maxids.max_devids);
67
+
68
+ } else if (!dte_valid || !ite_valid || !cte_valid) {
69
+ qemu_log_mask(LOG_GUEST_ERROR,
70
+ "%s: invalid command attributes: "
71
+ "dte: %s, ite: %s, cte: %s\n",
72
+ __func__,
73
+ dte_valid ? "valid" : "invalid",
74
+ ite_valid ? "valid" : "invalid",
75
+ cte_valid ? "valid" : "invalid");
76
+ } else if (eventid > max_eventid) {
77
+ qemu_log_mask(LOG_GUEST_ERROR,
78
+ "%s: invalid command attributes: eventid %d > %d\n",
79
+ __func__, eventid, max_eventid);
80
} else {
81
/*
82
* Current implementation only supports rdbase == procnum
83
--
84
2.25.1
85
86
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
Add X11, FP5280G2, G220A, Rainier and Fuji. Mention that Swift will be
4
removed in v7.0.
5
6
Signed-off-by: Joel Stanley <joel@jms.id.au>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20211117065752.330632-2-joel@jms.id.au
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/aspeed.rst | 7 ++++++-
12
1 file changed, 6 insertions(+), 1 deletion(-)
13
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/aspeed.rst
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@ AST2400 SoC based machines :
19
20
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
21
- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
22
+- ``supermicrox11-bmc`` Supermicro X11 BMC
23
24
AST2500 SoC based machines :
25
26
@@ -XXX,XX +XXX,XX @@ AST2500 SoC based machines :
27
- ``romulus-bmc`` OpenPOWER Romulus POWER9 BMC
28
- ``witherspoon-bmc`` OpenPOWER Witherspoon POWER9 BMC
29
- ``sonorapass-bmc`` OCP SonoraPass BMC
30
-- ``swift-bmc`` OpenPOWER Swift BMC POWER9
31
+- ``swift-bmc`` OpenPOWER Swift BMC POWER9 (to be removed in v7.0)
32
+- ``fp5280g2-bmc`` Inspur FP5280G2 BMC
33
+- ``g220a-bmc`` Bytedance G220A BMC
34
35
AST2600 SoC based machines :
36
37
- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex-A7)
38
- ``tacoma-bmc`` OpenPOWER Witherspoon POWER9 AST2600 BMC
39
+- ``rainier-bmc`` IBM Rainier POWER10 BMC
40
+- ``fuji-bmc`` Facebook Fuji BMC
41
42
Supported devices
43
-----------------
44
--
45
2.25.1
46
47
diff view generated by jsdifflib
1
The Musca boards have DAPLink firmware that sets the initial
1
From: Joel Stanley <joel@jms.id.au>
2
secure VTOR value (the location of the vector table) differently
3
depending on the boot mode (from flash, from RAM, etc). Export
4
the init-svtor as a QOM property of the ARMSSE object so that
5
the board can change it.
6
2
3
This is the latest URL for the OpenBMC CI. The old URL still works, but
4
redirects.
5
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Message-id: 20211117065752.330632-3-joel@jms.id.au
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
---
10
---
11
include/hw/arm/armsse.h | 3 +++
11
docs/system/arm/aspeed.rst | 2 +-
12
hw/arm/armsse.c | 8 ++++----
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
2 files changed, 7 insertions(+), 4 deletions(-)
14
13
15
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/armsse.h
16
--- a/docs/system/arm/aspeed.rst
18
+++ b/include/hw/arm/armsse.h
17
+++ b/docs/system/arm/aspeed.rst
19
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ The Aspeed machines can be started using the ``-kernel`` option to
20
* if necessary.)
19
load a Linux kernel or from a firmware. Images can be downloaded from
21
* + QOM property "SRAM_ADDR_WIDTH" sets the number of bits used for the
20
the OpenBMC jenkins :
22
* address of each SRAM bank (and thus the total amount of internal SRAM)
21
23
+ * + QOM property "init-svtor" sets the initial value of the CPU SVTOR register
22
- https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/distro=ubuntu,label=docker-builder
24
+ * (where it expects to load the PC and SP from the vector table on reset)
23
+ https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/
25
* + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts for CPU 0,
24
26
* which are wired to its NVIC lines 32 .. n+32
25
or directly from the OpenBMC GitHub release repository :
27
* + Named GPIO inputs "EXP_CPU1_IRQ" 0..n are the expansion interrupts for
28
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
29
uint32_t exp_numirq;
30
uint32_t mainclk_frq;
31
uint32_t sram_addr_width;
32
+ uint32_t init_svtor;
33
} ARMSSE;
34
35
typedef struct ARMSSEInfo ARMSSEInfo;
36
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/armsse.c
39
+++ b/hw/arm/armsse.c
40
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
41
* the INITSVTOR* registers before powering up the CPUs in any case,
42
* so the hardware's default value doesn't matter. QEMU doesn't emulate
43
* the control processor, so instead we behave in the way that the
44
- * firmware does. All boards currently known about have firmware that
45
- * sets the INITSVTOR0 and INITSVTOR1 registers to 0x10000000, like the
46
- * IoTKit default. We can make this more configurable if necessary.
47
+ * firmware does. The initial value is configurable by the board code
48
+ * to match whatever its firmware does.
49
*/
50
- qdev_prop_set_uint32(cpudev, "init-svtor", 0x10000000);
51
+ qdev_prop_set_uint32(cpudev, "init-svtor", s->init_svtor);
52
/*
53
* Start all CPUs except CPU0 powered down. In real hardware it is
54
* a configurable property of the SSE-200 which CPUs start powered up
55
@@ -XXX,XX +XXX,XX @@ static Property armsse_properties[] = {
56
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
57
DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
58
DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
59
+ DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
60
DEFINE_PROP_END_OF_LIST()
61
};
62
26
63
--
27
--
64
2.20.1
28
2.25.1
65
29
66
30
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
A common use case for the ASPEED machine is to boot a Linux kernel.
4
Provide a full example command line.
5
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Message-id: 20211117065752.330632-4-joel@jms.id.au
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/aspeed.rst | 15 ++++++++++++---
12
1 file changed, 12 insertions(+), 3 deletions(-)
13
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/aspeed.rst
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@ Missing devices
19
Boot options
20
------------
21
22
-The Aspeed machines can be started using the ``-kernel`` option to
23
-load a Linux kernel or from a firmware. Images can be downloaded from
24
-the OpenBMC jenkins :
25
+The Aspeed machines can be started using the ``-kernel`` and ``-dtb`` options
26
+to load a Linux kernel or from a firmware. Images can be downloaded from the
27
+OpenBMC jenkins :
28
29
https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/
30
31
@@ -XXX,XX +XXX,XX @@ or directly from the OpenBMC GitHub release repository :
32
33
https://github.com/openbmc/openbmc/releases
34
35
+To boot a kernel directly from a Linux build tree:
36
+
37
+.. code-block:: bash
38
+
39
+ $ qemu-system-arm -M ast2600-evb -nographic \
40
+ -kernel arch/arm/boot/zImage \
41
+ -dtb arch/arm/boot/dts/aspeed-ast2600-evb.dtb \
42
+ -initrd rootfs.cpio
43
+
44
The image should be attached as an MTD drive. Run :
45
46
.. code-block:: bash
47
--
48
2.25.1
49
50
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
Move it to the supported list.
4
5
Signed-off-by: Joel Stanley <joel@jms.id.au>
6
Message-id: 20211117065752.330632-5-joel@jms.id.au
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
docs/system/arm/aspeed.rst | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
11
12
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
13
index XXXXXXX..XXXXXXX 100644
14
--- a/docs/system/arm/aspeed.rst
15
+++ b/docs/system/arm/aspeed.rst
16
@@ -XXX,XX +XXX,XX @@ Supported devices
17
* Front LEDs (PCA9552 on I2C bus)
18
* LPC Peripheral Controller (a subset of subdevices are supported)
19
* Hash/Crypto Engine (HACE) - Hash support only. TODO: HMAC and RSA
20
+ * ADC
21
22
23
Missing devices
24
---------------
25
26
* Coprocessor support
27
- * ADC (out of tree implementation)
28
* PWM and Fan Controller
29
* Slave GPIO Controller
30
* Super I/O Controller
31
--
32
2.25.1
33
34
diff view generated by jsdifflib
New patch
1
From: Olivier Hériveaux <olivier.heriveaux@ledger.fr>
1
2
3
Fix issue where the data register may be overwritten by next character
4
reception before being read and returned.
5
6
Signed-off-by: Olivier Hériveaux <olivier.heriveaux@ledger.fr>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20211128120723.4053-1-olivier.heriveaux@ledger.fr
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/char/stm32f2xx_usart.c | 3 ++-
13
1 file changed, 2 insertions(+), 1 deletion(-)
14
15
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/char/stm32f2xx_usart.c
18
+++ b/hw/char/stm32f2xx_usart.c
19
@@ -XXX,XX +XXX,XX @@ static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr,
20
return retvalue;
21
case USART_DR:
22
DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) s->usart_dr);
23
+ retvalue = s->usart_dr & 0x3FF;
24
s->usart_sr &= ~USART_SR_RXNE;
25
qemu_chr_fe_accept_input(&s->chr);
26
qemu_set_irq(s->irq, 0);
27
- return s->usart_dr & 0x3FF;
28
+ return retvalue;
29
case USART_BRR:
30
return s->usart_brr;
31
case USART_CR1:
32
--
33
2.25.1
34
35
diff view generated by jsdifflib
1
The Musca-A and Musca-B1 development boards are based on the
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
SSE-200 subsystem for embedded. Implement an initial skeleton
3
model of these boards, which are similar but not identical.
4
2
5
This commit creates the board model with the SSE and the IRQ
3
gicv3_set_gicv3state() is used by arm_gicv3_common.c in
6
splitters to wire IRQs up to its two CPUs. As yet there
4
arm_gicv3_common_realize(). Since we want to restrict
7
are no devices and no memory: these will be added later.
5
arm_gicv3_cpuif.c to TCG, extract gicv3_set_gicv3state()
6
to a new file. Add this file to the meson 'specific'
7
source set, since it needs access to "cpu.h".
8
8
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20211115223619.2599282-2-philmd@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
---
13
---
12
hw/arm/Makefile.objs | 1 +
14
hw/intc/arm_gicv3_cpuif.c | 10 +---------
13
hw/arm/musca.c | 197 ++++++++++++++++++++++++++++++++
15
hw/intc/arm_gicv3_cpuif_common.c | 22 ++++++++++++++++++++++
14
MAINTAINERS | 6 +
16
hw/intc/meson.build | 1 +
15
default-configs/arm-softmmu.mak | 1 +
17
3 files changed, 24 insertions(+), 9 deletions(-)
16
4 files changed, 205 insertions(+)
18
create mode 100644 hw/intc/arm_gicv3_cpuif_common.c
17
create mode 100644 hw/arm/musca.c
18
19
19
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
20
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
20
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/Makefile.objs
22
--- a/hw/intc/arm_gicv3_cpuif.c
22
+++ b/hw/arm/Makefile.objs
23
+++ b/hw/intc/arm_gicv3_cpuif.c
23
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
24
@@ -XXX,XX +XXX,XX @@
24
obj-$(CONFIG_MPS2) += mps2.o
25
/*
25
obj-$(CONFIG_MPS2) += mps2-tz.o
26
- * ARM Generic Interrupt Controller v3
26
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
27
+ * ARM Generic Interrupt Controller v3 (emulation)
27
+obj-$(CONFIG_MUSCA) += musca.o
28
*
28
obj-$(CONFIG_ARMSSE) += armsse.o
29
* Copyright (c) 2016 Linaro Limited
29
obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
30
* Written by Peter Maydell
30
obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
31
@@ -XXX,XX +XXX,XX @@
31
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
32
#include "hw/irq.h"
33
#include "cpu.h"
34
35
-void gicv3_set_gicv3state(CPUState *cpu, GICv3CPUState *s)
36
-{
37
- ARMCPU *arm_cpu = ARM_CPU(cpu);
38
- CPUARMState *env = &arm_cpu->env;
39
-
40
- env->gicv3state = (void *)s;
41
-};
42
-
43
static GICv3CPUState *icc_cs_from_env(CPUARMState *env)
44
{
45
return env->gicv3state;
46
diff --git a/hw/intc/arm_gicv3_cpuif_common.c b/hw/intc/arm_gicv3_cpuif_common.c
32
new file mode 100644
47
new file mode 100644
33
index XXXXXXX..XXXXXXX
48
index XXXXXXX..XXXXXXX
34
--- /dev/null
49
--- /dev/null
35
+++ b/hw/arm/musca.c
50
+++ b/hw/intc/arm_gicv3_cpuif_common.c
36
@@ -XXX,XX +XXX,XX @@
51
@@ -XXX,XX +XXX,XX @@
52
+/* SPDX-License-Identifier: GPL-2.0-or-later */
37
+/*
53
+/*
38
+ * Arm Musca-B1 test chip board emulation
54
+ * ARM Generic Interrupt Controller v3
39
+ *
55
+ *
40
+ * Copyright (c) 2019 Linaro Limited
56
+ * Copyright (c) 2016 Linaro Limited
41
+ * Written by Peter Maydell
57
+ * Written by Peter Maydell
42
+ *
58
+ *
43
+ * This program is free software; you can redistribute it and/or modify
59
+ * This code is licensed under the GPL, version 2 or (at your option)
44
+ * it under the terms of the GNU General Public License version 2 or
60
+ * any later version.
45
+ * (at your option) any later version.
46
+ */
47
+
48
+/*
49
+ * The Musca boards are a reference implementation of a system using
50
+ * the SSE-200 subsystem for embedded:
51
+ * https://developer.arm.com/products/system-design/development-boards/iot-test-chips-and-boards/musca-a-test-chip-board
52
+ * https://developer.arm.com/products/system-design/development-boards/iot-test-chips-and-boards/musca-b-test-chip-board
53
+ * We model the A and B1 variants of this board, as described in the TRMs:
54
+ * http://infocenter.arm.com/help/topic/com.arm.doc.101107_0000_00_en/index.html
55
+ * http://infocenter.arm.com/help/topic/com.arm.doc.101312_0000_00_en/index.html
56
+ */
61
+ */
57
+
62
+
58
+#include "qemu/osdep.h"
63
+#include "qemu/osdep.h"
59
+#include "qemu/error-report.h"
64
+#include "gicv3_internal.h"
60
+#include "qapi/error.h"
65
+#include "cpu.h"
61
+#include "exec/address-spaces.h"
62
+#include "hw/arm/arm.h"
63
+#include "hw/arm/armsse.h"
64
+#include "hw/boards.h"
65
+#include "hw/core/split-irq.h"
66
+
66
+
67
+#define MUSCA_NUMIRQ_MAX 96
67
+void gicv3_set_gicv3state(CPUState *cpu, GICv3CPUState *s)
68
+{
69
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
70
+ CPUARMState *env = &arm_cpu->env;
68
+
71
+
69
+typedef enum MuscaType {
72
+ env->gicv3state = (void *)s;
70
+ MUSCA_A,
71
+ MUSCA_B1,
72
+} MuscaType;
73
+
74
+typedef struct {
75
+ MachineClass parent;
76
+ MuscaType type;
77
+ uint32_t init_svtor;
78
+ int sram_addr_width;
79
+ int num_irqs;
80
+} MuscaMachineClass;
81
+
82
+typedef struct {
83
+ MachineState parent;
84
+
85
+ ARMSSE sse;
86
+ SplitIRQ cpu_irq_splitter[MUSCA_NUMIRQ_MAX];
87
+} MuscaMachineState;
88
+
89
+#define TYPE_MUSCA_MACHINE "musca"
90
+#define TYPE_MUSCA_A_MACHINE MACHINE_TYPE_NAME("musca-a")
91
+#define TYPE_MUSCA_B1_MACHINE MACHINE_TYPE_NAME("musca-b1")
92
+
93
+#define MUSCA_MACHINE(obj) \
94
+ OBJECT_CHECK(MuscaMachineState, obj, TYPE_MUSCA_MACHINE)
95
+#define MUSCA_MACHINE_GET_CLASS(obj) \
96
+ OBJECT_GET_CLASS(MuscaMachineClass, obj, TYPE_MUSCA_MACHINE)
97
+#define MUSCA_MACHINE_CLASS(klass) \
98
+ OBJECT_CLASS_CHECK(MuscaMachineClass, klass, TYPE_MUSCA_MACHINE)
99
+
100
+/*
101
+ * Main SYSCLK frequency in Hz
102
+ * TODO this should really be different for the two cores, but we
103
+ * don't model that in our SSE-200 model yet.
104
+ */
105
+#define SYSCLK_FRQ 40000000
106
+
107
+static void musca_init(MachineState *machine)
108
+{
109
+ MuscaMachineState *mms = MUSCA_MACHINE(machine);
110
+ MuscaMachineClass *mmc = MUSCA_MACHINE_GET_CLASS(mms);
111
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
112
+ MemoryRegion *system_memory = get_system_memory();
113
+ DeviceState *ssedev;
114
+ int i;
115
+
116
+ assert(mmc->num_irqs <= MUSCA_NUMIRQ_MAX);
117
+
118
+ if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
119
+ error_report("This board can only be used with CPU %s",
120
+ mc->default_cpu_type);
121
+ exit(1);
122
+ }
123
+
124
+ sysbus_init_child_obj(OBJECT(machine), "sse-200", &mms->sse,
125
+ sizeof(mms->sse), TYPE_SSE200);
126
+ ssedev = DEVICE(&mms->sse);
127
+ object_property_set_link(OBJECT(&mms->sse), OBJECT(system_memory),
128
+ "memory", &error_fatal);
129
+ qdev_prop_set_uint32(ssedev, "EXP_NUMIRQ", mmc->num_irqs);
130
+ qdev_prop_set_uint32(ssedev, "init-svtor", mmc->init_svtor);
131
+ qdev_prop_set_uint32(ssedev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
132
+ qdev_prop_set_uint32(ssedev, "MAINCLK", SYSCLK_FRQ);
133
+ object_property_set_bool(OBJECT(&mms->sse), true, "realized",
134
+ &error_fatal);
135
+
136
+ /*
137
+ * We need to create splitters to feed the IRQ inputs
138
+ * for each CPU in the SSE-200 from each device in the board.
139
+ */
140
+ for (i = 0; i < mmc->num_irqs; i++) {
141
+ char *name = g_strdup_printf("musca-irq-splitter%d", i);
142
+ SplitIRQ *splitter = &mms->cpu_irq_splitter[i];
143
+
144
+ object_initialize_child(OBJECT(machine), name,
145
+ splitter, sizeof(*splitter),
146
+ TYPE_SPLIT_IRQ, &error_fatal, NULL);
147
+ g_free(name);
148
+
149
+ object_property_set_int(OBJECT(splitter), 2, "num-lines",
150
+ &error_fatal);
151
+ object_property_set_bool(OBJECT(splitter), true, "realized",
152
+ &error_fatal);
153
+ qdev_connect_gpio_out(DEVICE(splitter), 0,
154
+ qdev_get_gpio_in_named(ssedev, "EXP_IRQ", i));
155
+ qdev_connect_gpio_out(DEVICE(splitter), 1,
156
+ qdev_get_gpio_in_named(ssedev,
157
+ "EXP_CPU1_IRQ", i));
158
+ }
159
+
160
+ armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x2000000);
161
+}
162
+
163
+static void musca_class_init(ObjectClass *oc, void *data)
164
+{
165
+ MachineClass *mc = MACHINE_CLASS(oc);
166
+
167
+ mc->default_cpus = 2;
168
+ mc->min_cpus = mc->default_cpus;
169
+ mc->max_cpus = mc->default_cpus;
170
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
171
+ mc->init = musca_init;
172
+}
173
+
174
+static void musca_a_class_init(ObjectClass *oc, void *data)
175
+{
176
+ MachineClass *mc = MACHINE_CLASS(oc);
177
+ MuscaMachineClass *mmc = MUSCA_MACHINE_CLASS(oc);
178
+
179
+ mc->desc = "ARM Musca-A board (dual Cortex-M33)";
180
+ mmc->type = MUSCA_A;
181
+ mmc->init_svtor = 0x10200000;
182
+ mmc->sram_addr_width = 15;
183
+ mmc->num_irqs = 64;
184
+}
185
+
186
+static void musca_b1_class_init(ObjectClass *oc, void *data)
187
+{
188
+ MachineClass *mc = MACHINE_CLASS(oc);
189
+ MuscaMachineClass *mmc = MUSCA_MACHINE_CLASS(oc);
190
+
191
+ mc->desc = "ARM Musca-B1 board (dual Cortex-M33)";
192
+ mmc->type = MUSCA_B1;
193
+ /*
194
+ * This matches the DAPlink firmware which boots from QSPI. There
195
+ * is also a firmware blob which boots from the eFlash, which
196
+ * uses init_svtor = 0x1A000000. QEMU doesn't currently support that,
197
+ * though we could in theory expose a machine property on the command
198
+ * line to allow the user to request eFlash boot.
199
+ */
200
+ mmc->init_svtor = 0x10000000;
201
+ mmc->sram_addr_width = 17;
202
+ mmc->num_irqs = 96;
203
+}
204
+
205
+static const TypeInfo musca_info = {
206
+ .name = TYPE_MUSCA_MACHINE,
207
+ .parent = TYPE_MACHINE,
208
+ .abstract = true,
209
+ .instance_size = sizeof(MuscaMachineState),
210
+ .class_size = sizeof(MuscaMachineClass),
211
+ .class_init = musca_class_init,
212
+};
73
+};
213
+
74
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
214
+static const TypeInfo musca_a_info = {
215
+ .name = TYPE_MUSCA_A_MACHINE,
216
+ .parent = TYPE_MUSCA_MACHINE,
217
+ .class_init = musca_a_class_init,
218
+};
219
+
220
+static const TypeInfo musca_b1_info = {
221
+ .name = TYPE_MUSCA_B1_MACHINE,
222
+ .parent = TYPE_MUSCA_MACHINE,
223
+ .class_init = musca_b1_class_init,
224
+};
225
+
226
+static void musca_machine_init(void)
227
+{
228
+ type_register_static(&musca_info);
229
+ type_register_static(&musca_a_info);
230
+ type_register_static(&musca_b1_info);
231
+}
232
+
233
+type_init(musca_machine_init);
234
diff --git a/MAINTAINERS b/MAINTAINERS
235
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
236
--- a/MAINTAINERS
76
--- a/hw/intc/meson.build
237
+++ b/MAINTAINERS
77
+++ b/hw/intc/meson.build
238
@@ -XXX,XX +XXX,XX @@ F: include/hw/misc/iotkit-sysinfo.h
78
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_PMU', if_true: files('xlnx-pmu-iomod-in
239
F: hw/misc/armsse-cpuid.c
79
240
F: include/hw/misc/armsse-cpuid.h
80
specific_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: files('allwinner-a10-pic.c'))
241
81
specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c', 'apic_common.c'))
242
+Musca
82
+specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_common.c'))
243
+M: Peter Maydell <peter.maydell@linaro.org>
83
specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif.c'))
244
+L: qemu-arm@nongnu.org
84
specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'))
245
+S: Maintained
85
specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
246
+F: hw/arm/musca.c
247
+
248
Musicpal
249
M: Jan Kiszka <jan.kiszka@web.de>
250
M: Peter Maydell <peter.maydell@linaro.org>
251
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
252
index XXXXXXX..XXXXXXX 100644
253
--- a/default-configs/arm-softmmu.mak
254
+++ b/default-configs/arm-softmmu.mak
255
@@ -XXX,XX +XXX,XX @@ CONFIG_TUSB6010=y
256
CONFIG_IMX=y
257
CONFIG_MAINSTONE=y
258
CONFIG_MPS2=y
259
+CONFIG_MUSCA=y
260
CONFIG_NSERIES=y
261
CONFIG_RASPI=y
262
CONFIG_REALVIEW=y
263
--
86
--
264
2.20.1
87
2.25.1
265
88
266
89
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
3
The TYPE_ARM_GICV3 device is an emulated one. When using
4
KVM, it is recommended to use the TYPE_KVM_ARM_GICV3 device
5
(which uses in-kernel support).
6
7
When using --with-devices-FOO, it is possible to build a
8
binary with a specific set of devices. When this binary is
9
restricted to KVM accelerator, the TYPE_ARM_GICV3 device is
10
irrelevant, and it is desirable to remove it from the binary.
11
12
Therefore introduce the CONFIG_ARM_GIC_TCG Kconfig selector
13
which select the files required to have the TYPE_ARM_GICV3
14
device, but also allowing to de-select this device.
15
16
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Message-id: 20211115223619.2599282-3-philmd@redhat.com
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
21
hw/intc/arm_gicv3.c | 2 +-
22
hw/intc/Kconfig | 5 +++++
23
hw/intc/meson.build | 10 ++++++----
24
3 files changed, 12 insertions(+), 5 deletions(-)
25
26
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/intc/arm_gicv3.c
29
+++ b/hw/intc/arm_gicv3.c
30
@@ -XXX,XX +XXX,XX @@
31
/*
32
- * ARM Generic Interrupt Controller v3
33
+ * ARM Generic Interrupt Controller v3 (emulation)
34
*
35
* Copyright (c) 2015 Huawei.
36
* Copyright (c) 2016 Linaro Limited
37
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/intc/Kconfig
40
+++ b/hw/intc/Kconfig
41
@@ -XXX,XX +XXX,XX @@ config APIC
42
select MSI_NONBROKEN
43
select I8259
44
45
+config ARM_GIC_TCG
46
+ bool
47
+ default y
48
+ depends on ARM_GIC && TCG
49
+
50
config ARM_GIC_KVM
51
bool
52
default y
53
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/intc/meson.build
56
+++ b/hw/intc/meson.build
57
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ARM_GIC', if_true: files(
58
'arm_gic.c',
59
'arm_gic_common.c',
60
'arm_gicv2m.c',
61
- 'arm_gicv3.c',
62
'arm_gicv3_common.c',
63
- 'arm_gicv3_dist.c',
64
'arm_gicv3_its_common.c',
65
- 'arm_gicv3_redist.c',
66
+))
67
+softmmu_ss.add(when: 'CONFIG_ARM_GIC_TCG', if_true: files(
68
+ 'arm_gicv3.c',
69
+ 'arm_gicv3_dist.c',
70
'arm_gicv3_its.c',
71
+ 'arm_gicv3_redist.c',
72
))
73
softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_pic.c'))
74
softmmu_ss.add(when: 'CONFIG_HEATHROW_PIC', if_true: files('heathrow_pic.c'))
75
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_PMU', if_true: files('xlnx-pmu-iomod-in
76
specific_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: files('allwinner-a10-pic.c'))
77
specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c', 'apic_common.c'))
78
specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_common.c'))
79
-specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif.c'))
80
+specific_ss.add(when: 'CONFIG_ARM_GIC_TCG', if_true: files('arm_gicv3_cpuif.c'))
81
specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'))
82
specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
83
specific_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_nvic.c'))
84
--
85
2.25.1
86
87
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
For opcodes 0-5, move some if conditions into the structure
4
of a switch statement. For opcodes 6 & 7, decode everything
5
at once with a second switch.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190215192302.27855-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
6
---
12
target/arm/translate-a64.c | 94 ++++++++++++++++++++------------------
7
target/arm/translate-a64.c | 7 ++++---
13
1 file changed, 49 insertions(+), 45 deletions(-)
8
1 file changed, 4 insertions(+), 3 deletions(-)
14
9
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
10
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
12
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
13
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
14
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
20
int type = extract32(insn, 22, 2);
15
{
21
bool sbit = extract32(insn, 29, 1);
16
DisasContext *s = container_of(dcbase, DisasContext, base);
22
bool sf = extract32(insn, 31, 1);
17
CPUARMState *env = cpu->env_ptr;
23
+ bool itof = false;
18
+ uint64_t pc = s->base.pc_next;
24
19
uint32_t insn;
25
if (sbit) {
20
26
- unallocated_encoding(s);
21
if (s->ss_active && !s->pstate_ss) {
27
- return;
22
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
28
+ goto do_unallocated;
23
return;
29
}
24
}
30
25
31
- if (opcode > 5) {
26
- s->pc_curr = s->base.pc_next;
32
- /* FMOV */
27
- insn = arm_ldl_code(env, &s->base, s->base.pc_next, s->sctlr_b);
33
- bool itof = opcode & 1;
28
+ s->pc_curr = pc;
34
-
29
+ insn = arm_ldl_code(env, &s->base, pc, s->sctlr_b);
35
- if (rmode >= 2) {
30
s->insn = insn;
36
- unallocated_encoding(s);
31
- s->base.pc_next += 4;
37
- return;
32
+ s->base.pc_next = pc + 4;
38
- }
33
39
-
34
s->fp_access_checked = false;
40
- switch (sf << 3 | type << 1 | rmode) {
35
s->sve_access_checked = false;
41
- case 0x0: /* 32 bit */
42
- case 0xa: /* 64 bit */
43
- case 0xd: /* 64 bit to top half of quad */
44
- break;
45
- case 0x6: /* 16-bit float, 32-bit int */
46
- case 0xe: /* 16-bit float, 64-bit int */
47
- if (dc_isar_feature(aa64_fp16, s)) {
48
- break;
49
- }
50
- /* fallthru */
51
- default:
52
- /* all other sf/type/rmode combinations are invalid */
53
- unallocated_encoding(s);
54
- return;
55
- }
56
-
57
- if (!fp_access_check(s)) {
58
- return;
59
- }
60
- handle_fmov(s, rd, rn, type, itof);
61
- } else {
62
- /* actual FP conversions */
63
- bool itof = extract32(opcode, 1, 1);
64
-
65
- if (rmode != 0 && opcode > 1) {
66
- unallocated_encoding(s);
67
- return;
68
+ switch (opcode) {
69
+ case 2: /* SCVTF */
70
+ case 3: /* UCVTF */
71
+ itof = true;
72
+ /* fallthru */
73
+ case 4: /* FCVTAS */
74
+ case 5: /* FCVTAU */
75
+ if (rmode != 0) {
76
+ goto do_unallocated;
77
}
78
+ /* fallthru */
79
+ case 0: /* FCVT[NPMZ]S */
80
+ case 1: /* FCVT[NPMZ]U */
81
switch (type) {
82
case 0: /* float32 */
83
case 1: /* float64 */
84
break;
85
case 3: /* float16 */
86
- if (dc_isar_feature(aa64_fp16, s)) {
87
- break;
88
+ if (!dc_isar_feature(aa64_fp16, s)) {
89
+ goto do_unallocated;
90
}
91
- /* fallthru */
92
+ break;
93
default:
94
- unallocated_encoding(s);
95
- return;
96
+ goto do_unallocated;
97
}
98
-
99
if (!fp_access_check(s)) {
100
return;
101
}
102
handle_fpfpcvt(s, rd, rn, opcode, itof, rmode, 64, sf, type);
103
+ break;
104
+
105
+ default:
106
+ switch (sf << 7 | type << 5 | rmode << 3 | opcode) {
107
+ case 0b01100110: /* FMOV half <-> 32-bit int */
108
+ case 0b01100111:
109
+ case 0b11100110: /* FMOV half <-> 64-bit int */
110
+ case 0b11100111:
111
+ if (!dc_isar_feature(aa64_fp16, s)) {
112
+ goto do_unallocated;
113
+ }
114
+ /* fallthru */
115
+ case 0b00000110: /* FMOV 32-bit */
116
+ case 0b00000111:
117
+ case 0b10100110: /* FMOV 64-bit */
118
+ case 0b10100111:
119
+ case 0b11001110: /* FMOV top half of 128-bit */
120
+ case 0b11001111:
121
+ if (!fp_access_check(s)) {
122
+ return;
123
+ }
124
+ itof = opcode & 1;
125
+ handle_fmov(s, rd, rn, type, itof);
126
+ break;
127
+
128
+ default:
129
+ do_unallocated:
130
+ unallocated_encoding(s);
131
+ return;
132
+ }
133
+ break;
134
}
135
}
136
137
--
36
--
138
2.20.1
37
2.25.1
139
38
140
39
diff view generated by jsdifflib
1
Convert the debug printing in the PL031 device to use trace events,
1
From: Richard Henderson <richard.henderson@linaro.org>
2
and augment it to cover the interesting parts of device operation.
3
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
---
6
---
8
hw/timer/pl031.c | 55 +++++++++++++++++++++++--------------------
7
target/arm/translate.c | 9 +++++----
9
hw/timer/trace-events | 6 +++++
8
1 file changed, 5 insertions(+), 4 deletions(-)
10
2 files changed, 36 insertions(+), 25 deletions(-)
11
9
12
diff --git a/hw/timer/pl031.c b/hw/timer/pl031.c
10
diff --git a/target/arm/translate.c b/target/arm/translate.c
13
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/timer/pl031.c
12
--- a/target/arm/translate.c
15
+++ b/hw/timer/pl031.c
13
+++ b/target/arm/translate.c
16
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
17
#include "sysemu/sysemu.h"
18
#include "qemu/cutils.h"
19
#include "qemu/log.h"
20
-
21
-//#define DEBUG_PL031
22
-
23
-#ifdef DEBUG_PL031
24
-#define DPRINTF(fmt, ...) \
25
-do { printf("pl031: " fmt , ## __VA_ARGS__); } while (0)
26
-#else
27
-#define DPRINTF(fmt, ...) do {} while(0)
28
-#endif
29
+#include "trace.h"
30
31
#define RTC_DR 0x00 /* Data read register */
32
#define RTC_MR 0x04 /* Match register */
33
@@ -XXX,XX +XXX,XX @@ static const unsigned char pl031_id[] = {
34
35
static void pl031_update(PL031State *s)
36
{
15
{
37
- qemu_set_irq(s->irq, s->is & s->im);
16
DisasContext *dc = container_of(dcbase, DisasContext, base);
38
+ uint32_t flags = s->is & s->im;
17
CPUARMState *env = cpu->env_ptr;
39
+
18
+ uint32_t pc = dc->base.pc_next;
40
+ trace_pl031_irq_state(flags);
19
unsigned int insn;
41
+ qemu_set_irq(s->irq, flags);
20
42
}
21
if (arm_pre_translate_insn(dc)) {
43
22
- dc->base.pc_next += 4;
44
static void pl031_interrupt(void * opaque)
23
+ dc->base.pc_next = pc + 4;
45
@@ -XXX,XX +XXX,XX @@ static void pl031_interrupt(void * opaque)
24
return;
46
PL031State *s = (PL031State *)opaque;
47
48
s->is = 1;
49
- DPRINTF("Alarm raised\n");
50
+ trace_pl031_alarm_raised();
51
pl031_update(s);
52
}
53
54
@@ -XXX,XX +XXX,XX @@ static void pl031_set_alarm(PL031State *s)
55
/* The timer wraps around. This subtraction also wraps in the same way,
56
and gives correct results when alarm < now_ticks. */
57
ticks = s->mr - pl031_get_count(s);
58
- DPRINTF("Alarm set in %ud ticks\n", ticks);
59
+ trace_pl031_set_alarm(ticks);
60
if (ticks == 0) {
61
timer_del(s->timer);
62
pl031_interrupt(s);
63
@@ -XXX,XX +XXX,XX @@ static uint64_t pl031_read(void *opaque, hwaddr offset,
64
unsigned size)
65
{
66
PL031State *s = (PL031State *)opaque;
67
-
68
- if (offset >= 0xfe0 && offset < 0x1000)
69
- return pl031_id[(offset - 0xfe0) >> 2];
70
+ uint64_t r;
71
72
switch (offset) {
73
case RTC_DR:
74
- return pl031_get_count(s);
75
+ r = pl031_get_count(s);
76
+ break;
77
case RTC_MR:
78
- return s->mr;
79
+ r = s->mr;
80
+ break;
81
case RTC_IMSC:
82
- return s->im;
83
+ r = s->im;
84
+ break;
85
case RTC_RIS:
86
- return s->is;
87
+ r = s->is;
88
+ break;
89
case RTC_LR:
90
- return s->lr;
91
+ r = s->lr;
92
+ break;
93
case RTC_CR:
94
/* RTC is permanently enabled. */
95
- return 1;
96
+ r = 1;
97
+ break;
98
case RTC_MIS:
99
- return s->is & s->im;
100
+ r = s->is & s->im;
101
+ break;
102
+ case 0xfe0 ... 0xfff:
103
+ r = pl031_id[(offset - 0xfe0) >> 2];
104
+ break;
105
case RTC_ICR:
106
qemu_log_mask(LOG_GUEST_ERROR,
107
"pl031: read of write-only register at offset 0x%x\n",
108
(int)offset);
109
+ r = 0;
110
break;
111
default:
112
qemu_log_mask(LOG_GUEST_ERROR,
113
"pl031_read: Bad offset 0x%x\n", (int)offset);
114
+ r = 0;
115
break;
116
}
25
}
117
26
118
- return 0;
27
- dc->pc_curr = dc->base.pc_next;
119
+ trace_pl031_read(offset, r);
28
- insn = arm_ldl_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
120
+ return r;
29
+ dc->pc_curr = pc;
121
}
30
+ insn = arm_ldl_code(env, &dc->base, pc, dc->sctlr_b);
122
31
dc->insn = insn;
123
static void pl031_write(void * opaque, hwaddr offset,
32
- dc->base.pc_next += 4;
124
@@ -XXX,XX +XXX,XX @@ static void pl031_write(void * opaque, hwaddr offset,
33
+ dc->base.pc_next = pc + 4;
125
{
34
disas_arm_insn(dc, insn);
126
PL031State *s = (PL031State *)opaque;
35
127
36
arm_post_translate_insn(dc);
128
+ trace_pl031_write(offset, value);
129
130
switch (offset) {
131
case RTC_LR:
132
@@ -XXX,XX +XXX,XX @@ static void pl031_write(void * opaque, hwaddr offset,
133
break;
134
case RTC_IMSC:
135
s->im = value & 1;
136
- DPRINTF("Interrupt mask %d\n", s->im);
137
pl031_update(s);
138
break;
139
case RTC_ICR:
140
@@ -XXX,XX +XXX,XX @@ static void pl031_write(void * opaque, hwaddr offset,
141
cleared when bit 0 of the written value is set. However the
142
arm926e documentation (DDI0287B) states that the interrupt is
143
cleared when any value is written. */
144
- DPRINTF("Interrupt cleared");
145
s->is = 0;
146
pl031_update(s);
147
break;
148
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
149
index XXXXXXX..XXXXXXX 100644
150
--- a/hw/timer/trace-events
151
+++ b/hw/timer/trace-events
152
@@ -XXX,XX +XXX,XX @@ xlnx_zynqmp_rtc_gettime(int year, int month, int day, int hour, int min, int sec
153
nrf51_timer_read(uint64_t addr, uint32_t value, unsigned size) "read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
154
nrf51_timer_write(uint64_t addr, uint32_t value, unsigned size) "write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
155
156
+# hw/timer/pl031.c
157
+pl031_irq_state(int level) "irq state %d"
158
+pl031_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
159
+pl031_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
160
+pl031_alarm_raised(void) "alarm raised"
161
+pl031_set_alarm(uint32_t ticks) "alarm set for %u ticks"
162
--
37
--
163
2.20.1
38
2.25.1
164
39
165
40
diff view generated by jsdifflib
1
From: Aaron Lindsay OS <aaron@os.amperecomputing.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This was introduced by
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
commit bf8d09694ccc07487cd73d7562081fdaec3370c8
5
target/arm: Don't clear supported PMU events when initializing PMCEID1
6
and identified by Coverity (CID 1398645).
7
8
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
9
Reported-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20190219144621.450-1-aaron@os.amperecomputing.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
6
---
14
target/arm/helper.c | 2 +-
7
target/arm/translate.c | 16 ++++++++--------
15
1 file changed, 1 insertion(+), 1 deletion(-)
8
1 file changed, 8 insertions(+), 8 deletions(-)
16
9
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
10
diff --git a/target/arm/translate.c b/target/arm/translate.c
18
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
12
--- a/target/arm/translate.c
20
+++ b/target/arm/helper.c
13
+++ b/target/arm/translate.c
21
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu)
14
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
22
15
{
23
if (cnt->supported(&cpu->env)) {
16
DisasContext *dc = container_of(dcbase, DisasContext, base);
24
supported_event_map[cnt->number] = i;
17
CPUARMState *env = cpu->env_ptr;
25
- uint64_t event_mask = 1 << (cnt->number & 0x1f);
18
+ uint32_t pc = dc->base.pc_next;
26
+ uint64_t event_mask = 1ULL << (cnt->number & 0x1f);
19
uint32_t insn;
27
if (cnt->number & 0x20) {
20
bool is_16bit;
28
cpu->pmceid1 |= event_mask;
21
29
} else {
22
if (arm_pre_translate_insn(dc)) {
23
- dc->base.pc_next += 2;
24
+ dc->base.pc_next = pc + 2;
25
return;
26
}
27
28
- dc->pc_curr = dc->base.pc_next;
29
- insn = arm_lduw_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
30
+ dc->pc_curr = pc;
31
+ insn = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
32
is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
33
- dc->base.pc_next += 2;
34
+ pc += 2;
35
if (!is_16bit) {
36
- uint32_t insn2 = arm_lduw_code(env, &dc->base, dc->base.pc_next,
37
- dc->sctlr_b);
38
-
39
+ uint32_t insn2 = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
40
insn = insn << 16 | insn2;
41
- dc->base.pc_next += 2;
42
+ pc += 2;
43
}
44
+ dc->base.pc_next = pc;
45
dc->insn = insn;
46
47
if (dc->pstate_il) {
30
--
48
--
31
2.20.1
49
2.25.1
32
50
33
51
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
There are lots of special cases within these insns. Split the
3
Create arm_check_ss_active and arm_check_kernelpage.
4
major argument decode/loading/saving into no_output (compares),
5
rd_is_dp, and rm_is_dp.
6
4
7
We still need to special case argument load for compare (rd as
5
Reverse the order of the tests. While it doesn't matter in practice,
8
input, rm as zero) and vcvt fixed (rd as input+output), but lots
6
because only user-only has a kernel page and user-only never sets
9
of special cases do disappear.
7
ss_active, ss_active has priority over execution exceptions and it
10
8
is best to keep them in the proper order.
11
Now that we have a full switch at the beginning, hoist the ISA
12
checks from the code generation.
13
9
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20190215192302.27855-4-richard.henderson@linaro.org
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
13
---
19
target/arm/translate.c | 227 ++++++++++++++++++++---------------------
14
target/arm/translate.c | 10 +++++++---
20
1 file changed, 111 insertions(+), 116 deletions(-)
15
1 file changed, 7 insertions(+), 3 deletions(-)
21
16
22
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
23
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/translate.c
19
--- a/target/arm/translate.c
25
+++ b/target/arm/translate.c
20
+++ b/target/arm/translate.c
26
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
21
@@ -XXX,XX +XXX,XX @@ static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
27
}
22
dc->insn_start = tcg_last_op();
28
} else {
23
}
29
/* data processing */
24
30
+ bool rd_is_dp = dp;
25
-static bool arm_pre_translate_insn(DisasContext *dc)
31
+ bool rm_is_dp = dp;
26
+static bool arm_check_kernelpage(DisasContext *dc)
32
+ bool no_output = false;
27
{
33
+
28
#ifdef CONFIG_USER_ONLY
34
/* The opcode is in bits 23, 21, 20 and 6. */
29
/* Intercept jump to the magic kernel page. */
35
op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
30
@@ -XXX,XX +XXX,XX @@ static bool arm_pre_translate_insn(DisasContext *dc)
36
- if (dp) {
31
return true;
37
- if (op == 15) {
32
}
38
- /* rn is opcode */
33
#endif
39
- rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
34
+ return false;
40
- } else {
35
+}
41
- /* rn is register number */
36
42
- VFP_DREG_N(rn, insn);
37
+static bool arm_check_ss_active(DisasContext *dc)
43
- }
38
+{
44
+ rn = VFP_SREG_N(insn);
39
if (dc->ss_active && !dc->pstate_ss) {
45
40
/* Singlestep state is Active-pending.
46
- if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
41
* If we're in this state at the start of a TB then either
47
- ((rn & 0x1e) == 0x6))) {
42
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
48
- /* Integer or single/half precision destination. */
43
uint32_t pc = dc->base.pc_next;
49
- rd = VFP_SREG_D(insn);
44
unsigned int insn;
50
- } else {
45
51
- VFP_DREG_D(rd, insn);
46
- if (arm_pre_translate_insn(dc)) {
52
- }
47
+ if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
53
- if (op == 15 &&
48
dc->base.pc_next = pc + 4;
54
- (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
49
return;
55
- ((rn & 0x1e) == 0x4))) {
50
}
56
- /* VCVT from int or half precision is always from S reg
51
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
57
- * regardless of dp bit. VCVT with immediate frac_bits
52
uint32_t insn;
58
- * has same format as SREG_M.
53
bool is_16bit;
59
+ if (op == 15) {
54
60
+ /* rn is opcode, encoded as per VFP_SREG_N. */
55
- if (arm_pre_translate_insn(dc)) {
61
+ switch (rn) {
56
+ if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
62
+ case 0x00: /* vmov */
57
dc->base.pc_next = pc + 2;
63
+ case 0x01: /* vabs */
58
return;
64
+ case 0x02: /* vneg */
59
}
65
+ case 0x03: /* vsqrt */
66
+ break;
67
+
68
+ case 0x04: /* vcvtb.f64.f16, vcvtb.f32.f16 */
69
+ case 0x05: /* vcvtt.f64.f16, vcvtt.f32.f16 */
70
+ /*
71
+ * VCVTB, VCVTT: only present with the halfprec extension
72
+ * UNPREDICTABLE if bit 8 is set prior to ARMv8
73
+ * (we choose to UNDEF)
74
*/
75
- rm = VFP_SREG_M(insn);
76
- } else {
77
- VFP_DREG_M(rm, insn);
78
+ if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
79
+ !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
80
+ return 1;
81
+ }
82
+ rm_is_dp = false;
83
+ break;
84
+ case 0x06: /* vcvtb.f16.f32, vcvtb.f16.f64 */
85
+ case 0x07: /* vcvtt.f16.f32, vcvtt.f16.f64 */
86
+ if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
87
+ !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
88
+ return 1;
89
+ }
90
+ rd_is_dp = false;
91
+ break;
92
+
93
+ case 0x08: case 0x0a: /* vcmp, vcmpz */
94
+ case 0x09: case 0x0b: /* vcmpe, vcmpez */
95
+ no_output = true;
96
+ break;
97
+
98
+ case 0x0c: /* vrintr */
99
+ case 0x0d: /* vrintz */
100
+ case 0x0e: /* vrintx */
101
+ break;
102
+
103
+ case 0x0f: /* vcvt double<->single */
104
+ rd_is_dp = !dp;
105
+ break;
106
+
107
+ case 0x10: /* vcvt.fxx.u32 */
108
+ case 0x11: /* vcvt.fxx.s32 */
109
+ rm_is_dp = false;
110
+ break;
111
+ case 0x18: /* vcvtr.u32.fxx */
112
+ case 0x19: /* vcvtz.u32.fxx */
113
+ case 0x1a: /* vcvtr.s32.fxx */
114
+ case 0x1b: /* vcvtz.s32.fxx */
115
+ rd_is_dp = false;
116
+ break;
117
+
118
+ case 0x14: /* vcvt fp <-> fixed */
119
+ case 0x15:
120
+ case 0x16:
121
+ case 0x17:
122
+ case 0x1c:
123
+ case 0x1d:
124
+ case 0x1e:
125
+ case 0x1f:
126
+ if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
127
+ return 1;
128
+ }
129
+ /* Immediate frac_bits has same format as SREG_M. */
130
+ rm_is_dp = false;
131
+ break;
132
+
133
+ default:
134
+ return 1;
135
}
136
+ } else if (dp) {
137
+ /* rn is register number */
138
+ VFP_DREG_N(rn, insn);
139
+ }
140
+
141
+ if (rd_is_dp) {
142
+ VFP_DREG_D(rd, insn);
143
+ } else {
144
+ rd = VFP_SREG_D(insn);
145
+ }
146
+ if (rm_is_dp) {
147
+ VFP_DREG_M(rm, insn);
148
} else {
149
- rn = VFP_SREG_N(insn);
150
- if (op == 15 && rn == 15) {
151
- /* Double precision destination. */
152
- VFP_DREG_D(rd, insn);
153
- } else {
154
- rd = VFP_SREG_D(insn);
155
- }
156
- /* NB that we implicitly rely on the encoding for the frac_bits
157
- * in VCVT of fixed to float being the same as that of an SREG_M
158
- */
159
rm = VFP_SREG_M(insn);
160
}
161
162
veclen = s->vec_len;
163
- if (op == 15 && rn > 3)
164
+ if (op == 15 && rn > 3) {
165
veclen = 0;
166
+ }
167
168
/* Shut up compiler warnings. */
169
delta_m = 0;
170
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
171
/* Load the initial operands. */
172
if (op == 15) {
173
switch (rn) {
174
- case 16:
175
- case 17:
176
- /* Integer source */
177
- gen_mov_F0_vreg(0, rm);
178
- break;
179
- case 8:
180
- case 9:
181
- /* Compare */
182
+ case 0x08: case 0x09: /* Compare */
183
gen_mov_F0_vreg(dp, rd);
184
gen_mov_F1_vreg(dp, rm);
185
break;
186
- case 10:
187
- case 11:
188
- /* Compare with zero */
189
+ case 0x0a: case 0x0b: /* Compare with zero */
190
gen_mov_F0_vreg(dp, rd);
191
gen_vfp_F1_ld0(dp);
192
break;
193
- case 20:
194
- case 21:
195
- case 22:
196
- case 23:
197
- case 28:
198
- case 29:
199
- case 30:
200
- case 31:
201
+ case 0x14: /* vcvt fp <-> fixed */
202
+ case 0x15:
203
+ case 0x16:
204
+ case 0x17:
205
+ case 0x1c:
206
+ case 0x1d:
207
+ case 0x1e:
208
+ case 0x1f:
209
/* Source and destination the same. */
210
gen_mov_F0_vreg(dp, rd);
211
break;
212
- case 4:
213
- case 5:
214
- case 6:
215
- case 7:
216
- /* VCVTB, VCVTT: only present with the halfprec extension
217
- * UNPREDICTABLE if bit 8 is set prior to ARMv8
218
- * (we choose to UNDEF)
219
- */
220
- if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
221
- !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
222
- return 1;
223
- }
224
- if (!extract32(rn, 1, 1)) {
225
- /* Half precision source. */
226
- gen_mov_F0_vreg(0, rm);
227
- break;
228
- }
229
- /* Otherwise fall through */
230
default:
231
/* One source operand. */
232
- gen_mov_F0_vreg(dp, rm);
233
+ gen_mov_F0_vreg(rm_is_dp, rm);
234
break;
235
}
236
} else {
237
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
238
break;
239
}
240
case 15: /* single<->double conversion */
241
- if (dp)
242
+ if (dp) {
243
gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
244
- else
245
+ } else {
246
gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
247
+ }
248
break;
249
case 16: /* fuito */
250
gen_vfp_uito(dp, 0);
251
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
252
gen_vfp_sito(dp, 0);
253
break;
254
case 20: /* fshto */
255
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
256
- return 1;
257
- }
258
gen_vfp_shto(dp, 16 - rm, 0);
259
break;
260
case 21: /* fslto */
261
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
262
- return 1;
263
- }
264
gen_vfp_slto(dp, 32 - rm, 0);
265
break;
266
case 22: /* fuhto */
267
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
268
- return 1;
269
- }
270
gen_vfp_uhto(dp, 16 - rm, 0);
271
break;
272
case 23: /* fulto */
273
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
274
- return 1;
275
- }
276
gen_vfp_ulto(dp, 32 - rm, 0);
277
break;
278
case 24: /* ftoui */
279
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
280
gen_vfp_tosiz(dp, 0);
281
break;
282
case 28: /* ftosh */
283
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
284
- return 1;
285
- }
286
gen_vfp_tosh(dp, 16 - rm, 0);
287
break;
288
case 29: /* ftosl */
289
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
290
- return 1;
291
- }
292
gen_vfp_tosl(dp, 32 - rm, 0);
293
break;
294
case 30: /* ftouh */
295
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
296
- return 1;
297
- }
298
gen_vfp_touh(dp, 16 - rm, 0);
299
break;
300
case 31: /* ftoul */
301
- if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
302
- return 1;
303
- }
304
gen_vfp_toul(dp, 32 - rm, 0);
305
break;
306
default: /* undefined */
307
- return 1;
308
+ g_assert_not_reached();
309
}
310
break;
311
default: /* undefined */
312
return 1;
313
}
314
315
- /* Write back the result. */
316
- if (op == 15 && (rn >= 8 && rn <= 11)) {
317
- /* Comparison, do nothing. */
318
- } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
319
- (rn & 0x1e) == 0x6)) {
320
- /* VCVT double to int: always integer result.
321
- * VCVT double to half precision is always a single
322
- * precision result.
323
- */
324
- gen_mov_vreg_F0(0, rd);
325
- } else if (op == 15 && rn == 15) {
326
- /* conversion */
327
- gen_mov_vreg_F0(!dp, rd);
328
- } else {
329
- gen_mov_vreg_F0(dp, rd);
330
+ /* Write back the result, if any. */
331
+ if (!no_output) {
332
+ gen_mov_vreg_F0(rd_is_dp, rd);
333
}
334
335
/* break out of the loop if we have finished */
336
- if (veclen == 0)
337
+ if (veclen == 0) {
338
break;
339
+ }
340
341
if (op == 15 && delta_m == 0) {
342
/* single source one-many */
343
--
60
--
344
2.20.1
61
2.25.1
345
62
346
63
diff view generated by jsdifflib
1
Coverity points out (CID 1398632, CID 1398650) that we
1
From: Richard Henderson <richard.henderson@linaro.org>
2
leak a couple of allocated strings in the error-exit
3
code path for setting up the MHUs in the ARMSSE.
4
Fix this bug by moving the allocate-and-free of each
5
string to be closer to the use, so we do the free before
6
doing the error-exit check.
7
2
8
Fixes: f8574705f62b38a ("hw/arm/armsse: Add unimplemented-device stubs for MHUs")
3
The size of the code covered by a TranslationBlock cannot be 0;
4
this is checked via assert in tb_gen_code.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20190215113707.24553-1-peter.maydell@linaro.org
12
---
9
---
13
hw/arm/armsse.c | 10 ++++++----
10
target/arm/translate-a64.c | 1 +
14
1 file changed, 6 insertions(+), 4 deletions(-)
11
1 file changed, 1 insertion(+)
15
12
16
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/armsse.c
15
--- a/target/arm/translate-a64.c
19
+++ b/hw/arm/armsse.c
16
+++ b/target/arm/translate-a64.c
20
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
21
18
assert(s->base.num_insns == 1);
22
if (info->has_mhus) {
19
gen_swstep_exception(s, 0, 0);
23
for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
20
s->base.is_jmp = DISAS_NORETURN;
24
- char *name = g_strdup_printf("MHU%d", i);
21
+ s->base.pc_next = pc + 4;
25
- char *port = g_strdup_printf("port[%d]", i + 3);
22
return;
26
+ char *name;
27
+ char *port;
28
29
+ name = g_strdup_printf("MHU%d", i);
30
qdev_prop_set_string(DEVICE(&s->mhu[i]), "name", name);
31
qdev_prop_set_uint64(DEVICE(&s->mhu[i]), "size", 0x1000);
32
object_property_set_bool(OBJECT(&s->mhu[i]), true,
33
"realized", &err);
34
+ g_free(name);
35
if (err) {
36
error_propagate(errp, err);
37
return;
38
}
39
+ port = g_strdup_printf("port[%d]", i + 3);
40
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mhu[i]), 0);
41
object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr),
42
port, &err);
43
+ g_free(port);
44
if (err) {
45
error_propagate(errp, err);
46
return;
47
}
48
- g_free(name);
49
- g_free(port);
50
}
51
}
23
}
52
24
53
--
25
--
54
2.20.1
26
2.25.1
55
27
56
28
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Move all of the fp helpers out of helper.c into a new file.
3
We will reuse this section of arm_deliver_fault for
4
This is code movement only. Since helper.c has no copyright
4
raising pc alignment faults.
5
header, take the one from cpu.h for the new file.
6
5
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190215192302.27855-3-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
target/arm/Makefile.objs | 2 +-
10
target/arm/tlb_helper.c | 45 +++++++++++++++++++++++++----------------
13
target/arm/helper.c | 1062 -------------------------------------
11
1 file changed, 28 insertions(+), 17 deletions(-)
14
target/arm/vfp_helper.c | 1088 ++++++++++++++++++++++++++++++++++++++
15
3 files changed, 1089 insertions(+), 1063 deletions(-)
16
create mode 100644 target/arm/vfp_helper.c
17
12
18
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
13
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/Makefile.objs
15
--- a/target/arm/tlb_helper.c
21
+++ b/target/arm/Makefile.objs
16
+++ b/target/arm/tlb_helper.c
22
@@ -XXX,XX +XXX,XX @@ obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o
17
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
23
obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o
18
return syn;
24
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
25
obj-y += translate.o op_helper.o helper.o cpu.o
26
-obj-y += neon_helper.o iwmmxt_helper.o vec_helper.o
27
+obj-y += neon_helper.o iwmmxt_helper.o vec_helper.o vfp_helper.o
28
obj-y += gdbstub.o
29
obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o
30
obj-$(TARGET_AARCH64) += pauth_helper.o
31
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/helper.c
34
+++ b/target/arm/helper.c
35
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
36
return (a & mask) | (b & ~mask);
37
}
19
}
38
20
39
-/* VFP support. We follow the convention used for VFP instructions:
21
-static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
40
- Single precision routines have a "s" suffix, double precision a
22
- MMUAccessType access_type,
41
- "d" suffix. */
23
- int mmu_idx, ARMMMUFaultInfo *fi)
24
+static uint32_t compute_fsr_fsc(CPUARMState *env, ARMMMUFaultInfo *fi,
25
+ int target_el, int mmu_idx, uint32_t *ret_fsc)
26
{
27
- CPUARMState *env = &cpu->env;
28
- int target_el;
29
- bool same_el;
30
- uint32_t syn, exc, fsr, fsc;
31
ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
42
-
32
-
43
-/* Convert host exception flags to vfp form. */
33
- target_el = exception_target_el(env);
44
-static inline int vfp_exceptbits_from_host(int host_bits)
34
- if (fi->stage2) {
45
-{
35
- target_el = 2;
46
- int target_bits = 0;
36
- env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
47
-
37
- if (arm_is_secure_below_el3(env) && fi->s1ns) {
48
- if (host_bits & float_flag_invalid)
38
- env->cp15.hpfar_el2 |= HPFAR_NS;
49
- target_bits |= 1;
50
- if (host_bits & float_flag_divbyzero)
51
- target_bits |= 2;
52
- if (host_bits & float_flag_overflow)
53
- target_bits |= 4;
54
- if (host_bits & (float_flag_underflow | float_flag_output_denormal))
55
- target_bits |= 8;
56
- if (host_bits & float_flag_inexact)
57
- target_bits |= 0x10;
58
- if (host_bits & float_flag_input_denormal)
59
- target_bits |= 0x80;
60
- return target_bits;
61
-}
62
-
63
-uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
64
-{
65
- uint32_t i, fpscr;
66
-
67
- fpscr = env->vfp.xregs[ARM_VFP_FPSCR]
68
- | (env->vfp.vec_len << 16)
69
- | (env->vfp.vec_stride << 20);
70
-
71
- i = get_float_exception_flags(&env->vfp.fp_status);
72
- i |= get_float_exception_flags(&env->vfp.standard_fp_status);
73
- /* FZ16 does not generate an input denormal exception. */
74
- i |= (get_float_exception_flags(&env->vfp.fp_status_f16)
75
- & ~float_flag_input_denormal);
76
- fpscr |= vfp_exceptbits_from_host(i);
77
-
78
- i = env->vfp.qc[0] | env->vfp.qc[1] | env->vfp.qc[2] | env->vfp.qc[3];
79
- fpscr |= i ? FPCR_QC : 0;
80
-
81
- return fpscr;
82
-}
83
-
84
-uint32_t vfp_get_fpscr(CPUARMState *env)
85
-{
86
- return HELPER(vfp_get_fpscr)(env);
87
-}
88
-
89
-/* Convert vfp exception flags to target form. */
90
-static inline int vfp_exceptbits_to_host(int target_bits)
91
-{
92
- int host_bits = 0;
93
-
94
- if (target_bits & 1)
95
- host_bits |= float_flag_invalid;
96
- if (target_bits & 2)
97
- host_bits |= float_flag_divbyzero;
98
- if (target_bits & 4)
99
- host_bits |= float_flag_overflow;
100
- if (target_bits & 8)
101
- host_bits |= float_flag_underflow;
102
- if (target_bits & 0x10)
103
- host_bits |= float_flag_inexact;
104
- if (target_bits & 0x80)
105
- host_bits |= float_flag_input_denormal;
106
- return host_bits;
107
-}
108
-
109
-void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
110
-{
111
- int i;
112
- uint32_t changed = env->vfp.xregs[ARM_VFP_FPSCR];
113
-
114
- /* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
115
- if (!cpu_isar_feature(aa64_fp16, arm_env_get_cpu(env))) {
116
- val &= ~FPCR_FZ16;
117
- }
118
-
119
- /*
120
- * We don't implement trapped exception handling, so the
121
- * trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
122
- *
123
- * If we exclude the exception flags, IOC|DZC|OFC|UFC|IXC|IDC
124
- * (which are stored in fp_status), and the other RES0 bits
125
- * in between, then we clear all of the low 16 bits.
126
- */
127
- env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xf7c80000;
128
- env->vfp.vec_len = (val >> 16) & 7;
129
- env->vfp.vec_stride = (val >> 20) & 3;
130
-
131
- /*
132
- * The bit we set within fpscr_q is arbitrary; the register as a
133
- * whole being zero/non-zero is what counts.
134
- */
135
- env->vfp.qc[0] = val & FPCR_QC;
136
- env->vfp.qc[1] = 0;
137
- env->vfp.qc[2] = 0;
138
- env->vfp.qc[3] = 0;
139
-
140
- changed ^= val;
141
- if (changed & (3 << 22)) {
142
- i = (val >> 22) & 3;
143
- switch (i) {
144
- case FPROUNDING_TIEEVEN:
145
- i = float_round_nearest_even;
146
- break;
147
- case FPROUNDING_POSINF:
148
- i = float_round_up;
149
- break;
150
- case FPROUNDING_NEGINF:
151
- i = float_round_down;
152
- break;
153
- case FPROUNDING_ZERO:
154
- i = float_round_to_zero;
155
- break;
156
- }
157
- set_float_rounding_mode(i, &env->vfp.fp_status);
158
- set_float_rounding_mode(i, &env->vfp.fp_status_f16);
159
- }
160
- if (changed & FPCR_FZ16) {
161
- bool ftz_enabled = val & FPCR_FZ16;
162
- set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16);
163
- set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16);
164
- }
165
- if (changed & FPCR_FZ) {
166
- bool ftz_enabled = val & FPCR_FZ;
167
- set_flush_to_zero(ftz_enabled, &env->vfp.fp_status);
168
- set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status);
169
- }
170
- if (changed & FPCR_DN) {
171
- bool dnan_enabled = val & FPCR_DN;
172
- set_default_nan_mode(dnan_enabled, &env->vfp.fp_status);
173
- set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16);
174
- }
175
-
176
- /* The exception flags are ORed together when we read fpscr so we
177
- * only need to preserve the current state in one of our
178
- * float_status values.
179
- */
180
- i = vfp_exceptbits_to_host(val);
181
- set_float_exception_flags(i, &env->vfp.fp_status);
182
- set_float_exception_flags(0, &env->vfp.fp_status_f16);
183
- set_float_exception_flags(0, &env->vfp.standard_fp_status);
184
-}
185
-
186
-void vfp_set_fpscr(CPUARMState *env, uint32_t val)
187
-{
188
- HELPER(vfp_set_fpscr)(env, val);
189
-}
190
-
191
-#define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p))
192
-
193
-#define VFP_BINOP(name) \
194
-float32 VFP_HELPER(name, s)(float32 a, float32 b, void *fpstp) \
195
-{ \
196
- float_status *fpst = fpstp; \
197
- return float32_ ## name(a, b, fpst); \
198
-} \
199
-float64 VFP_HELPER(name, d)(float64 a, float64 b, void *fpstp) \
200
-{ \
201
- float_status *fpst = fpstp; \
202
- return float64_ ## name(a, b, fpst); \
203
-}
204
-VFP_BINOP(add)
205
-VFP_BINOP(sub)
206
-VFP_BINOP(mul)
207
-VFP_BINOP(div)
208
-VFP_BINOP(min)
209
-VFP_BINOP(max)
210
-VFP_BINOP(minnum)
211
-VFP_BINOP(maxnum)
212
-#undef VFP_BINOP
213
-
214
-float32 VFP_HELPER(neg, s)(float32 a)
215
-{
216
- return float32_chs(a);
217
-}
218
-
219
-float64 VFP_HELPER(neg, d)(float64 a)
220
-{
221
- return float64_chs(a);
222
-}
223
-
224
-float32 VFP_HELPER(abs, s)(float32 a)
225
-{
226
- return float32_abs(a);
227
-}
228
-
229
-float64 VFP_HELPER(abs, d)(float64 a)
230
-{
231
- return float64_abs(a);
232
-}
233
-
234
-float32 VFP_HELPER(sqrt, s)(float32 a, CPUARMState *env)
235
-{
236
- return float32_sqrt(a, &env->vfp.fp_status);
237
-}
238
-
239
-float64 VFP_HELPER(sqrt, d)(float64 a, CPUARMState *env)
240
-{
241
- return float64_sqrt(a, &env->vfp.fp_status);
242
-}
243
-
244
-static void softfloat_to_vfp_compare(CPUARMState *env, int cmp)
245
-{
246
- uint32_t flags;
247
- switch (cmp) {
248
- case float_relation_equal:
249
- flags = 0x6;
250
- break;
251
- case float_relation_less:
252
- flags = 0x8;
253
- break;
254
- case float_relation_greater:
255
- flags = 0x2;
256
- break;
257
- case float_relation_unordered:
258
- flags = 0x3;
259
- break;
260
- default:
261
- g_assert_not_reached();
262
- }
263
- env->vfp.xregs[ARM_VFP_FPSCR] =
264
- deposit32(env->vfp.xregs[ARM_VFP_FPSCR], 28, 4, flags);
265
-}
266
-
267
-/* XXX: check quiet/signaling case */
268
-#define DO_VFP_cmp(p, type) \
269
-void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \
270
-{ \
271
- softfloat_to_vfp_compare(env, \
272
- type ## _compare_quiet(a, b, &env->vfp.fp_status)); \
273
-} \
274
-void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \
275
-{ \
276
- softfloat_to_vfp_compare(env, \
277
- type ## _compare(a, b, &env->vfp.fp_status)); \
278
-}
279
-DO_VFP_cmp(s, float32)
280
-DO_VFP_cmp(d, float64)
281
-#undef DO_VFP_cmp
282
-
283
-/* Integer to float and float to integer conversions */
284
-
285
-#define CONV_ITOF(name, ftype, fsz, sign) \
286
-ftype HELPER(name)(uint32_t x, void *fpstp) \
287
-{ \
288
- float_status *fpst = fpstp; \
289
- return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
290
-}
291
-
292
-#define CONV_FTOI(name, ftype, fsz, sign, round) \
293
-sign##int32_t HELPER(name)(ftype x, void *fpstp) \
294
-{ \
295
- float_status *fpst = fpstp; \
296
- if (float##fsz##_is_any_nan(x)) { \
297
- float_raise(float_flag_invalid, fpst); \
298
- return 0; \
299
- } \
300
- return float##fsz##_to_##sign##int32##round(x, fpst); \
301
-}
302
-
303
-#define FLOAT_CONVS(name, p, ftype, fsz, sign) \
304
- CONV_ITOF(vfp_##name##to##p, ftype, fsz, sign) \
305
- CONV_FTOI(vfp_to##name##p, ftype, fsz, sign, ) \
306
- CONV_FTOI(vfp_to##name##z##p, ftype, fsz, sign, _round_to_zero)
307
-
308
-FLOAT_CONVS(si, h, uint32_t, 16, )
309
-FLOAT_CONVS(si, s, float32, 32, )
310
-FLOAT_CONVS(si, d, float64, 64, )
311
-FLOAT_CONVS(ui, h, uint32_t, 16, u)
312
-FLOAT_CONVS(ui, s, float32, 32, u)
313
-FLOAT_CONVS(ui, d, float64, 64, u)
314
-
315
-#undef CONV_ITOF
316
-#undef CONV_FTOI
317
-#undef FLOAT_CONVS
318
-
319
-/* floating point conversion */
320
-float64 VFP_HELPER(fcvtd, s)(float32 x, CPUARMState *env)
321
-{
322
- return float32_to_float64(x, &env->vfp.fp_status);
323
-}
324
-
325
-float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env)
326
-{
327
- return float64_to_float32(x, &env->vfp.fp_status);
328
-}
329
-
330
-/* VFP3 fixed point conversion. */
331
-#define VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \
332
-float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \
333
- void *fpstp) \
334
-{ return itype##_to_##float##fsz##_scalbn(x, -shift, fpstp); }
335
-
336
-#define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, ROUND, suff) \
337
-uint##isz##_t HELPER(vfp_to##name##p##suff)(float##fsz x, uint32_t shift, \
338
- void *fpst) \
339
-{ \
340
- if (unlikely(float##fsz##_is_any_nan(x))) { \
341
- float_raise(float_flag_invalid, fpst); \
342
- return 0; \
343
- } \
344
- return float##fsz##_to_##itype##_scalbn(x, ROUND, shift, fpst); \
345
-}
346
-
347
-#define VFP_CONV_FIX(name, p, fsz, isz, itype) \
348
-VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \
349
-VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \
350
- float_round_to_zero, _round_to_zero) \
351
-VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \
352
- get_float_rounding_mode(fpst), )
353
-
354
-#define VFP_CONV_FIX_A64(name, p, fsz, isz, itype) \
355
-VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \
356
-VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \
357
- get_float_rounding_mode(fpst), )
358
-
359
-VFP_CONV_FIX(sh, d, 64, 64, int16)
360
-VFP_CONV_FIX(sl, d, 64, 64, int32)
361
-VFP_CONV_FIX_A64(sq, d, 64, 64, int64)
362
-VFP_CONV_FIX(uh, d, 64, 64, uint16)
363
-VFP_CONV_FIX(ul, d, 64, 64, uint32)
364
-VFP_CONV_FIX_A64(uq, d, 64, 64, uint64)
365
-VFP_CONV_FIX(sh, s, 32, 32, int16)
366
-VFP_CONV_FIX(sl, s, 32, 32, int32)
367
-VFP_CONV_FIX_A64(sq, s, 32, 64, int64)
368
-VFP_CONV_FIX(uh, s, 32, 32, uint16)
369
-VFP_CONV_FIX(ul, s, 32, 32, uint32)
370
-VFP_CONV_FIX_A64(uq, s, 32, 64, uint64)
371
-
372
-#undef VFP_CONV_FIX
373
-#undef VFP_CONV_FIX_FLOAT
374
-#undef VFP_CONV_FLOAT_FIX_ROUND
375
-#undef VFP_CONV_FIX_A64
376
-
377
-uint32_t HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
378
-{
379
- return int32_to_float16_scalbn(x, -shift, fpst);
380
-}
381
-
382
-uint32_t HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
383
-{
384
- return uint32_to_float16_scalbn(x, -shift, fpst);
385
-}
386
-
387
-uint32_t HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
388
-{
389
- return int64_to_float16_scalbn(x, -shift, fpst);
390
-}
391
-
392
-uint32_t HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
393
-{
394
- return uint64_to_float16_scalbn(x, -shift, fpst);
395
-}
396
-
397
-uint32_t HELPER(vfp_toshh)(uint32_t x, uint32_t shift, void *fpst)
398
-{
399
- if (unlikely(float16_is_any_nan(x))) {
400
- float_raise(float_flag_invalid, fpst);
401
- return 0;
402
- }
403
- return float16_to_int16_scalbn(x, get_float_rounding_mode(fpst),
404
- shift, fpst);
405
-}
406
-
407
-uint32_t HELPER(vfp_touhh)(uint32_t x, uint32_t shift, void *fpst)
408
-{
409
- if (unlikely(float16_is_any_nan(x))) {
410
- float_raise(float_flag_invalid, fpst);
411
- return 0;
412
- }
413
- return float16_to_uint16_scalbn(x, get_float_rounding_mode(fpst),
414
- shift, fpst);
415
-}
416
-
417
-uint32_t HELPER(vfp_toslh)(uint32_t x, uint32_t shift, void *fpst)
418
-{
419
- if (unlikely(float16_is_any_nan(x))) {
420
- float_raise(float_flag_invalid, fpst);
421
- return 0;
422
- }
423
- return float16_to_int32_scalbn(x, get_float_rounding_mode(fpst),
424
- shift, fpst);
425
-}
426
-
427
-uint32_t HELPER(vfp_toulh)(uint32_t x, uint32_t shift, void *fpst)
428
-{
429
- if (unlikely(float16_is_any_nan(x))) {
430
- float_raise(float_flag_invalid, fpst);
431
- return 0;
432
- }
433
- return float16_to_uint32_scalbn(x, get_float_rounding_mode(fpst),
434
- shift, fpst);
435
-}
436
-
437
-uint64_t HELPER(vfp_tosqh)(uint32_t x, uint32_t shift, void *fpst)
438
-{
439
- if (unlikely(float16_is_any_nan(x))) {
440
- float_raise(float_flag_invalid, fpst);
441
- return 0;
442
- }
443
- return float16_to_int64_scalbn(x, get_float_rounding_mode(fpst),
444
- shift, fpst);
445
-}
446
-
447
-uint64_t HELPER(vfp_touqh)(uint32_t x, uint32_t shift, void *fpst)
448
-{
449
- if (unlikely(float16_is_any_nan(x))) {
450
- float_raise(float_flag_invalid, fpst);
451
- return 0;
452
- }
453
- return float16_to_uint64_scalbn(x, get_float_rounding_mode(fpst),
454
- shift, fpst);
455
-}
456
-
457
-/* Set the current fp rounding mode and return the old one.
458
- * The argument is a softfloat float_round_ value.
459
- */
460
-uint32_t HELPER(set_rmode)(uint32_t rmode, void *fpstp)
461
-{
462
- float_status *fp_status = fpstp;
463
-
464
- uint32_t prev_rmode = get_float_rounding_mode(fp_status);
465
- set_float_rounding_mode(rmode, fp_status);
466
-
467
- return prev_rmode;
468
-}
469
-
470
-/* Set the current fp rounding mode in the standard fp status and return
471
- * the old one. This is for NEON instructions that need to change the
472
- * rounding mode but wish to use the standard FPSCR values for everything
473
- * else. Always set the rounding mode back to the correct value after
474
- * modifying it.
475
- * The argument is a softfloat float_round_ value.
476
- */
477
-uint32_t HELPER(set_neon_rmode)(uint32_t rmode, CPUARMState *env)
478
-{
479
- float_status *fp_status = &env->vfp.standard_fp_status;
480
-
481
- uint32_t prev_rmode = get_float_rounding_mode(fp_status);
482
- set_float_rounding_mode(rmode, fp_status);
483
-
484
- return prev_rmode;
485
-}
486
-
487
-/* Half precision conversions. */
488
-float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, void *fpstp, uint32_t ahp_mode)
489
-{
490
- /* Squash FZ16 to 0 for the duration of conversion. In this case,
491
- * it would affect flushing input denormals.
492
- */
493
- float_status *fpst = fpstp;
494
- flag save = get_flush_inputs_to_zero(fpst);
495
- set_flush_inputs_to_zero(false, fpst);
496
- float32 r = float16_to_float32(a, !ahp_mode, fpst);
497
- set_flush_inputs_to_zero(save, fpst);
498
- return r;
499
-}
500
-
501
-uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
502
-{
503
- /* Squash FZ16 to 0 for the duration of conversion. In this case,
504
- * it would affect flushing output denormals.
505
- */
506
- float_status *fpst = fpstp;
507
- flag save = get_flush_to_zero(fpst);
508
- set_flush_to_zero(false, fpst);
509
- float16 r = float32_to_float16(a, !ahp_mode, fpst);
510
- set_flush_to_zero(save, fpst);
511
- return r;
512
-}
513
-
514
-float64 HELPER(vfp_fcvt_f16_to_f64)(uint32_t a, void *fpstp, uint32_t ahp_mode)
515
-{
516
- /* Squash FZ16 to 0 for the duration of conversion. In this case,
517
- * it would affect flushing input denormals.
518
- */
519
- float_status *fpst = fpstp;
520
- flag save = get_flush_inputs_to_zero(fpst);
521
- set_flush_inputs_to_zero(false, fpst);
522
- float64 r = float16_to_float64(a, !ahp_mode, fpst);
523
- set_flush_inputs_to_zero(save, fpst);
524
- return r;
525
-}
526
-
527
-uint32_t HELPER(vfp_fcvt_f64_to_f16)(float64 a, void *fpstp, uint32_t ahp_mode)
528
-{
529
- /* Squash FZ16 to 0 for the duration of conversion. In this case,
530
- * it would affect flushing output denormals.
531
- */
532
- float_status *fpst = fpstp;
533
- flag save = get_flush_to_zero(fpst);
534
- set_flush_to_zero(false, fpst);
535
- float16 r = float64_to_float16(a, !ahp_mode, fpst);
536
- set_flush_to_zero(save, fpst);
537
- return r;
538
-}
539
-
540
-#define float32_two make_float32(0x40000000)
541
-#define float32_three make_float32(0x40400000)
542
-#define float32_one_point_five make_float32(0x3fc00000)
543
-
544
-float32 HELPER(recps_f32)(float32 a, float32 b, CPUARMState *env)
545
-{
546
- float_status *s = &env->vfp.standard_fp_status;
547
- if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) ||
548
- (float32_is_infinity(b) && float32_is_zero_or_denormal(a))) {
549
- if (!(float32_is_zero(a) || float32_is_zero(b))) {
550
- float_raise(float_flag_input_denormal, s);
551
- }
552
- return float32_two;
553
- }
554
- return float32_sub(float32_two, float32_mul(a, b, s), s);
555
-}
556
-
557
-float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUARMState *env)
558
-{
559
- float_status *s = &env->vfp.standard_fp_status;
560
- float32 product;
561
- if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) ||
562
- (float32_is_infinity(b) && float32_is_zero_or_denormal(a))) {
563
- if (!(float32_is_zero(a) || float32_is_zero(b))) {
564
- float_raise(float_flag_input_denormal, s);
565
- }
566
- return float32_one_point_five;
567
- }
568
- product = float32_mul(a, b, s);
569
- return float32_div(float32_sub(float32_three, product, s), float32_two, s);
570
-}
571
-
572
-/* NEON helpers. */
573
-
574
-/* Constants 256 and 512 are used in some helpers; we avoid relying on
575
- * int->float conversions at run-time. */
576
-#define float64_256 make_float64(0x4070000000000000LL)
577
-#define float64_512 make_float64(0x4080000000000000LL)
578
-#define float16_maxnorm make_float16(0x7bff)
579
-#define float32_maxnorm make_float32(0x7f7fffff)
580
-#define float64_maxnorm make_float64(0x7fefffffffffffffLL)
581
-
582
-/* Reciprocal functions
583
- *
584
- * The algorithm that must be used to calculate the estimate
585
- * is specified by the ARM ARM, see FPRecipEstimate()/RecipEstimate
586
- */
587
-
588
-/* See RecipEstimate()
589
- *
590
- * input is a 9 bit fixed point number
591
- * input range 256 .. 511 for a number from 0.5 <= x < 1.0.
592
- * result range 256 .. 511 for a number from 1.0 to 511/256.
593
- */
594
-
595
-static int recip_estimate(int input)
596
-{
597
- int a, b, r;
598
- assert(256 <= input && input < 512);
599
- a = (input * 2) + 1;
600
- b = (1 << 19) / a;
601
- r = (b + 1) >> 1;
602
- assert(256 <= r && r < 512);
603
- return r;
604
-}
605
-
606
-/*
607
- * Common wrapper to call recip_estimate
608
- *
609
- * The parameters are exponent and 64 bit fraction (without implicit
610
- * bit) where the binary point is nominally at bit 52. Returns a
611
- * float64 which can then be rounded to the appropriate size by the
612
- * callee.
613
- */
614
-
615
-static uint64_t call_recip_estimate(int *exp, int exp_off, uint64_t frac)
616
-{
617
- uint32_t scaled, estimate;
618
- uint64_t result_frac;
619
- int result_exp;
620
-
621
- /* Handle sub-normals */
622
- if (*exp == 0) {
623
- if (extract64(frac, 51, 1) == 0) {
624
- *exp = -1;
625
- frac <<= 2;
626
- } else {
627
- frac <<= 1;
628
- }
39
- }
629
- }
40
- }
630
-
41
- same_el = (arm_current_el(env) == target_el);
631
- /* scaled = UInt('1':fraction<51:44>) */
42
+ uint32_t fsr, fsc;
632
- scaled = deposit32(1 << 8, 0, 8, extract64(frac, 44, 8));
43
633
- estimate = recip_estimate(scaled);
44
if (target_el == 2 || arm_el_is_aa64(env, target_el) ||
634
-
45
arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
635
- result_exp = exp_off - *exp;
46
@@ -XXX,XX +XXX,XX @@ static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
636
- result_frac = deposit64(0, 44, 8, estimate);
47
fsc = 0x3f;
637
- if (result_exp == 0) {
48
}
638
- result_frac = deposit64(result_frac >> 1, 51, 1, 1);
49
639
- } else if (result_exp == -1) {
50
+ *ret_fsc = fsc;
640
- result_frac = deposit64(result_frac >> 2, 50, 2, 1);
51
+ return fsr;
641
- result_exp = 0;
642
- }
643
-
644
- *exp = result_exp;
645
-
646
- return result_frac;
647
-}
648
-
649
-static bool round_to_inf(float_status *fpst, bool sign_bit)
650
-{
651
- switch (fpst->float_rounding_mode) {
652
- case float_round_nearest_even: /* Round to Nearest */
653
- return true;
654
- case float_round_up: /* Round to +Inf */
655
- return !sign_bit;
656
- case float_round_down: /* Round to -Inf */
657
- return sign_bit;
658
- case float_round_to_zero: /* Round to Zero */
659
- return false;
660
- }
661
-
662
- g_assert_not_reached();
663
-}
664
-
665
-uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
666
-{
667
- float_status *fpst = fpstp;
668
- float16 f16 = float16_squash_input_denormal(input, fpst);
669
- uint32_t f16_val = float16_val(f16);
670
- uint32_t f16_sign = float16_is_neg(f16);
671
- int f16_exp = extract32(f16_val, 10, 5);
672
- uint32_t f16_frac = extract32(f16_val, 0, 10);
673
- uint64_t f64_frac;
674
-
675
- if (float16_is_any_nan(f16)) {
676
- float16 nan = f16;
677
- if (float16_is_signaling_nan(f16, fpst)) {
678
- float_raise(float_flag_invalid, fpst);
679
- nan = float16_silence_nan(f16, fpst);
680
- }
681
- if (fpst->default_nan_mode) {
682
- nan = float16_default_nan(fpst);
683
- }
684
- return nan;
685
- } else if (float16_is_infinity(f16)) {
686
- return float16_set_sign(float16_zero, float16_is_neg(f16));
687
- } else if (float16_is_zero(f16)) {
688
- float_raise(float_flag_divbyzero, fpst);
689
- return float16_set_sign(float16_infinity, float16_is_neg(f16));
690
- } else if (float16_abs(f16) < (1 << 8)) {
691
- /* Abs(value) < 2.0^-16 */
692
- float_raise(float_flag_overflow | float_flag_inexact, fpst);
693
- if (round_to_inf(fpst, f16_sign)) {
694
- return float16_set_sign(float16_infinity, f16_sign);
695
- } else {
696
- return float16_set_sign(float16_maxnorm, f16_sign);
697
- }
698
- } else if (f16_exp >= 29 && fpst->flush_to_zero) {
699
- float_raise(float_flag_underflow, fpst);
700
- return float16_set_sign(float16_zero, float16_is_neg(f16));
701
- }
702
-
703
- f64_frac = call_recip_estimate(&f16_exp, 29,
704
- ((uint64_t) f16_frac) << (52 - 10));
705
-
706
- /* result = sign : result_exp<4:0> : fraction<51:42> */
707
- f16_val = deposit32(0, 15, 1, f16_sign);
708
- f16_val = deposit32(f16_val, 10, 5, f16_exp);
709
- f16_val = deposit32(f16_val, 0, 10, extract64(f64_frac, 52 - 10, 10));
710
- return make_float16(f16_val);
711
-}
712
-
713
-float32 HELPER(recpe_f32)(float32 input, void *fpstp)
714
-{
715
- float_status *fpst = fpstp;
716
- float32 f32 = float32_squash_input_denormal(input, fpst);
717
- uint32_t f32_val = float32_val(f32);
718
- bool f32_sign = float32_is_neg(f32);
719
- int f32_exp = extract32(f32_val, 23, 8);
720
- uint32_t f32_frac = extract32(f32_val, 0, 23);
721
- uint64_t f64_frac;
722
-
723
- if (float32_is_any_nan(f32)) {
724
- float32 nan = f32;
725
- if (float32_is_signaling_nan(f32, fpst)) {
726
- float_raise(float_flag_invalid, fpst);
727
- nan = float32_silence_nan(f32, fpst);
728
- }
729
- if (fpst->default_nan_mode) {
730
- nan = float32_default_nan(fpst);
731
- }
732
- return nan;
733
- } else if (float32_is_infinity(f32)) {
734
- return float32_set_sign(float32_zero, float32_is_neg(f32));
735
- } else if (float32_is_zero(f32)) {
736
- float_raise(float_flag_divbyzero, fpst);
737
- return float32_set_sign(float32_infinity, float32_is_neg(f32));
738
- } else if (float32_abs(f32) < (1ULL << 21)) {
739
- /* Abs(value) < 2.0^-128 */
740
- float_raise(float_flag_overflow | float_flag_inexact, fpst);
741
- if (round_to_inf(fpst, f32_sign)) {
742
- return float32_set_sign(float32_infinity, f32_sign);
743
- } else {
744
- return float32_set_sign(float32_maxnorm, f32_sign);
745
- }
746
- } else if (f32_exp >= 253 && fpst->flush_to_zero) {
747
- float_raise(float_flag_underflow, fpst);
748
- return float32_set_sign(float32_zero, float32_is_neg(f32));
749
- }
750
-
751
- f64_frac = call_recip_estimate(&f32_exp, 253,
752
- ((uint64_t) f32_frac) << (52 - 23));
753
-
754
- /* result = sign : result_exp<7:0> : fraction<51:29> */
755
- f32_val = deposit32(0, 31, 1, f32_sign);
756
- f32_val = deposit32(f32_val, 23, 8, f32_exp);
757
- f32_val = deposit32(f32_val, 0, 23, extract64(f64_frac, 52 - 23, 23));
758
- return make_float32(f32_val);
759
-}
760
-
761
-float64 HELPER(recpe_f64)(float64 input, void *fpstp)
762
-{
763
- float_status *fpst = fpstp;
764
- float64 f64 = float64_squash_input_denormal(input, fpst);
765
- uint64_t f64_val = float64_val(f64);
766
- bool f64_sign = float64_is_neg(f64);
767
- int f64_exp = extract64(f64_val, 52, 11);
768
- uint64_t f64_frac = extract64(f64_val, 0, 52);
769
-
770
- /* Deal with any special cases */
771
- if (float64_is_any_nan(f64)) {
772
- float64 nan = f64;
773
- if (float64_is_signaling_nan(f64, fpst)) {
774
- float_raise(float_flag_invalid, fpst);
775
- nan = float64_silence_nan(f64, fpst);
776
- }
777
- if (fpst->default_nan_mode) {
778
- nan = float64_default_nan(fpst);
779
- }
780
- return nan;
781
- } else if (float64_is_infinity(f64)) {
782
- return float64_set_sign(float64_zero, float64_is_neg(f64));
783
- } else if (float64_is_zero(f64)) {
784
- float_raise(float_flag_divbyzero, fpst);
785
- return float64_set_sign(float64_infinity, float64_is_neg(f64));
786
- } else if ((f64_val & ~(1ULL << 63)) < (1ULL << 50)) {
787
- /* Abs(value) < 2.0^-1024 */
788
- float_raise(float_flag_overflow | float_flag_inexact, fpst);
789
- if (round_to_inf(fpst, f64_sign)) {
790
- return float64_set_sign(float64_infinity, f64_sign);
791
- } else {
792
- return float64_set_sign(float64_maxnorm, f64_sign);
793
- }
794
- } else if (f64_exp >= 2045 && fpst->flush_to_zero) {
795
- float_raise(float_flag_underflow, fpst);
796
- return float64_set_sign(float64_zero, float64_is_neg(f64));
797
- }
798
-
799
- f64_frac = call_recip_estimate(&f64_exp, 2045, f64_frac);
800
-
801
- /* result = sign : result_exp<10:0> : fraction<51:0>; */
802
- f64_val = deposit64(0, 63, 1, f64_sign);
803
- f64_val = deposit64(f64_val, 52, 11, f64_exp);
804
- f64_val = deposit64(f64_val, 0, 52, f64_frac);
805
- return make_float64(f64_val);
806
-}
807
-
808
-/* The algorithm that must be used to calculate the estimate
809
- * is specified by the ARM ARM.
810
- */
811
-
812
-static int do_recip_sqrt_estimate(int a)
813
-{
814
- int b, estimate;
815
-
816
- assert(128 <= a && a < 512);
817
- if (a < 256) {
818
- a = a * 2 + 1;
819
- } else {
820
- a = (a >> 1) << 1;
821
- a = (a + 1) * 2;
822
- }
823
- b = 512;
824
- while (a * (b + 1) * (b + 1) < (1 << 28)) {
825
- b += 1;
826
- }
827
- estimate = (b + 1) / 2;
828
- assert(256 <= estimate && estimate < 512);
829
-
830
- return estimate;
831
-}
832
-
833
-
834
-static uint64_t recip_sqrt_estimate(int *exp , int exp_off, uint64_t frac)
835
-{
836
- int estimate;
837
- uint32_t scaled;
838
-
839
- if (*exp == 0) {
840
- while (extract64(frac, 51, 1) == 0) {
841
- frac = frac << 1;
842
- *exp -= 1;
843
- }
844
- frac = extract64(frac, 0, 51) << 1;
845
- }
846
-
847
- if (*exp & 1) {
848
- /* scaled = UInt('01':fraction<51:45>) */
849
- scaled = deposit32(1 << 7, 0, 7, extract64(frac, 45, 7));
850
- } else {
851
- /* scaled = UInt('1':fraction<51:44>) */
852
- scaled = deposit32(1 << 8, 0, 8, extract64(frac, 44, 8));
853
- }
854
- estimate = do_recip_sqrt_estimate(scaled);
855
-
856
- *exp = (exp_off - *exp) / 2;
857
- return extract64(estimate, 0, 8) << 44;
858
-}
859
-
860
-uint32_t HELPER(rsqrte_f16)(uint32_t input, void *fpstp)
861
-{
862
- float_status *s = fpstp;
863
- float16 f16 = float16_squash_input_denormal(input, s);
864
- uint16_t val = float16_val(f16);
865
- bool f16_sign = float16_is_neg(f16);
866
- int f16_exp = extract32(val, 10, 5);
867
- uint16_t f16_frac = extract32(val, 0, 10);
868
- uint64_t f64_frac;
869
-
870
- if (float16_is_any_nan(f16)) {
871
- float16 nan = f16;
872
- if (float16_is_signaling_nan(f16, s)) {
873
- float_raise(float_flag_invalid, s);
874
- nan = float16_silence_nan(f16, s);
875
- }
876
- if (s->default_nan_mode) {
877
- nan = float16_default_nan(s);
878
- }
879
- return nan;
880
- } else if (float16_is_zero(f16)) {
881
- float_raise(float_flag_divbyzero, s);
882
- return float16_set_sign(float16_infinity, f16_sign);
883
- } else if (f16_sign) {
884
- float_raise(float_flag_invalid, s);
885
- return float16_default_nan(s);
886
- } else if (float16_is_infinity(f16)) {
887
- return float16_zero;
888
- }
889
-
890
- /* Scale and normalize to a double-precision value between 0.25 and 1.0,
891
- * preserving the parity of the exponent. */
892
-
893
- f64_frac = ((uint64_t) f16_frac) << (52 - 10);
894
-
895
- f64_frac = recip_sqrt_estimate(&f16_exp, 44, f64_frac);
896
-
897
- /* result = sign : result_exp<4:0> : estimate<7:0> : Zeros(2) */
898
- val = deposit32(0, 15, 1, f16_sign);
899
- val = deposit32(val, 10, 5, f16_exp);
900
- val = deposit32(val, 2, 8, extract64(f64_frac, 52 - 8, 8));
901
- return make_float16(val);
902
-}
903
-
904
-float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
905
-{
906
- float_status *s = fpstp;
907
- float32 f32 = float32_squash_input_denormal(input, s);
908
- uint32_t val = float32_val(f32);
909
- uint32_t f32_sign = float32_is_neg(f32);
910
- int f32_exp = extract32(val, 23, 8);
911
- uint32_t f32_frac = extract32(val, 0, 23);
912
- uint64_t f64_frac;
913
-
914
- if (float32_is_any_nan(f32)) {
915
- float32 nan = f32;
916
- if (float32_is_signaling_nan(f32, s)) {
917
- float_raise(float_flag_invalid, s);
918
- nan = float32_silence_nan(f32, s);
919
- }
920
- if (s->default_nan_mode) {
921
- nan = float32_default_nan(s);
922
- }
923
- return nan;
924
- } else if (float32_is_zero(f32)) {
925
- float_raise(float_flag_divbyzero, s);
926
- return float32_set_sign(float32_infinity, float32_is_neg(f32));
927
- } else if (float32_is_neg(f32)) {
928
- float_raise(float_flag_invalid, s);
929
- return float32_default_nan(s);
930
- } else if (float32_is_infinity(f32)) {
931
- return float32_zero;
932
- }
933
-
934
- /* Scale and normalize to a double-precision value between 0.25 and 1.0,
935
- * preserving the parity of the exponent. */
936
-
937
- f64_frac = ((uint64_t) f32_frac) << 29;
938
-
939
- f64_frac = recip_sqrt_estimate(&f32_exp, 380, f64_frac);
940
-
941
- /* result = sign : result_exp<4:0> : estimate<7:0> : Zeros(15) */
942
- val = deposit32(0, 31, 1, f32_sign);
943
- val = deposit32(val, 23, 8, f32_exp);
944
- val = deposit32(val, 15, 8, extract64(f64_frac, 52 - 8, 8));
945
- return make_float32(val);
946
-}
947
-
948
-float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
949
-{
950
- float_status *s = fpstp;
951
- float64 f64 = float64_squash_input_denormal(input, s);
952
- uint64_t val = float64_val(f64);
953
- bool f64_sign = float64_is_neg(f64);
954
- int f64_exp = extract64(val, 52, 11);
955
- uint64_t f64_frac = extract64(val, 0, 52);
956
-
957
- if (float64_is_any_nan(f64)) {
958
- float64 nan = f64;
959
- if (float64_is_signaling_nan(f64, s)) {
960
- float_raise(float_flag_invalid, s);
961
- nan = float64_silence_nan(f64, s);
962
- }
963
- if (s->default_nan_mode) {
964
- nan = float64_default_nan(s);
965
- }
966
- return nan;
967
- } else if (float64_is_zero(f64)) {
968
- float_raise(float_flag_divbyzero, s);
969
- return float64_set_sign(float64_infinity, float64_is_neg(f64));
970
- } else if (float64_is_neg(f64)) {
971
- float_raise(float_flag_invalid, s);
972
- return float64_default_nan(s);
973
- } else if (float64_is_infinity(f64)) {
974
- return float64_zero;
975
- }
976
-
977
- f64_frac = recip_sqrt_estimate(&f64_exp, 3068, f64_frac);
978
-
979
- /* result = sign : result_exp<4:0> : estimate<7:0> : Zeros(44) */
980
- val = deposit64(0, 61, 1, f64_sign);
981
- val = deposit64(val, 52, 11, f64_exp);
982
- val = deposit64(val, 44, 8, extract64(f64_frac, 52 - 8, 8));
983
- return make_float64(val);
984
-}
985
-
986
-uint32_t HELPER(recpe_u32)(uint32_t a, void *fpstp)
987
-{
988
- /* float_status *s = fpstp; */
989
- int input, estimate;
990
-
991
- if ((a & 0x80000000) == 0) {
992
- return 0xffffffff;
993
- }
994
-
995
- input = extract32(a, 23, 9);
996
- estimate = recip_estimate(input);
997
-
998
- return deposit32(0, (32 - 9), 9, estimate);
999
-}
1000
-
1001
-uint32_t HELPER(rsqrte_u32)(uint32_t a, void *fpstp)
1002
-{
1003
- int estimate;
1004
-
1005
- if ((a & 0xc0000000) == 0) {
1006
- return 0xffffffff;
1007
- }
1008
-
1009
- estimate = do_recip_sqrt_estimate(extract32(a, 23, 9));
1010
-
1011
- return deposit32(0, 23, 9, estimate);
1012
-}
1013
-
1014
-/* VFPv4 fused multiply-accumulate */
1015
-float32 VFP_HELPER(muladd, s)(float32 a, float32 b, float32 c, void *fpstp)
1016
-{
1017
- float_status *fpst = fpstp;
1018
- return float32_muladd(a, b, c, 0, fpst);
1019
-}
1020
-
1021
-float64 VFP_HELPER(muladd, d)(float64 a, float64 b, float64 c, void *fpstp)
1022
-{
1023
- float_status *fpst = fpstp;
1024
- return float64_muladd(a, b, c, 0, fpst);
1025
-}
1026
-
1027
-/* ARMv8 round to integral */
1028
-float32 HELPER(rints_exact)(float32 x, void *fp_status)
1029
-{
1030
- return float32_round_to_int(x, fp_status);
1031
-}
1032
-
1033
-float64 HELPER(rintd_exact)(float64 x, void *fp_status)
1034
-{
1035
- return float64_round_to_int(x, fp_status);
1036
-}
1037
-
1038
-float32 HELPER(rints)(float32 x, void *fp_status)
1039
-{
1040
- int old_flags = get_float_exception_flags(fp_status), new_flags;
1041
- float32 ret;
1042
-
1043
- ret = float32_round_to_int(x, fp_status);
1044
-
1045
- /* Suppress any inexact exceptions the conversion produced */
1046
- if (!(old_flags & float_flag_inexact)) {
1047
- new_flags = get_float_exception_flags(fp_status);
1048
- set_float_exception_flags(new_flags & ~float_flag_inexact, fp_status);
1049
- }
1050
-
1051
- return ret;
1052
-}
1053
-
1054
-float64 HELPER(rintd)(float64 x, void *fp_status)
1055
-{
1056
- int old_flags = get_float_exception_flags(fp_status), new_flags;
1057
- float64 ret;
1058
-
1059
- ret = float64_round_to_int(x, fp_status);
1060
-
1061
- new_flags = get_float_exception_flags(fp_status);
1062
-
1063
- /* Suppress any inexact exceptions the conversion produced */
1064
- if (!(old_flags & float_flag_inexact)) {
1065
- new_flags = get_float_exception_flags(fp_status);
1066
- set_float_exception_flags(new_flags & ~float_flag_inexact, fp_status);
1067
- }
1068
-
1069
- return ret;
1070
-}
1071
-
1072
-/* Convert ARM rounding mode to softfloat */
1073
-int arm_rmode_to_sf(int rmode)
1074
-{
1075
- switch (rmode) {
1076
- case FPROUNDING_TIEAWAY:
1077
- rmode = float_round_ties_away;
1078
- break;
1079
- case FPROUNDING_ODD:
1080
- /* FIXME: add support for TIEAWAY and ODD */
1081
- qemu_log_mask(LOG_UNIMP, "arm: unimplemented rounding mode: %d\n",
1082
- rmode);
1083
- /* fall through for now */
1084
- case FPROUNDING_TIEEVEN:
1085
- default:
1086
- rmode = float_round_nearest_even;
1087
- break;
1088
- case FPROUNDING_POSINF:
1089
- rmode = float_round_up;
1090
- break;
1091
- case FPROUNDING_NEGINF:
1092
- rmode = float_round_down;
1093
- break;
1094
- case FPROUNDING_ZERO:
1095
- rmode = float_round_to_zero;
1096
- break;
1097
- }
1098
- return rmode;
1099
-}
1100
-
1101
/* CRC helpers.
1102
* The upper bytes of val (above the number specified by 'bytes') must have
1103
* been zeroed out by the caller.
1104
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
1105
new file mode 100644
1106
index XXXXXXX..XXXXXXX
1107
--- /dev/null
1108
+++ b/target/arm/vfp_helper.c
1109
@@ -XXX,XX +XXX,XX @@
1110
+/*
1111
+ * ARM VFP floating-point operations
1112
+ *
1113
+ * Copyright (c) 2003 Fabrice Bellard
1114
+ *
1115
+ * This library is free software; you can redistribute it and/or
1116
+ * modify it under the terms of the GNU Lesser General Public
1117
+ * License as published by the Free Software Foundation; either
1118
+ * version 2.1 of the License, or (at your option) any later version.
1119
+ *
1120
+ * This library is distributed in the hope that it will be useful,
1121
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1122
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1123
+ * Lesser General Public License for more details.
1124
+ *
1125
+ * You should have received a copy of the GNU Lesser General Public
1126
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1127
+ */
1128
+
1129
+#include "qemu/osdep.h"
1130
+#include "qemu/log.h"
1131
+#include "cpu.h"
1132
+#include "exec/helper-proto.h"
1133
+#include "fpu/softfloat.h"
1134
+#include "internals.h"
1135
+
1136
+
1137
+/* VFP support. We follow the convention used for VFP instructions:
1138
+ Single precision routines have a "s" suffix, double precision a
1139
+ "d" suffix. */
1140
+
1141
+/* Convert host exception flags to vfp form. */
1142
+static inline int vfp_exceptbits_from_host(int host_bits)
1143
+{
1144
+ int target_bits = 0;
1145
+
1146
+ if (host_bits & float_flag_invalid)
1147
+ target_bits |= 1;
1148
+ if (host_bits & float_flag_divbyzero)
1149
+ target_bits |= 2;
1150
+ if (host_bits & float_flag_overflow)
1151
+ target_bits |= 4;
1152
+ if (host_bits & (float_flag_underflow | float_flag_output_denormal))
1153
+ target_bits |= 8;
1154
+ if (host_bits & float_flag_inexact)
1155
+ target_bits |= 0x10;
1156
+ if (host_bits & float_flag_input_denormal)
1157
+ target_bits |= 0x80;
1158
+ return target_bits;
1159
+}
52
+}
1160
+
53
+
1161
+uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
54
+static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
55
+ MMUAccessType access_type,
56
+ int mmu_idx, ARMMMUFaultInfo *fi)
1162
+{
57
+{
1163
+ uint32_t i, fpscr;
58
+ CPUARMState *env = &cpu->env;
59
+ int target_el;
60
+ bool same_el;
61
+ uint32_t syn, exc, fsr, fsc;
1164
+
62
+
1165
+ fpscr = env->vfp.xregs[ARM_VFP_FPSCR]
63
+ target_el = exception_target_el(env);
1166
+ | (env->vfp.vec_len << 16)
64
+ if (fi->stage2) {
1167
+ | (env->vfp.vec_stride << 20);
65
+ target_el = 2;
1168
+
66
+ env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
1169
+ i = get_float_exception_flags(&env->vfp.fp_status);
67
+ if (arm_is_secure_below_el3(env) && fi->s1ns) {
1170
+ i |= get_float_exception_flags(&env->vfp.standard_fp_status);
68
+ env->cp15.hpfar_el2 |= HPFAR_NS;
1171
+ /* FZ16 does not generate an input denormal exception. */
1172
+ i |= (get_float_exception_flags(&env->vfp.fp_status_f16)
1173
+ & ~float_flag_input_denormal);
1174
+ fpscr |= vfp_exceptbits_from_host(i);
1175
+
1176
+ i = env->vfp.qc[0] | env->vfp.qc[1] | env->vfp.qc[2] | env->vfp.qc[3];
1177
+ fpscr |= i ? FPCR_QC : 0;
1178
+
1179
+ return fpscr;
1180
+}
1181
+
1182
+uint32_t vfp_get_fpscr(CPUARMState *env)
1183
+{
1184
+ return HELPER(vfp_get_fpscr)(env);
1185
+}
1186
+
1187
+/* Convert vfp exception flags to target form. */
1188
+static inline int vfp_exceptbits_to_host(int target_bits)
1189
+{
1190
+ int host_bits = 0;
1191
+
1192
+ if (target_bits & 1)
1193
+ host_bits |= float_flag_invalid;
1194
+ if (target_bits & 2)
1195
+ host_bits |= float_flag_divbyzero;
1196
+ if (target_bits & 4)
1197
+ host_bits |= float_flag_overflow;
1198
+ if (target_bits & 8)
1199
+ host_bits |= float_flag_underflow;
1200
+ if (target_bits & 0x10)
1201
+ host_bits |= float_flag_inexact;
1202
+ if (target_bits & 0x80)
1203
+ host_bits |= float_flag_input_denormal;
1204
+ return host_bits;
1205
+}
1206
+
1207
+void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
1208
+{
1209
+ int i;
1210
+ uint32_t changed = env->vfp.xregs[ARM_VFP_FPSCR];
1211
+
1212
+ /* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
1213
+ if (!cpu_isar_feature(aa64_fp16, arm_env_get_cpu(env))) {
1214
+ val &= ~FPCR_FZ16;
1215
+ }
1216
+
1217
+ /*
1218
+ * We don't implement trapped exception handling, so the
1219
+ * trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
1220
+ *
1221
+ * If we exclude the exception flags, IOC|DZC|OFC|UFC|IXC|IDC
1222
+ * (which are stored in fp_status), and the other RES0 bits
1223
+ * in between, then we clear all of the low 16 bits.
1224
+ */
1225
+ env->vfp.xregs[ARM_VFP_FPSCR] = val & 0xf7c80000;
1226
+ env->vfp.vec_len = (val >> 16) & 7;
1227
+ env->vfp.vec_stride = (val >> 20) & 3;
1228
+
1229
+ /*
1230
+ * The bit we set within fpscr_q is arbitrary; the register as a
1231
+ * whole being zero/non-zero is what counts.
1232
+ */
1233
+ env->vfp.qc[0] = val & FPCR_QC;
1234
+ env->vfp.qc[1] = 0;
1235
+ env->vfp.qc[2] = 0;
1236
+ env->vfp.qc[3] = 0;
1237
+
1238
+ changed ^= val;
1239
+ if (changed & (3 << 22)) {
1240
+ i = (val >> 22) & 3;
1241
+ switch (i) {
1242
+ case FPROUNDING_TIEEVEN:
1243
+ i = float_round_nearest_even;
1244
+ break;
1245
+ case FPROUNDING_POSINF:
1246
+ i = float_round_up;
1247
+ break;
1248
+ case FPROUNDING_NEGINF:
1249
+ i = float_round_down;
1250
+ break;
1251
+ case FPROUNDING_ZERO:
1252
+ i = float_round_to_zero;
1253
+ break;
1254
+ }
1255
+ set_float_rounding_mode(i, &env->vfp.fp_status);
1256
+ set_float_rounding_mode(i, &env->vfp.fp_status_f16);
1257
+ }
1258
+ if (changed & FPCR_FZ16) {
1259
+ bool ftz_enabled = val & FPCR_FZ16;
1260
+ set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16);
1261
+ set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16);
1262
+ }
1263
+ if (changed & FPCR_FZ) {
1264
+ bool ftz_enabled = val & FPCR_FZ;
1265
+ set_flush_to_zero(ftz_enabled, &env->vfp.fp_status);
1266
+ set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status);
1267
+ }
1268
+ if (changed & FPCR_DN) {
1269
+ bool dnan_enabled = val & FPCR_DN;
1270
+ set_default_nan_mode(dnan_enabled, &env->vfp.fp_status);
1271
+ set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16);
1272
+ }
1273
+
1274
+ /* The exception flags are ORed together when we read fpscr so we
1275
+ * only need to preserve the current state in one of our
1276
+ * float_status values.
1277
+ */
1278
+ i = vfp_exceptbits_to_host(val);
1279
+ set_float_exception_flags(i, &env->vfp.fp_status);
1280
+ set_float_exception_flags(0, &env->vfp.fp_status_f16);
1281
+ set_float_exception_flags(0, &env->vfp.standard_fp_status);
1282
+}
1283
+
1284
+void vfp_set_fpscr(CPUARMState *env, uint32_t val)
1285
+{
1286
+ HELPER(vfp_set_fpscr)(env, val);
1287
+}
1288
+
1289
+#define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p))
1290
+
1291
+#define VFP_BINOP(name) \
1292
+float32 VFP_HELPER(name, s)(float32 a, float32 b, void *fpstp) \
1293
+{ \
1294
+ float_status *fpst = fpstp; \
1295
+ return float32_ ## name(a, b, fpst); \
1296
+} \
1297
+float64 VFP_HELPER(name, d)(float64 a, float64 b, void *fpstp) \
1298
+{ \
1299
+ float_status *fpst = fpstp; \
1300
+ return float64_ ## name(a, b, fpst); \
1301
+}
1302
+VFP_BINOP(add)
1303
+VFP_BINOP(sub)
1304
+VFP_BINOP(mul)
1305
+VFP_BINOP(div)
1306
+VFP_BINOP(min)
1307
+VFP_BINOP(max)
1308
+VFP_BINOP(minnum)
1309
+VFP_BINOP(maxnum)
1310
+#undef VFP_BINOP
1311
+
1312
+float32 VFP_HELPER(neg, s)(float32 a)
1313
+{
1314
+ return float32_chs(a);
1315
+}
1316
+
1317
+float64 VFP_HELPER(neg, d)(float64 a)
1318
+{
1319
+ return float64_chs(a);
1320
+}
1321
+
1322
+float32 VFP_HELPER(abs, s)(float32 a)
1323
+{
1324
+ return float32_abs(a);
1325
+}
1326
+
1327
+float64 VFP_HELPER(abs, d)(float64 a)
1328
+{
1329
+ return float64_abs(a);
1330
+}
1331
+
1332
+float32 VFP_HELPER(sqrt, s)(float32 a, CPUARMState *env)
1333
+{
1334
+ return float32_sqrt(a, &env->vfp.fp_status);
1335
+}
1336
+
1337
+float64 VFP_HELPER(sqrt, d)(float64 a, CPUARMState *env)
1338
+{
1339
+ return float64_sqrt(a, &env->vfp.fp_status);
1340
+}
1341
+
1342
+static void softfloat_to_vfp_compare(CPUARMState *env, int cmp)
1343
+{
1344
+ uint32_t flags;
1345
+ switch (cmp) {
1346
+ case float_relation_equal:
1347
+ flags = 0x6;
1348
+ break;
1349
+ case float_relation_less:
1350
+ flags = 0x8;
1351
+ break;
1352
+ case float_relation_greater:
1353
+ flags = 0x2;
1354
+ break;
1355
+ case float_relation_unordered:
1356
+ flags = 0x3;
1357
+ break;
1358
+ default:
1359
+ g_assert_not_reached();
1360
+ }
1361
+ env->vfp.xregs[ARM_VFP_FPSCR] =
1362
+ deposit32(env->vfp.xregs[ARM_VFP_FPSCR], 28, 4, flags);
1363
+}
1364
+
1365
+/* XXX: check quiet/signaling case */
1366
+#define DO_VFP_cmp(p, type) \
1367
+void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \
1368
+{ \
1369
+ softfloat_to_vfp_compare(env, \
1370
+ type ## _compare_quiet(a, b, &env->vfp.fp_status)); \
1371
+} \
1372
+void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \
1373
+{ \
1374
+ softfloat_to_vfp_compare(env, \
1375
+ type ## _compare(a, b, &env->vfp.fp_status)); \
1376
+}
1377
+DO_VFP_cmp(s, float32)
1378
+DO_VFP_cmp(d, float64)
1379
+#undef DO_VFP_cmp
1380
+
1381
+/* Integer to float and float to integer conversions */
1382
+
1383
+#define CONV_ITOF(name, ftype, fsz, sign) \
1384
+ftype HELPER(name)(uint32_t x, void *fpstp) \
1385
+{ \
1386
+ float_status *fpst = fpstp; \
1387
+ return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
1388
+}
1389
+
1390
+#define CONV_FTOI(name, ftype, fsz, sign, round) \
1391
+sign##int32_t HELPER(name)(ftype x, void *fpstp) \
1392
+{ \
1393
+ float_status *fpst = fpstp; \
1394
+ if (float##fsz##_is_any_nan(x)) { \
1395
+ float_raise(float_flag_invalid, fpst); \
1396
+ return 0; \
1397
+ } \
1398
+ return float##fsz##_to_##sign##int32##round(x, fpst); \
1399
+}
1400
+
1401
+#define FLOAT_CONVS(name, p, ftype, fsz, sign) \
1402
+ CONV_ITOF(vfp_##name##to##p, ftype, fsz, sign) \
1403
+ CONV_FTOI(vfp_to##name##p, ftype, fsz, sign, ) \
1404
+ CONV_FTOI(vfp_to##name##z##p, ftype, fsz, sign, _round_to_zero)
1405
+
1406
+FLOAT_CONVS(si, h, uint32_t, 16, )
1407
+FLOAT_CONVS(si, s, float32, 32, )
1408
+FLOAT_CONVS(si, d, float64, 64, )
1409
+FLOAT_CONVS(ui, h, uint32_t, 16, u)
1410
+FLOAT_CONVS(ui, s, float32, 32, u)
1411
+FLOAT_CONVS(ui, d, float64, 64, u)
1412
+
1413
+#undef CONV_ITOF
1414
+#undef CONV_FTOI
1415
+#undef FLOAT_CONVS
1416
+
1417
+/* floating point conversion */
1418
+float64 VFP_HELPER(fcvtd, s)(float32 x, CPUARMState *env)
1419
+{
1420
+ return float32_to_float64(x, &env->vfp.fp_status);
1421
+}
1422
+
1423
+float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env)
1424
+{
1425
+ return float64_to_float32(x, &env->vfp.fp_status);
1426
+}
1427
+
1428
+/* VFP3 fixed point conversion. */
1429
+#define VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \
1430
+float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \
1431
+ void *fpstp) \
1432
+{ return itype##_to_##float##fsz##_scalbn(x, -shift, fpstp); }
1433
+
1434
+#define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, ROUND, suff) \
1435
+uint##isz##_t HELPER(vfp_to##name##p##suff)(float##fsz x, uint32_t shift, \
1436
+ void *fpst) \
1437
+{ \
1438
+ if (unlikely(float##fsz##_is_any_nan(x))) { \
1439
+ float_raise(float_flag_invalid, fpst); \
1440
+ return 0; \
1441
+ } \
1442
+ return float##fsz##_to_##itype##_scalbn(x, ROUND, shift, fpst); \
1443
+}
1444
+
1445
+#define VFP_CONV_FIX(name, p, fsz, isz, itype) \
1446
+VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \
1447
+VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \
1448
+ float_round_to_zero, _round_to_zero) \
1449
+VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \
1450
+ get_float_rounding_mode(fpst), )
1451
+
1452
+#define VFP_CONV_FIX_A64(name, p, fsz, isz, itype) \
1453
+VFP_CONV_FIX_FLOAT(name, p, fsz, isz, itype) \
1454
+VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, \
1455
+ get_float_rounding_mode(fpst), )
1456
+
1457
+VFP_CONV_FIX(sh, d, 64, 64, int16)
1458
+VFP_CONV_FIX(sl, d, 64, 64, int32)
1459
+VFP_CONV_FIX_A64(sq, d, 64, 64, int64)
1460
+VFP_CONV_FIX(uh, d, 64, 64, uint16)
1461
+VFP_CONV_FIX(ul, d, 64, 64, uint32)
1462
+VFP_CONV_FIX_A64(uq, d, 64, 64, uint64)
1463
+VFP_CONV_FIX(sh, s, 32, 32, int16)
1464
+VFP_CONV_FIX(sl, s, 32, 32, int32)
1465
+VFP_CONV_FIX_A64(sq, s, 32, 64, int64)
1466
+VFP_CONV_FIX(uh, s, 32, 32, uint16)
1467
+VFP_CONV_FIX(ul, s, 32, 32, uint32)
1468
+VFP_CONV_FIX_A64(uq, s, 32, 64, uint64)
1469
+
1470
+#undef VFP_CONV_FIX
1471
+#undef VFP_CONV_FIX_FLOAT
1472
+#undef VFP_CONV_FLOAT_FIX_ROUND
1473
+#undef VFP_CONV_FIX_A64
1474
+
1475
+uint32_t HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
1476
+{
1477
+ return int32_to_float16_scalbn(x, -shift, fpst);
1478
+}
1479
+
1480
+uint32_t HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
1481
+{
1482
+ return uint32_to_float16_scalbn(x, -shift, fpst);
1483
+}
1484
+
1485
+uint32_t HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
1486
+{
1487
+ return int64_to_float16_scalbn(x, -shift, fpst);
1488
+}
1489
+
1490
+uint32_t HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
1491
+{
1492
+ return uint64_to_float16_scalbn(x, -shift, fpst);
1493
+}
1494
+
1495
+uint32_t HELPER(vfp_toshh)(uint32_t x, uint32_t shift, void *fpst)
1496
+{
1497
+ if (unlikely(float16_is_any_nan(x))) {
1498
+ float_raise(float_flag_invalid, fpst);
1499
+ return 0;
1500
+ }
1501
+ return float16_to_int16_scalbn(x, get_float_rounding_mode(fpst),
1502
+ shift, fpst);
1503
+}
1504
+
1505
+uint32_t HELPER(vfp_touhh)(uint32_t x, uint32_t shift, void *fpst)
1506
+{
1507
+ if (unlikely(float16_is_any_nan(x))) {
1508
+ float_raise(float_flag_invalid, fpst);
1509
+ return 0;
1510
+ }
1511
+ return float16_to_uint16_scalbn(x, get_float_rounding_mode(fpst),
1512
+ shift, fpst);
1513
+}
1514
+
1515
+uint32_t HELPER(vfp_toslh)(uint32_t x, uint32_t shift, void *fpst)
1516
+{
1517
+ if (unlikely(float16_is_any_nan(x))) {
1518
+ float_raise(float_flag_invalid, fpst);
1519
+ return 0;
1520
+ }
1521
+ return float16_to_int32_scalbn(x, get_float_rounding_mode(fpst),
1522
+ shift, fpst);
1523
+}
1524
+
1525
+uint32_t HELPER(vfp_toulh)(uint32_t x, uint32_t shift, void *fpst)
1526
+{
1527
+ if (unlikely(float16_is_any_nan(x))) {
1528
+ float_raise(float_flag_invalid, fpst);
1529
+ return 0;
1530
+ }
1531
+ return float16_to_uint32_scalbn(x, get_float_rounding_mode(fpst),
1532
+ shift, fpst);
1533
+}
1534
+
1535
+uint64_t HELPER(vfp_tosqh)(uint32_t x, uint32_t shift, void *fpst)
1536
+{
1537
+ if (unlikely(float16_is_any_nan(x))) {
1538
+ float_raise(float_flag_invalid, fpst);
1539
+ return 0;
1540
+ }
1541
+ return float16_to_int64_scalbn(x, get_float_rounding_mode(fpst),
1542
+ shift, fpst);
1543
+}
1544
+
1545
+uint64_t HELPER(vfp_touqh)(uint32_t x, uint32_t shift, void *fpst)
1546
+{
1547
+ if (unlikely(float16_is_any_nan(x))) {
1548
+ float_raise(float_flag_invalid, fpst);
1549
+ return 0;
1550
+ }
1551
+ return float16_to_uint64_scalbn(x, get_float_rounding_mode(fpst),
1552
+ shift, fpst);
1553
+}
1554
+
1555
+/* Set the current fp rounding mode and return the old one.
1556
+ * The argument is a softfloat float_round_ value.
1557
+ */
1558
+uint32_t HELPER(set_rmode)(uint32_t rmode, void *fpstp)
1559
+{
1560
+ float_status *fp_status = fpstp;
1561
+
1562
+ uint32_t prev_rmode = get_float_rounding_mode(fp_status);
1563
+ set_float_rounding_mode(rmode, fp_status);
1564
+
1565
+ return prev_rmode;
1566
+}
1567
+
1568
+/* Set the current fp rounding mode in the standard fp status and return
1569
+ * the old one. This is for NEON instructions that need to change the
1570
+ * rounding mode but wish to use the standard FPSCR values for everything
1571
+ * else. Always set the rounding mode back to the correct value after
1572
+ * modifying it.
1573
+ * The argument is a softfloat float_round_ value.
1574
+ */
1575
+uint32_t HELPER(set_neon_rmode)(uint32_t rmode, CPUARMState *env)
1576
+{
1577
+ float_status *fp_status = &env->vfp.standard_fp_status;
1578
+
1579
+ uint32_t prev_rmode = get_float_rounding_mode(fp_status);
1580
+ set_float_rounding_mode(rmode, fp_status);
1581
+
1582
+ return prev_rmode;
1583
+}
1584
+
1585
+/* Half precision conversions. */
1586
+float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, void *fpstp, uint32_t ahp_mode)
1587
+{
1588
+ /* Squash FZ16 to 0 for the duration of conversion. In this case,
1589
+ * it would affect flushing input denormals.
1590
+ */
1591
+ float_status *fpst = fpstp;
1592
+ flag save = get_flush_inputs_to_zero(fpst);
1593
+ set_flush_inputs_to_zero(false, fpst);
1594
+ float32 r = float16_to_float32(a, !ahp_mode, fpst);
1595
+ set_flush_inputs_to_zero(save, fpst);
1596
+ return r;
1597
+}
1598
+
1599
+uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
1600
+{
1601
+ /* Squash FZ16 to 0 for the duration of conversion. In this case,
1602
+ * it would affect flushing output denormals.
1603
+ */
1604
+ float_status *fpst = fpstp;
1605
+ flag save = get_flush_to_zero(fpst);
1606
+ set_flush_to_zero(false, fpst);
1607
+ float16 r = float32_to_float16(a, !ahp_mode, fpst);
1608
+ set_flush_to_zero(save, fpst);
1609
+ return r;
1610
+}
1611
+
1612
+float64 HELPER(vfp_fcvt_f16_to_f64)(uint32_t a, void *fpstp, uint32_t ahp_mode)
1613
+{
1614
+ /* Squash FZ16 to 0 for the duration of conversion. In this case,
1615
+ * it would affect flushing input denormals.
1616
+ */
1617
+ float_status *fpst = fpstp;
1618
+ flag save = get_flush_inputs_to_zero(fpst);
1619
+ set_flush_inputs_to_zero(false, fpst);
1620
+ float64 r = float16_to_float64(a, !ahp_mode, fpst);
1621
+ set_flush_inputs_to_zero(save, fpst);
1622
+ return r;
1623
+}
1624
+
1625
+uint32_t HELPER(vfp_fcvt_f64_to_f16)(float64 a, void *fpstp, uint32_t ahp_mode)
1626
+{
1627
+ /* Squash FZ16 to 0 for the duration of conversion. In this case,
1628
+ * it would affect flushing output denormals.
1629
+ */
1630
+ float_status *fpst = fpstp;
1631
+ flag save = get_flush_to_zero(fpst);
1632
+ set_flush_to_zero(false, fpst);
1633
+ float16 r = float64_to_float16(a, !ahp_mode, fpst);
1634
+ set_flush_to_zero(save, fpst);
1635
+ return r;
1636
+}
1637
+
1638
+#define float32_two make_float32(0x40000000)
1639
+#define float32_three make_float32(0x40400000)
1640
+#define float32_one_point_five make_float32(0x3fc00000)
1641
+
1642
+float32 HELPER(recps_f32)(float32 a, float32 b, CPUARMState *env)
1643
+{
1644
+ float_status *s = &env->vfp.standard_fp_status;
1645
+ if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) ||
1646
+ (float32_is_infinity(b) && float32_is_zero_or_denormal(a))) {
1647
+ if (!(float32_is_zero(a) || float32_is_zero(b))) {
1648
+ float_raise(float_flag_input_denormal, s);
1649
+ }
1650
+ return float32_two;
1651
+ }
1652
+ return float32_sub(float32_two, float32_mul(a, b, s), s);
1653
+}
1654
+
1655
+float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUARMState *env)
1656
+{
1657
+ float_status *s = &env->vfp.standard_fp_status;
1658
+ float32 product;
1659
+ if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) ||
1660
+ (float32_is_infinity(b) && float32_is_zero_or_denormal(a))) {
1661
+ if (!(float32_is_zero(a) || float32_is_zero(b))) {
1662
+ float_raise(float_flag_input_denormal, s);
1663
+ }
1664
+ return float32_one_point_five;
1665
+ }
1666
+ product = float32_mul(a, b, s);
1667
+ return float32_div(float32_sub(float32_three, product, s), float32_two, s);
1668
+}
1669
+
1670
+/* NEON helpers. */
1671
+
1672
+/* Constants 256 and 512 are used in some helpers; we avoid relying on
1673
+ * int->float conversions at run-time. */
1674
+#define float64_256 make_float64(0x4070000000000000LL)
1675
+#define float64_512 make_float64(0x4080000000000000LL)
1676
+#define float16_maxnorm make_float16(0x7bff)
1677
+#define float32_maxnorm make_float32(0x7f7fffff)
1678
+#define float64_maxnorm make_float64(0x7fefffffffffffffLL)
1679
+
1680
+/* Reciprocal functions
1681
+ *
1682
+ * The algorithm that must be used to calculate the estimate
1683
+ * is specified by the ARM ARM, see FPRecipEstimate()/RecipEstimate
1684
+ */
1685
+
1686
+/* See RecipEstimate()
1687
+ *
1688
+ * input is a 9 bit fixed point number
1689
+ * input range 256 .. 511 for a number from 0.5 <= x < 1.0.
1690
+ * result range 256 .. 511 for a number from 1.0 to 511/256.
1691
+ */
1692
+
1693
+static int recip_estimate(int input)
1694
+{
1695
+ int a, b, r;
1696
+ assert(256 <= input && input < 512);
1697
+ a = (input * 2) + 1;
1698
+ b = (1 << 19) / a;
1699
+ r = (b + 1) >> 1;
1700
+ assert(256 <= r && r < 512);
1701
+ return r;
1702
+}
1703
+
1704
+/*
1705
+ * Common wrapper to call recip_estimate
1706
+ *
1707
+ * The parameters are exponent and 64 bit fraction (without implicit
1708
+ * bit) where the binary point is nominally at bit 52. Returns a
1709
+ * float64 which can then be rounded to the appropriate size by the
1710
+ * callee.
1711
+ */
1712
+
1713
+static uint64_t call_recip_estimate(int *exp, int exp_off, uint64_t frac)
1714
+{
1715
+ uint32_t scaled, estimate;
1716
+ uint64_t result_frac;
1717
+ int result_exp;
1718
+
1719
+ /* Handle sub-normals */
1720
+ if (*exp == 0) {
1721
+ if (extract64(frac, 51, 1) == 0) {
1722
+ *exp = -1;
1723
+ frac <<= 2;
1724
+ } else {
1725
+ frac <<= 1;
1726
+ }
69
+ }
1727
+ }
70
+ }
71
+ same_el = (arm_current_el(env) == target_el);
1728
+
72
+
1729
+ /* scaled = UInt('1':fraction<51:44>) */
73
+ fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc);
1730
+ scaled = deposit32(1 << 8, 0, 8, extract64(frac, 44, 8));
1731
+ estimate = recip_estimate(scaled);
1732
+
74
+
1733
+ result_exp = exp_off - *exp;
75
if (access_type == MMU_INST_FETCH) {
1734
+ result_frac = deposit64(0, 44, 8, estimate);
76
syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc);
1735
+ if (result_exp == 0) {
77
exc = EXCP_PREFETCH_ABORT;
1736
+ result_frac = deposit64(result_frac >> 1, 51, 1, 1);
1737
+ } else if (result_exp == -1) {
1738
+ result_frac = deposit64(result_frac >> 2, 50, 2, 1);
1739
+ result_exp = 0;
1740
+ }
1741
+
1742
+ *exp = result_exp;
1743
+
1744
+ return result_frac;
1745
+}
1746
+
1747
+static bool round_to_inf(float_status *fpst, bool sign_bit)
1748
+{
1749
+ switch (fpst->float_rounding_mode) {
1750
+ case float_round_nearest_even: /* Round to Nearest */
1751
+ return true;
1752
+ case float_round_up: /* Round to +Inf */
1753
+ return !sign_bit;
1754
+ case float_round_down: /* Round to -Inf */
1755
+ return sign_bit;
1756
+ case float_round_to_zero: /* Round to Zero */
1757
+ return false;
1758
+ }
1759
+
1760
+ g_assert_not_reached();
1761
+}
1762
+
1763
+uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
1764
+{
1765
+ float_status *fpst = fpstp;
1766
+ float16 f16 = float16_squash_input_denormal(input, fpst);
1767
+ uint32_t f16_val = float16_val(f16);
1768
+ uint32_t f16_sign = float16_is_neg(f16);
1769
+ int f16_exp = extract32(f16_val, 10, 5);
1770
+ uint32_t f16_frac = extract32(f16_val, 0, 10);
1771
+ uint64_t f64_frac;
1772
+
1773
+ if (float16_is_any_nan(f16)) {
1774
+ float16 nan = f16;
1775
+ if (float16_is_signaling_nan(f16, fpst)) {
1776
+ float_raise(float_flag_invalid, fpst);
1777
+ nan = float16_silence_nan(f16, fpst);
1778
+ }
1779
+ if (fpst->default_nan_mode) {
1780
+ nan = float16_default_nan(fpst);
1781
+ }
1782
+ return nan;
1783
+ } else if (float16_is_infinity(f16)) {
1784
+ return float16_set_sign(float16_zero, float16_is_neg(f16));
1785
+ } else if (float16_is_zero(f16)) {
1786
+ float_raise(float_flag_divbyzero, fpst);
1787
+ return float16_set_sign(float16_infinity, float16_is_neg(f16));
1788
+ } else if (float16_abs(f16) < (1 << 8)) {
1789
+ /* Abs(value) < 2.0^-16 */
1790
+ float_raise(float_flag_overflow | float_flag_inexact, fpst);
1791
+ if (round_to_inf(fpst, f16_sign)) {
1792
+ return float16_set_sign(float16_infinity, f16_sign);
1793
+ } else {
1794
+ return float16_set_sign(float16_maxnorm, f16_sign);
1795
+ }
1796
+ } else if (f16_exp >= 29 && fpst->flush_to_zero) {
1797
+ float_raise(float_flag_underflow, fpst);
1798
+ return float16_set_sign(float16_zero, float16_is_neg(f16));
1799
+ }
1800
+
1801
+ f64_frac = call_recip_estimate(&f16_exp, 29,
1802
+ ((uint64_t) f16_frac) << (52 - 10));
1803
+
1804
+ /* result = sign : result_exp<4:0> : fraction<51:42> */
1805
+ f16_val = deposit32(0, 15, 1, f16_sign);
1806
+ f16_val = deposit32(f16_val, 10, 5, f16_exp);
1807
+ f16_val = deposit32(f16_val, 0, 10, extract64(f64_frac, 52 - 10, 10));
1808
+ return make_float16(f16_val);
1809
+}
1810
+
1811
+float32 HELPER(recpe_f32)(float32 input, void *fpstp)
1812
+{
1813
+ float_status *fpst = fpstp;
1814
+ float32 f32 = float32_squash_input_denormal(input, fpst);
1815
+ uint32_t f32_val = float32_val(f32);
1816
+ bool f32_sign = float32_is_neg(f32);
1817
+ int f32_exp = extract32(f32_val, 23, 8);
1818
+ uint32_t f32_frac = extract32(f32_val, 0, 23);
1819
+ uint64_t f64_frac;
1820
+
1821
+ if (float32_is_any_nan(f32)) {
1822
+ float32 nan = f32;
1823
+ if (float32_is_signaling_nan(f32, fpst)) {
1824
+ float_raise(float_flag_invalid, fpst);
1825
+ nan = float32_silence_nan(f32, fpst);
1826
+ }
1827
+ if (fpst->default_nan_mode) {
1828
+ nan = float32_default_nan(fpst);
1829
+ }
1830
+ return nan;
1831
+ } else if (float32_is_infinity(f32)) {
1832
+ return float32_set_sign(float32_zero, float32_is_neg(f32));
1833
+ } else if (float32_is_zero(f32)) {
1834
+ float_raise(float_flag_divbyzero, fpst);
1835
+ return float32_set_sign(float32_infinity, float32_is_neg(f32));
1836
+ } else if (float32_abs(f32) < (1ULL << 21)) {
1837
+ /* Abs(value) < 2.0^-128 */
1838
+ float_raise(float_flag_overflow | float_flag_inexact, fpst);
1839
+ if (round_to_inf(fpst, f32_sign)) {
1840
+ return float32_set_sign(float32_infinity, f32_sign);
1841
+ } else {
1842
+ return float32_set_sign(float32_maxnorm, f32_sign);
1843
+ }
1844
+ } else if (f32_exp >= 253 && fpst->flush_to_zero) {
1845
+ float_raise(float_flag_underflow, fpst);
1846
+ return float32_set_sign(float32_zero, float32_is_neg(f32));
1847
+ }
1848
+
1849
+ f64_frac = call_recip_estimate(&f32_exp, 253,
1850
+ ((uint64_t) f32_frac) << (52 - 23));
1851
+
1852
+ /* result = sign : result_exp<7:0> : fraction<51:29> */
1853
+ f32_val = deposit32(0, 31, 1, f32_sign);
1854
+ f32_val = deposit32(f32_val, 23, 8, f32_exp);
1855
+ f32_val = deposit32(f32_val, 0, 23, extract64(f64_frac, 52 - 23, 23));
1856
+ return make_float32(f32_val);
1857
+}
1858
+
1859
+float64 HELPER(recpe_f64)(float64 input, void *fpstp)
1860
+{
1861
+ float_status *fpst = fpstp;
1862
+ float64 f64 = float64_squash_input_denormal(input, fpst);
1863
+ uint64_t f64_val = float64_val(f64);
1864
+ bool f64_sign = float64_is_neg(f64);
1865
+ int f64_exp = extract64(f64_val, 52, 11);
1866
+ uint64_t f64_frac = extract64(f64_val, 0, 52);
1867
+
1868
+ /* Deal with any special cases */
1869
+ if (float64_is_any_nan(f64)) {
1870
+ float64 nan = f64;
1871
+ if (float64_is_signaling_nan(f64, fpst)) {
1872
+ float_raise(float_flag_invalid, fpst);
1873
+ nan = float64_silence_nan(f64, fpst);
1874
+ }
1875
+ if (fpst->default_nan_mode) {
1876
+ nan = float64_default_nan(fpst);
1877
+ }
1878
+ return nan;
1879
+ } else if (float64_is_infinity(f64)) {
1880
+ return float64_set_sign(float64_zero, float64_is_neg(f64));
1881
+ } else if (float64_is_zero(f64)) {
1882
+ float_raise(float_flag_divbyzero, fpst);
1883
+ return float64_set_sign(float64_infinity, float64_is_neg(f64));
1884
+ } else if ((f64_val & ~(1ULL << 63)) < (1ULL << 50)) {
1885
+ /* Abs(value) < 2.0^-1024 */
1886
+ float_raise(float_flag_overflow | float_flag_inexact, fpst);
1887
+ if (round_to_inf(fpst, f64_sign)) {
1888
+ return float64_set_sign(float64_infinity, f64_sign);
1889
+ } else {
1890
+ return float64_set_sign(float64_maxnorm, f64_sign);
1891
+ }
1892
+ } else if (f64_exp >= 2045 && fpst->flush_to_zero) {
1893
+ float_raise(float_flag_underflow, fpst);
1894
+ return float64_set_sign(float64_zero, float64_is_neg(f64));
1895
+ }
1896
+
1897
+ f64_frac = call_recip_estimate(&f64_exp, 2045, f64_frac);
1898
+
1899
+ /* result = sign : result_exp<10:0> : fraction<51:0>; */
1900
+ f64_val = deposit64(0, 63, 1, f64_sign);
1901
+ f64_val = deposit64(f64_val, 52, 11, f64_exp);
1902
+ f64_val = deposit64(f64_val, 0, 52, f64_frac);
1903
+ return make_float64(f64_val);
1904
+}
1905
+
1906
+/* The algorithm that must be used to calculate the estimate
1907
+ * is specified by the ARM ARM.
1908
+ */
1909
+
1910
+static int do_recip_sqrt_estimate(int a)
1911
+{
1912
+ int b, estimate;
1913
+
1914
+ assert(128 <= a && a < 512);
1915
+ if (a < 256) {
1916
+ a = a * 2 + 1;
1917
+ } else {
1918
+ a = (a >> 1) << 1;
1919
+ a = (a + 1) * 2;
1920
+ }
1921
+ b = 512;
1922
+ while (a * (b + 1) * (b + 1) < (1 << 28)) {
1923
+ b += 1;
1924
+ }
1925
+ estimate = (b + 1) / 2;
1926
+ assert(256 <= estimate && estimate < 512);
1927
+
1928
+ return estimate;
1929
+}
1930
+
1931
+
1932
+static uint64_t recip_sqrt_estimate(int *exp , int exp_off, uint64_t frac)
1933
+{
1934
+ int estimate;
1935
+ uint32_t scaled;
1936
+
1937
+ if (*exp == 0) {
1938
+ while (extract64(frac, 51, 1) == 0) {
1939
+ frac = frac << 1;
1940
+ *exp -= 1;
1941
+ }
1942
+ frac = extract64(frac, 0, 51) << 1;
1943
+ }
1944
+
1945
+ if (*exp & 1) {
1946
+ /* scaled = UInt('01':fraction<51:45>) */
1947
+ scaled = deposit32(1 << 7, 0, 7, extract64(frac, 45, 7));
1948
+ } else {
1949
+ /* scaled = UInt('1':fraction<51:44>) */
1950
+ scaled = deposit32(1 << 8, 0, 8, extract64(frac, 44, 8));
1951
+ }
1952
+ estimate = do_recip_sqrt_estimate(scaled);
1953
+
1954
+ *exp = (exp_off - *exp) / 2;
1955
+ return extract64(estimate, 0, 8) << 44;
1956
+}
1957
+
1958
+uint32_t HELPER(rsqrte_f16)(uint32_t input, void *fpstp)
1959
+{
1960
+ float_status *s = fpstp;
1961
+ float16 f16 = float16_squash_input_denormal(input, s);
1962
+ uint16_t val = float16_val(f16);
1963
+ bool f16_sign = float16_is_neg(f16);
1964
+ int f16_exp = extract32(val, 10, 5);
1965
+ uint16_t f16_frac = extract32(val, 0, 10);
1966
+ uint64_t f64_frac;
1967
+
1968
+ if (float16_is_any_nan(f16)) {
1969
+ float16 nan = f16;
1970
+ if (float16_is_signaling_nan(f16, s)) {
1971
+ float_raise(float_flag_invalid, s);
1972
+ nan = float16_silence_nan(f16, s);
1973
+ }
1974
+ if (s->default_nan_mode) {
1975
+ nan = float16_default_nan(s);
1976
+ }
1977
+ return nan;
1978
+ } else if (float16_is_zero(f16)) {
1979
+ float_raise(float_flag_divbyzero, s);
1980
+ return float16_set_sign(float16_infinity, f16_sign);
1981
+ } else if (f16_sign) {
1982
+ float_raise(float_flag_invalid, s);
1983
+ return float16_default_nan(s);
1984
+ } else if (float16_is_infinity(f16)) {
1985
+ return float16_zero;
1986
+ }
1987
+
1988
+ /* Scale and normalize to a double-precision value between 0.25 and 1.0,
1989
+ * preserving the parity of the exponent. */
1990
+
1991
+ f64_frac = ((uint64_t) f16_frac) << (52 - 10);
1992
+
1993
+ f64_frac = recip_sqrt_estimate(&f16_exp, 44, f64_frac);
1994
+
1995
+ /* result = sign : result_exp<4:0> : estimate<7:0> : Zeros(2) */
1996
+ val = deposit32(0, 15, 1, f16_sign);
1997
+ val = deposit32(val, 10, 5, f16_exp);
1998
+ val = deposit32(val, 2, 8, extract64(f64_frac, 52 - 8, 8));
1999
+ return make_float16(val);
2000
+}
2001
+
2002
+float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
2003
+{
2004
+ float_status *s = fpstp;
2005
+ float32 f32 = float32_squash_input_denormal(input, s);
2006
+ uint32_t val = float32_val(f32);
2007
+ uint32_t f32_sign = float32_is_neg(f32);
2008
+ int f32_exp = extract32(val, 23, 8);
2009
+ uint32_t f32_frac = extract32(val, 0, 23);
2010
+ uint64_t f64_frac;
2011
+
2012
+ if (float32_is_any_nan(f32)) {
2013
+ float32 nan = f32;
2014
+ if (float32_is_signaling_nan(f32, s)) {
2015
+ float_raise(float_flag_invalid, s);
2016
+ nan = float32_silence_nan(f32, s);
2017
+ }
2018
+ if (s->default_nan_mode) {
2019
+ nan = float32_default_nan(s);
2020
+ }
2021
+ return nan;
2022
+ } else if (float32_is_zero(f32)) {
2023
+ float_raise(float_flag_divbyzero, s);
2024
+ return float32_set_sign(float32_infinity, float32_is_neg(f32));
2025
+ } else if (float32_is_neg(f32)) {
2026
+ float_raise(float_flag_invalid, s);
2027
+ return float32_default_nan(s);
2028
+ } else if (float32_is_infinity(f32)) {
2029
+ return float32_zero;
2030
+ }
2031
+
2032
+ /* Scale and normalize to a double-precision value between 0.25 and 1.0,
2033
+ * preserving the parity of the exponent. */
2034
+
2035
+ f64_frac = ((uint64_t) f32_frac) << 29;
2036
+
2037
+ f64_frac = recip_sqrt_estimate(&f32_exp, 380, f64_frac);
2038
+
2039
+ /* result = sign : result_exp<4:0> : estimate<7:0> : Zeros(15) */
2040
+ val = deposit32(0, 31, 1, f32_sign);
2041
+ val = deposit32(val, 23, 8, f32_exp);
2042
+ val = deposit32(val, 15, 8, extract64(f64_frac, 52 - 8, 8));
2043
+ return make_float32(val);
2044
+}
2045
+
2046
+float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
2047
+{
2048
+ float_status *s = fpstp;
2049
+ float64 f64 = float64_squash_input_denormal(input, s);
2050
+ uint64_t val = float64_val(f64);
2051
+ bool f64_sign = float64_is_neg(f64);
2052
+ int f64_exp = extract64(val, 52, 11);
2053
+ uint64_t f64_frac = extract64(val, 0, 52);
2054
+
2055
+ if (float64_is_any_nan(f64)) {
2056
+ float64 nan = f64;
2057
+ if (float64_is_signaling_nan(f64, s)) {
2058
+ float_raise(float_flag_invalid, s);
2059
+ nan = float64_silence_nan(f64, s);
2060
+ }
2061
+ if (s->default_nan_mode) {
2062
+ nan = float64_default_nan(s);
2063
+ }
2064
+ return nan;
2065
+ } else if (float64_is_zero(f64)) {
2066
+ float_raise(float_flag_divbyzero, s);
2067
+ return float64_set_sign(float64_infinity, float64_is_neg(f64));
2068
+ } else if (float64_is_neg(f64)) {
2069
+ float_raise(float_flag_invalid, s);
2070
+ return float64_default_nan(s);
2071
+ } else if (float64_is_infinity(f64)) {
2072
+ return float64_zero;
2073
+ }
2074
+
2075
+ f64_frac = recip_sqrt_estimate(&f64_exp, 3068, f64_frac);
2076
+
2077
+ /* result = sign : result_exp<4:0> : estimate<7:0> : Zeros(44) */
2078
+ val = deposit64(0, 61, 1, f64_sign);
2079
+ val = deposit64(val, 52, 11, f64_exp);
2080
+ val = deposit64(val, 44, 8, extract64(f64_frac, 52 - 8, 8));
2081
+ return make_float64(val);
2082
+}
2083
+
2084
+uint32_t HELPER(recpe_u32)(uint32_t a, void *fpstp)
2085
+{
2086
+ /* float_status *s = fpstp; */
2087
+ int input, estimate;
2088
+
2089
+ if ((a & 0x80000000) == 0) {
2090
+ return 0xffffffff;
2091
+ }
2092
+
2093
+ input = extract32(a, 23, 9);
2094
+ estimate = recip_estimate(input);
2095
+
2096
+ return deposit32(0, (32 - 9), 9, estimate);
2097
+}
2098
+
2099
+uint32_t HELPER(rsqrte_u32)(uint32_t a, void *fpstp)
2100
+{
2101
+ int estimate;
2102
+
2103
+ if ((a & 0xc0000000) == 0) {
2104
+ return 0xffffffff;
2105
+ }
2106
+
2107
+ estimate = do_recip_sqrt_estimate(extract32(a, 23, 9));
2108
+
2109
+ return deposit32(0, 23, 9, estimate);
2110
+}
2111
+
2112
+/* VFPv4 fused multiply-accumulate */
2113
+float32 VFP_HELPER(muladd, s)(float32 a, float32 b, float32 c, void *fpstp)
2114
+{
2115
+ float_status *fpst = fpstp;
2116
+ return float32_muladd(a, b, c, 0, fpst);
2117
+}
2118
+
2119
+float64 VFP_HELPER(muladd, d)(float64 a, float64 b, float64 c, void *fpstp)
2120
+{
2121
+ float_status *fpst = fpstp;
2122
+ return float64_muladd(a, b, c, 0, fpst);
2123
+}
2124
+
2125
+/* ARMv8 round to integral */
2126
+float32 HELPER(rints_exact)(float32 x, void *fp_status)
2127
+{
2128
+ return float32_round_to_int(x, fp_status);
2129
+}
2130
+
2131
+float64 HELPER(rintd_exact)(float64 x, void *fp_status)
2132
+{
2133
+ return float64_round_to_int(x, fp_status);
2134
+}
2135
+
2136
+float32 HELPER(rints)(float32 x, void *fp_status)
2137
+{
2138
+ int old_flags = get_float_exception_flags(fp_status), new_flags;
2139
+ float32 ret;
2140
+
2141
+ ret = float32_round_to_int(x, fp_status);
2142
+
2143
+ /* Suppress any inexact exceptions the conversion produced */
2144
+ if (!(old_flags & float_flag_inexact)) {
2145
+ new_flags = get_float_exception_flags(fp_status);
2146
+ set_float_exception_flags(new_flags & ~float_flag_inexact, fp_status);
2147
+ }
2148
+
2149
+ return ret;
2150
+}
2151
+
2152
+float64 HELPER(rintd)(float64 x, void *fp_status)
2153
+{
2154
+ int old_flags = get_float_exception_flags(fp_status), new_flags;
2155
+ float64 ret;
2156
+
2157
+ ret = float64_round_to_int(x, fp_status);
2158
+
2159
+ new_flags = get_float_exception_flags(fp_status);
2160
+
2161
+ /* Suppress any inexact exceptions the conversion produced */
2162
+ if (!(old_flags & float_flag_inexact)) {
2163
+ new_flags = get_float_exception_flags(fp_status);
2164
+ set_float_exception_flags(new_flags & ~float_flag_inexact, fp_status);
2165
+ }
2166
+
2167
+ return ret;
2168
+}
2169
+
2170
+/* Convert ARM rounding mode to softfloat */
2171
+int arm_rmode_to_sf(int rmode)
2172
+{
2173
+ switch (rmode) {
2174
+ case FPROUNDING_TIEAWAY:
2175
+ rmode = float_round_ties_away;
2176
+ break;
2177
+ case FPROUNDING_ODD:
2178
+ /* FIXME: add support for TIEAWAY and ODD */
2179
+ qemu_log_mask(LOG_UNIMP, "arm: unimplemented rounding mode: %d\n",
2180
+ rmode);
2181
+ /* fall through for now */
2182
+ case FPROUNDING_TIEEVEN:
2183
+ default:
2184
+ rmode = float_round_nearest_even;
2185
+ break;
2186
+ case FPROUNDING_POSINF:
2187
+ rmode = float_round_up;
2188
+ break;
2189
+ case FPROUNDING_NEGINF:
2190
+ rmode = float_round_down;
2191
+ break;
2192
+ case FPROUNDING_ZERO:
2193
+ rmode = float_round_to_zero;
2194
+ break;
2195
+ }
2196
+ return rmode;
2197
+}
2198
--
78
--
2199
2.20.1
79
2.25.1
2200
80
2201
81
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
For A64, any input to an indirect branch can cause this.
4
5
For A32, many indirect branch paths force the branch to be aligned,
6
but BXWritePC does not. This includes the BX instruction but also
7
other interworking changes to PC. Prior to v8, this case is UNDEFINED.
8
With v8, this is CONSTRAINED UNPREDICTABLE and may either raise an
9
exception or force align the PC.
10
11
We choose to raise an exception because we have the infrastructure,
12
it makes the generated code for gen_bx simpler, and it has the
13
possibility of catching more guest bugs.
14
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20190215192302.27855-5-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
[PMM: fixed a couple of comment typos]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
18
---
9
target/arm/cpu.h | 10 +++++
19
target/arm/helper.h | 1 +
10
target/arm/helper.h | 3 ++
20
target/arm/syndrome.h | 5 ++++
11
target/arm/cpu.c | 1 +
21
linux-user/aarch64/cpu_loop.c | 46 ++++++++++++++++++++---------------
12
target/arm/cpu64.c | 2 +
22
target/arm/tlb_helper.c | 18 ++++++++++++++
13
target/arm/translate-a64.c | 26 +++++++++++
23
target/arm/translate-a64.c | 15 ++++++++++++
14
target/arm/translate.c | 10 +++++
24
target/arm/translate.c | 22 ++++++++++++++++-
15
target/arm/vfp_helper.c | 88 ++++++++++++++++++++++++++++++++++++++
25
6 files changed, 87 insertions(+), 20 deletions(-)
16
7 files changed, 140 insertions(+)
26
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_vcma(const ARMISARegisters *id)
23
return FIELD_EX32(id->id_isar5, ID_ISAR5, VCMA) != 0;
24
}
25
26
+static inline bool isar_feature_aa32_jscvt(const ARMISARegisters *id)
27
+{
28
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, JSCVT) != 0;
29
+}
30
+
31
static inline bool isar_feature_aa32_dp(const ARMISARegisters *id)
32
{
33
return FIELD_EX32(id->id_isar6, ID_ISAR6, DP) != 0;
34
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dp(const ARMISARegisters *id)
35
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, DP) != 0;
36
}
37
38
+static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
39
+{
40
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
41
+}
42
+
43
static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
44
{
45
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
46
diff --git a/target/arm/helper.h b/target/arm/helper.h
27
diff --git a/target/arm/helper.h b/target/arm/helper.h
47
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/helper.h
29
--- a/target/arm/helper.h
49
+++ b/target/arm/helper.h
30
+++ b/target/arm/helper.h
50
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(rintd_exact, TCG_CALL_NO_RWG, f64, f64, ptr)
31
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_NO_RWG_SE,
51
DEF_HELPER_FLAGS_2(rints, TCG_CALL_NO_RWG, f32, f32, ptr)
32
DEF_HELPER_2(exception_internal, void, env, i32)
52
DEF_HELPER_FLAGS_2(rintd, TCG_CALL_NO_RWG, f64, f64, ptr)
33
DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32)
53
34
DEF_HELPER_2(exception_bkpt_insn, void, env, i32)
54
+DEF_HELPER_FLAGS_2(vjcvt, TCG_CALL_NO_RWG, i32, f64, env)
35
+DEF_HELPER_2(exception_pc_alignment, noreturn, env, tl)
55
+DEF_HELPER_FLAGS_2(fjcvtzs, TCG_CALL_NO_RWG, i64, f64, ptr)
36
DEF_HELPER_1(setend, void, env)
56
+
37
DEF_HELPER_2(wfi, void, env, i32)
57
/* neon_helper.c */
38
DEF_HELPER_1(wfe, void, env)
58
DEF_HELPER_FLAGS_3(neon_qadd_u8, TCG_CALL_NO_RWG, i32, env, i32, i32)
39
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
59
DEF_HELPER_FLAGS_3(neon_qadd_s8, TCG_CALL_NO_RWG, i32, env, i32, i32)
40
index XXXXXXX..XXXXXXX 100644
60
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
41
--- a/target/arm/syndrome.h
61
index XXXXXXX..XXXXXXX 100644
42
+++ b/target/arm/syndrome.h
62
--- a/target/arm/cpu.c
43
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_illegalstate(void)
63
+++ b/target/arm/cpu.c
44
return (EC_ILLEGALSTATE << ARM_EL_EC_SHIFT) | ARM_EL_IL;
64
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
45
}
65
cpu->isar.id_isar5 = t;
46
66
47
+static inline uint32_t syn_pcalignment(void)
67
t = cpu->isar.id_isar6;
48
+{
68
+ t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
49
+ return (EC_PCALIGNMENT << ARM_EL_EC_SHIFT) | ARM_EL_IL;
69
t = FIELD_DP32(t, ID_ISAR6, DP, 1);
50
+}
70
cpu->isar.id_isar6 = t;
51
+
71
52
#endif /* TARGET_ARM_SYNDROME_H */
72
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
53
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
73
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/cpu64.c
55
--- a/linux-user/aarch64/cpu_loop.c
75
+++ b/target/arm/cpu64.c
56
+++ b/linux-user/aarch64/cpu_loop.c
76
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
57
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
77
cpu->isar.id_aa64isar0 = t;
58
break;
78
59
case EXCP_PREFETCH_ABORT:
79
t = cpu->isar.id_aa64isar1;
60
case EXCP_DATA_ABORT:
80
+ t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1);
61
- /* We should only arrive here with EC in {DATAABORT, INSNABORT}. */
81
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
62
ec = syn_get_ec(env->exception.syndrome);
82
t = FIELD_DP64(t, ID_AA64ISAR1, APA, 1); /* PAuth, architected only */
63
- assert(ec == EC_DATAABORT || ec == EC_INSNABORT);
83
t = FIELD_DP64(t, ID_AA64ISAR1, API, 0);
64
-
84
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
65
- /* Both EC have the same format for FSC, or close enough. */
85
cpu->isar.id_isar5 = u;
66
- fsc = extract32(env->exception.syndrome, 0, 6);
86
67
- switch (fsc) {
87
u = cpu->isar.id_isar6;
68
- case 0x04 ... 0x07: /* Translation fault, level {0-3} */
88
+ u = FIELD_DP32(u, ID_ISAR6, JSCVT, 1);
69
- si_signo = TARGET_SIGSEGV;
89
u = FIELD_DP32(u, ID_ISAR6, DP, 1);
70
- si_code = TARGET_SEGV_MAPERR;
90
cpu->isar.id_isar6 = u;
71
+ switch (ec) {
91
72
+ case EC_DATAABORT:
73
+ case EC_INSNABORT:
74
+ /* Both EC have the same format for FSC, or close enough. */
75
+ fsc = extract32(env->exception.syndrome, 0, 6);
76
+ switch (fsc) {
77
+ case 0x04 ... 0x07: /* Translation fault, level {0-3} */
78
+ si_signo = TARGET_SIGSEGV;
79
+ si_code = TARGET_SEGV_MAPERR;
80
+ break;
81
+ case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
82
+ case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
83
+ si_signo = TARGET_SIGSEGV;
84
+ si_code = TARGET_SEGV_ACCERR;
85
+ break;
86
+ case 0x11: /* Synchronous Tag Check Fault */
87
+ si_signo = TARGET_SIGSEGV;
88
+ si_code = TARGET_SEGV_MTESERR;
89
+ break;
90
+ case 0x21: /* Alignment fault */
91
+ si_signo = TARGET_SIGBUS;
92
+ si_code = TARGET_BUS_ADRALN;
93
+ break;
94
+ default:
95
+ g_assert_not_reached();
96
+ }
97
break;
98
- case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
99
- case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
100
- si_signo = TARGET_SIGSEGV;
101
- si_code = TARGET_SEGV_ACCERR;
102
- break;
103
- case 0x11: /* Synchronous Tag Check Fault */
104
- si_signo = TARGET_SIGSEGV;
105
- si_code = TARGET_SEGV_MTESERR;
106
- break;
107
- case 0x21: /* Alignment fault */
108
+ case EC_PCALIGNMENT:
109
si_signo = TARGET_SIGBUS;
110
si_code = TARGET_BUS_ADRALN;
111
break;
112
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/tlb_helper.c
115
+++ b/target/arm/tlb_helper.c
116
@@ -XXX,XX +XXX,XX @@
117
#include "cpu.h"
118
#include "internals.h"
119
#include "exec/exec-all.h"
120
+#include "exec/helper-proto.h"
121
122
static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
123
unsigned int target_el,
124
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
125
arm_deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi);
126
}
127
128
+void helper_exception_pc_alignment(CPUARMState *env, target_ulong pc)
129
+{
130
+ ARMMMUFaultInfo fi = { .type = ARMFault_Alignment };
131
+ int target_el = exception_target_el(env);
132
+ int mmu_idx = cpu_mmu_index(env, true);
133
+ uint32_t fsc;
134
+
135
+ env->exception.vaddress = pc;
136
+
137
+ /*
138
+ * Note that the fsc is not applicable to this exception,
139
+ * since any syndrome is pcalignment not insn_abort.
140
+ */
141
+ env->exception.fsr = compute_fsr_fsc(env, &fi, target_el, mmu_idx, &fsc);
142
+ raise_exception(env, EXCP_PREFETCH_ABORT, syn_pcalignment(), target_el);
143
+}
144
+
145
#if !defined(CONFIG_USER_ONLY)
146
147
/*
92
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
148
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
93
index XXXXXXX..XXXXXXX 100644
149
index XXXXXXX..XXXXXXX 100644
94
--- a/target/arm/translate-a64.c
150
--- a/target/arm/translate-a64.c
95
+++ b/target/arm/translate-a64.c
151
+++ b/target/arm/translate-a64.c
96
@@ -XXX,XX +XXX,XX @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
152
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
153
uint64_t pc = s->base.pc_next;
154
uint32_t insn;
155
156
+ /* Singlestep exceptions have the highest priority. */
157
if (s->ss_active && !s->pstate_ss) {
158
/* Singlestep state is Active-pending.
159
* If we're in this state at the start of a TB then either
160
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
161
return;
97
}
162
}
98
}
163
99
164
+ if (pc & 3) {
100
+static void handle_fjcvtzs(DisasContext *s, int rd, int rn)
165
+ /*
101
+{
166
+ * PC alignment fault. This has priority over the instruction abort
102
+ TCGv_i64 t = read_fp_dreg(s, rn);
167
+ * that we would receive from a translation fault via arm_ldl_code.
103
+ TCGv_ptr fpstatus = get_fpstatus_ptr(false);
168
+ * This should only be possible after an indirect branch, at the
104
+
169
+ * start of the TB.
105
+ gen_helper_fjcvtzs(t, t, fpstatus);
170
+ */
106
+
171
+ assert(s->base.num_insns == 1);
107
+ tcg_temp_free_ptr(fpstatus);
172
+ gen_helper_exception_pc_alignment(cpu_env, tcg_constant_tl(pc));
108
+
173
+ s->base.is_jmp = DISAS_NORETURN;
109
+ tcg_gen_ext32u_i64(cpu_reg(s, rd), t);
174
+ s->base.pc_next = QEMU_ALIGN_UP(pc, 4);
110
+ tcg_gen_extrh_i64_i32(cpu_ZF, t);
175
+ return;
111
+ tcg_gen_movi_i32(cpu_CF, 0);
176
+ }
112
+ tcg_gen_movi_i32(cpu_NF, 0);
177
+
113
+ tcg_gen_movi_i32(cpu_VF, 0);
178
s->pc_curr = pc;
114
+
179
insn = arm_ldl_code(env, &s->base, pc, s->sctlr_b);
115
+ tcg_temp_free_i64(t);
180
s->insn = insn;
116
+}
117
+
118
/* Floating point <-> integer conversions
119
* 31 30 29 28 24 23 22 21 20 19 18 16 15 10 9 5 4 0
120
* +----+---+---+-----------+------+---+-------+-----+-------------+----+----+
121
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
122
handle_fmov(s, rd, rn, type, itof);
123
break;
124
125
+ case 0b00111110: /* FJCVTZS */
126
+ if (!dc_isar_feature(aa64_jscvt, s)) {
127
+ goto do_unallocated;
128
+ } else if (fp_access_check(s)) {
129
+ handle_fjcvtzs(s, rd, rn);
130
+ }
131
+ break;
132
+
133
default:
134
do_unallocated:
135
unallocated_encoding(s);
136
diff --git a/target/arm/translate.c b/target/arm/translate.c
181
diff --git a/target/arm/translate.c b/target/arm/translate.c
137
index XXXXXXX..XXXXXXX 100644
182
index XXXXXXX..XXXXXXX 100644
138
--- a/target/arm/translate.c
183
--- a/target/arm/translate.c
139
+++ b/target/arm/translate.c
184
+++ b/target/arm/translate.c
140
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
185
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
141
rm_is_dp = false;
186
uint32_t pc = dc->base.pc_next;
142
break;
187
unsigned int insn;
143
188
144
+ case 0x13: /* vjcvt */
189
- if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
145
+ if (!dp || !dc_isar_feature(aa32_jscvt, s)) {
190
+ /* Singlestep exceptions have the highest priority. */
146
+ return 1;
191
+ if (arm_check_ss_active(dc)) {
147
+ }
192
+ dc->base.pc_next = pc + 4;
148
+ rd_is_dp = false;
193
+ return;
149
+ break;
194
+ }
150
+
195
+
151
default:
196
+ if (pc & 3) {
152
return 1;
197
+ /*
153
}
198
+ * PC alignment fault. This has priority over the instruction abort
154
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
199
+ * that we would receive from a translation fault via arm_ldl_code
155
case 17: /* fsito */
200
+ * (or the execution of the kernelpage entrypoint). This should only
156
gen_vfp_sito(dp, 0);
201
+ * be possible after an indirect branch, at the start of the TB.
157
break;
202
+ */
158
+ case 19: /* vjcvt */
203
+ assert(dc->base.num_insns == 1);
159
+ gen_helper_vjcvt(cpu_F0s, cpu_F0d, cpu_env);
204
+ gen_helper_exception_pc_alignment(cpu_env, tcg_constant_tl(pc));
160
+ break;
205
+ dc->base.is_jmp = DISAS_NORETURN;
161
case 20: /* fshto */
206
+ dc->base.pc_next = QEMU_ALIGN_UP(pc, 4);
162
gen_vfp_shto(dp, 16 - rm, 0);
207
+ return;
163
break;
208
+ }
164
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
209
+
165
index XXXXXXX..XXXXXXX 100644
210
+ if (arm_check_kernelpage(dc)) {
166
--- a/target/arm/vfp_helper.c
211
dc->base.pc_next = pc + 4;
167
+++ b/target/arm/vfp_helper.c
212
return;
168
@@ -XXX,XX +XXX,XX @@ int arm_rmode_to_sf(int rmode)
169
}
213
}
170
return rmode;
171
}
172
+
173
+/*
174
+ * Implement float64 to int32_t conversion without saturation;
175
+ * the result is supplied modulo 2^32.
176
+ */
177
+uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus)
178
+{
179
+ float_status *status = vstatus;
180
+ uint32_t exp, sign;
181
+ uint64_t frac;
182
+ uint32_t inexact = 1; /* !Z */
183
+
184
+ sign = extract64(value, 63, 1);
185
+ exp = extract64(value, 52, 11);
186
+ frac = extract64(value, 0, 52);
187
+
188
+ if (exp == 0) {
189
+ /* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
190
+ inexact = sign;
191
+ if (frac != 0) {
192
+ if (status->flush_inputs_to_zero) {
193
+ float_raise(float_flag_input_denormal, status);
194
+ } else {
195
+ float_raise(float_flag_inexact, status);
196
+ inexact = 1;
197
+ }
198
+ }
199
+ frac = 0;
200
+ } else if (exp == 0x7ff) {
201
+ /* This operation raises Invalid for both NaN and overflow (Inf). */
202
+ float_raise(float_flag_invalid, status);
203
+ frac = 0;
204
+ } else {
205
+ int true_exp = exp - 1023;
206
+ int shift = true_exp - 52;
207
+
208
+ /* Restore implicit bit. */
209
+ frac |= 1ull << 52;
210
+
211
+ /* Shift the fraction into place. */
212
+ if (shift >= 0) {
213
+ /* The number is so large we must shift the fraction left. */
214
+ if (shift >= 64) {
215
+ /* The fraction is shifted out entirely. */
216
+ frac = 0;
217
+ } else {
218
+ frac <<= shift;
219
+ }
220
+ } else if (shift > -64) {
221
+ /* Normal case -- shift right and notice if bits shift out. */
222
+ inexact = (frac << (64 + shift)) != 0;
223
+ frac >>= -shift;
224
+ } else {
225
+ /* The fraction is shifted out entirely. */
226
+ frac = 0;
227
+ }
228
+
229
+ /* Notice overflow or inexact exceptions. */
230
+ if (true_exp > 31 || frac > (sign ? 0x80000000ull : 0x7fffffff)) {
231
+ /* Overflow, for which this operation raises invalid. */
232
+ float_raise(float_flag_invalid, status);
233
+ inexact = 1;
234
+ } else if (inexact) {
235
+ float_raise(float_flag_inexact, status);
236
+ }
237
+
238
+ /* Honor the sign. */
239
+ if (sign) {
240
+ frac = -frac;
241
+ }
242
+ }
243
+
244
+ /* Pack the result and the env->ZF representation of Z together. */
245
+ return deposit64(frac, 32, 32, inexact);
246
+}
247
+
248
+uint32_t HELPER(vjcvt)(float64 value, CPUARMState *env)
249
+{
250
+ uint64_t pair = HELPER(fjcvtzs)(value, &env->vfp.fp_status);
251
+ uint32_t result = pair;
252
+ uint32_t z = (pair >> 32) == 0;
253
+
254
+ /* Store Z, clear NCV, in FPSCR.NZCV. */
255
+ env->vfp.xregs[ARM_VFP_FPSCR]
256
+ = (env->vfp.xregs[ARM_VFP_FPSCR] & ~CPSR_NZCV) | (z * CPSR_Z);
257
+
258
+ return result;
259
+}
260
--
214
--
261
2.20.1
215
2.25.1
262
216
263
217
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Misaligned thumb PC is architecturally impossible.
4
Assert is better than proceeding, in case we've missed
5
something somewhere.
6
7
Expand a comment about aligning the pc in gdbstub.
8
Fail an incoming migrate if a thumb pc is misaligned.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/gdbstub.c | 9 +++++++--
15
target/arm/machine.c | 10 ++++++++++
16
target/arm/translate.c | 3 +++
17
3 files changed, 20 insertions(+), 2 deletions(-)
18
19
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/gdbstub.c
22
+++ b/target/arm/gdbstub.c
23
@@ -XXX,XX +XXX,XX @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
24
25
tmp = ldl_p(mem_buf);
26
27
- /* Mask out low bit of PC to workaround gdb bugs. This will probably
28
- cause problems if we ever implement the Jazelle DBX extensions. */
29
+ /*
30
+ * Mask out low bits of PC to workaround gdb bugs.
31
+ * This avoids an assert in thumb_tr_translate_insn, because it is
32
+ * architecturally impossible to misalign the pc.
33
+ * This will probably cause problems if we ever implement the
34
+ * Jazelle DBX extensions.
35
+ */
36
if (n == 15) {
37
tmp &= ~1;
38
}
39
diff --git a/target/arm/machine.c b/target/arm/machine.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/machine.c
42
+++ b/target/arm/machine.c
43
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
44
return -1;
45
}
46
}
47
+
48
+ /*
49
+ * Misaligned thumb pc is architecturally impossible.
50
+ * We have an assert in thumb_tr_translate_insn to verify this.
51
+ * Fail an incoming migrate to avoid this assert.
52
+ */
53
+ if (!is_a64(env) && env->thumb && (env->regs[15] & 1)) {
54
+ return -1;
55
+ }
56
+
57
if (!kvm_enabled()) {
58
pmu_op_finish(&cpu->env);
59
}
60
diff --git a/target/arm/translate.c b/target/arm/translate.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/translate.c
63
+++ b/target/arm/translate.c
64
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
65
uint32_t insn;
66
bool is_16bit;
67
68
+ /* Misaligned thumb PC is architecturally impossible. */
69
+ assert((dc->base.pc_next & 1) == 0);
70
+
71
if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
72
dc->base.pc_next = pc + 2;
73
return;
74
--
75
2.25.1
76
77
diff view generated by jsdifflib
1
The region 0x40010000 .. 0x4001ffff and its secure-only alias
1
From: Richard Henderson <richard.henderson@linaro.org>
2
at 0x50010000... are for per-CPU devices. We implement this by
3
giving each CPU its own container memory region, where the
4
per-CPU devices live. Unfortunately, the alias region which
5
makes devices mapped at 0x4... addresses also appear at 0x5...
6
is only implemented in the overall "all CPUs" container. The
7
effect of this bug is that the CPU_IDENTITY register block appears
8
only at 0x4001f000, but not at the 0x5001f000 alias where it should
9
also appear. Guests (like very recent Arm Trusted Firmware-M)
10
which try to access it at 0x5001f000 will crash.
11
2
12
Fix this by moving the handling for this alias from the "all CPUs"
3
Both single-step and pc alignment faults have priority over
13
container to the per-CPU container. (We leave the aliases for
4
breakpoint exceptions.
14
0x1... and 0x3... in the overall container, because there are
15
no per-CPU devices there.)
16
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Message-id: 20190215180500.6906-1-peter.maydell@linaro.org
19
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
20
---
9
---
21
include/hw/arm/armsse.h | 2 +-
10
target/arm/debug_helper.c | 23 +++++++++++++++++++++++
22
hw/arm/armsse.c | 26 ++++++++++++++++----------
11
1 file changed, 23 insertions(+)
23
2 files changed, 17 insertions(+), 11 deletions(-)
24
12
25
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
13
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
26
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/arm/armsse.h
15
--- a/target/arm/debug_helper.c
28
+++ b/include/hw/arm/armsse.h
16
+++ b/target/arm/debug_helper.c
29
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
17
@@ -XXX,XX +XXX,XX @@ bool arm_debug_check_breakpoint(CPUState *cs)
30
MemoryRegion cpu_container[SSE_MAX_CPUS];
31
MemoryRegion alias1;
32
MemoryRegion alias2;
33
- MemoryRegion alias3;
34
+ MemoryRegion alias3[SSE_MAX_CPUS];
35
MemoryRegion sram[MAX_SRAM_BANKS];
36
37
qemu_irq *exp_irqs[SSE_MAX_CPUS];
38
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/armsse.c
41
+++ b/hw/arm/armsse.c
42
@@ -XXX,XX +XXX,XX @@ static bool irq_is_common[32] = {
43
/* 30, 31: reserved */
44
};
45
46
-/* Create an alias region of @size bytes starting at @base
47
+/*
48
+ * Create an alias region in @container of @size bytes starting at @base
49
* which mirrors the memory starting at @orig.
50
*/
51
-static void make_alias(ARMSSE *s, MemoryRegion *mr, const char *name,
52
- hwaddr base, hwaddr size, hwaddr orig)
53
+static void make_alias(ARMSSE *s, MemoryRegion *mr, MemoryRegion *container,
54
+ const char *name, hwaddr base, hwaddr size, hwaddr orig)
55
{
18
{
56
- memory_region_init_alias(mr, NULL, name, &s->container, orig, size);
19
ARMCPU *cpu = ARM_CPU(cs);
57
+ memory_region_init_alias(mr, NULL, name, container, orig, size);
20
CPUARMState *env = &cpu->env;
58
/* The alias is even lower priority than unimplemented_device regions */
21
+ target_ulong pc;
59
- memory_region_add_subregion_overlap(&s->container, base, mr, -1500);
22
int n;
60
+ memory_region_add_subregion_overlap(container, base, mr, -1500);
23
61
}
24
/*
62
25
@@ -XXX,XX +XXX,XX @@ bool arm_debug_check_breakpoint(CPUState *cs)
63
static void irq_status_forwarder(void *opaque, int n, int level)
26
return false;
64
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
65
}
27
}
66
28
67
/* Set up the big aliases first */
29
+ /*
68
- make_alias(s, &s->alias1, "alias 1", 0x10000000, 0x10000000, 0x00000000);
30
+ * Single-step exceptions have priority over breakpoint exceptions.
69
- make_alias(s, &s->alias2, "alias 2", 0x30000000, 0x10000000, 0x20000000);
31
+ * If single-step state is active-pending, suppress the bp.
70
+ make_alias(s, &s->alias1, &s->container, "alias 1",
32
+ */
71
+ 0x10000000, 0x10000000, 0x00000000);
33
+ if (arm_singlestep_active(env) && !(env->pstate & PSTATE_SS)) {
72
+ make_alias(s, &s->alias2, &s->container,
34
+ return false;
73
+ "alias 2", 0x30000000, 0x10000000, 0x20000000);
74
/* The 0x50000000..0x5fffffff region is not a pure alias: it has
75
* a few extra devices that only appear there (generally the
76
* control interfaces for the protection controllers).
77
* We implement this by mapping those devices over the top of this
78
- * alias MR at a higher priority.
79
+ * alias MR at a higher priority. Some of the devices in this range
80
+ * are per-CPU, so we must put this alias in the per-cpu containers.
81
*/
82
- make_alias(s, &s->alias3, "alias 3", 0x50000000, 0x10000000, 0x40000000);
83
-
84
+ for (i = 0; i < info->num_cpus; i++) {
85
+ make_alias(s, &s->alias3[i], &s->cpu_container[i],
86
+ "alias 3", 0x50000000, 0x10000000, 0x40000000);
87
+ }
35
+ }
88
36
+
89
/* Security controller */
37
+ /*
90
object_property_set_bool(OBJECT(&s->secctl), true, "realized", &err);
38
+ * PC alignment faults have priority over breakpoint exceptions.
39
+ */
40
+ pc = is_a64(env) ? env->pc : env->regs[15];
41
+ if ((is_a64(env) || !env->thumb) && (pc & 3) != 0) {
42
+ return false;
43
+ }
44
+
45
+ /*
46
+ * Instruction aborts have priority over breakpoint exceptions.
47
+ * TODO: We would need to look up the page for PC and verify that
48
+ * it is present and executable.
49
+ */
50
+
51
for (n = 0; n < ARRAY_SIZE(env->cpu_breakpoint); n++) {
52
if (bp_wp_matches(cpu, n, false)) {
53
return true;
91
--
54
--
92
2.20.1
55
2.25.1
93
56
94
57
diff view generated by jsdifflib
1
Many of the devices on the Musca board live behind TrustZone
1
From: Richard Henderson <richard.henderson@linaro.org>
2
Peripheral Protection Controllers (PPCs); add models of the
3
PPCs, using a similar scheme to the MPS2 board models.
4
This commit wires up the PPCs with "unimplemented device"
5
stubs behind them in the correct places in the address map.
6
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
---
6
---
10
hw/arm/musca.c | 289 +++++++++++++++++++++++++++++++++++++++++++++++++
7
tests/tcg/aarch64/pcalign-a64.c | 37 +++++++++++++++++++++++++
11
1 file changed, 289 insertions(+)
8
tests/tcg/arm/pcalign-a32.c | 46 +++++++++++++++++++++++++++++++
9
tests/tcg/aarch64/Makefile.target | 4 +--
10
tests/tcg/arm/Makefile.target | 4 +++
11
4 files changed, 89 insertions(+), 2 deletions(-)
12
create mode 100644 tests/tcg/aarch64/pcalign-a64.c
13
create mode 100644 tests/tcg/arm/pcalign-a32.c
12
14
13
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
15
diff --git a/tests/tcg/aarch64/pcalign-a64.c b/tests/tcg/aarch64/pcalign-a64.c
14
index XXXXXXX..XXXXXXX 100644
16
new file mode 100644
15
--- a/hw/arm/musca.c
17
index XXXXXXX..XXXXXXX
16
+++ b/hw/arm/musca.c
18
--- /dev/null
19
+++ b/tests/tcg/aarch64/pcalign-a64.c
17
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
18
#include "hw/arm/armsse.h"
21
+/* Test PC misalignment exception */
19
#include "hw/boards.h"
20
#include "hw/core/split-irq.h"
21
+#include "hw/misc/tz-ppc.h"
22
+#include "hw/misc/unimp.h"
23
24
#define MUSCA_NUMIRQ_MAX 96
25
+#define MUSCA_PPC_MAX 3
26
27
typedef enum MuscaType {
28
MUSCA_A,
29
@@ -XXX,XX +XXX,XX @@ typedef struct {
30
31
ARMSSE sse;
32
SplitIRQ cpu_irq_splitter[MUSCA_NUMIRQ_MAX];
33
+ SplitIRQ sec_resp_splitter;
34
+ TZPPC ppc[MUSCA_PPC_MAX];
35
+ MemoryRegion container;
36
+ UnimplementedDeviceState eflash[2];
37
+ UnimplementedDeviceState qspi;
38
+ UnimplementedDeviceState mpc[5];
39
+ UnimplementedDeviceState mhu[2];
40
+ UnimplementedDeviceState pwm[3];
41
+ UnimplementedDeviceState i2s;
42
+ UnimplementedDeviceState uart[2];
43
+ UnimplementedDeviceState i2c[2];
44
+ UnimplementedDeviceState spi;
45
+ UnimplementedDeviceState scc;
46
+ UnimplementedDeviceState timer;
47
+ UnimplementedDeviceState rtc;
48
+ UnimplementedDeviceState pvt;
49
+ UnimplementedDeviceState sdio;
50
+ UnimplementedDeviceState gpio;
51
} MuscaMachineState;
52
53
#define TYPE_MUSCA_MACHINE "musca"
54
@@ -XXX,XX +XXX,XX @@ typedef struct {
55
*/
56
#define SYSCLK_FRQ 40000000
57
58
+/*
59
+ * Most of the devices in the Musca board sit behind Peripheral Protection
60
+ * Controllers. These data structures define the layout of which devices
61
+ * sit behind which PPCs.
62
+ * The devfn for each port is a function which creates, configures
63
+ * and initializes the device, returning the MemoryRegion which
64
+ * needs to be plugged into the downstream end of the PPC port.
65
+ */
66
+typedef MemoryRegion *MakeDevFn(MuscaMachineState *mms, void *opaque,
67
+ const char *name, hwaddr size);
68
+
22
+
69
+typedef struct PPCPortInfo {
23
+#include <assert.h>
70
+ const char *name;
24
+#include <signal.h>
71
+ MakeDevFn *devfn;
25
+#include <stdlib.h>
72
+ void *opaque;
26
+#include <stdio.h>
73
+ hwaddr addr;
74
+ hwaddr size;
75
+} PPCPortInfo;
76
+
27
+
77
+typedef struct PPCInfo {
28
+static void *expected;
78
+ const char *name;
79
+ PPCPortInfo ports[TZ_NUM_PORTS];
80
+} PPCInfo;
81
+
29
+
82
+static MemoryRegion *make_unimp_dev(MuscaMachineState *mms,
30
+static void sigbus(int sig, siginfo_t *info, void *vuc)
83
+ void *opaque, const char *name, hwaddr size)
84
+{
31
+{
85
+ /*
32
+ assert(info->si_code == BUS_ADRALN);
86
+ * Initialize, configure and realize a TYPE_UNIMPLEMENTED_DEVICE,
33
+ assert(info->si_addr == expected);
87
+ * and return a pointer to its MemoryRegion.
34
+ exit(EXIT_SUCCESS);
88
+ */
89
+ UnimplementedDeviceState *uds = opaque;
90
+
91
+ sysbus_init_child_obj(OBJECT(mms), name, uds,
92
+ sizeof(UnimplementedDeviceState),
93
+ TYPE_UNIMPLEMENTED_DEVICE);
94
+ qdev_prop_set_string(DEVICE(uds), "name", name);
95
+ qdev_prop_set_uint64(DEVICE(uds), "size", size);
96
+ object_property_set_bool(OBJECT(uds), true, "realized", &error_fatal);
97
+ return sysbus_mmio_get_region(SYS_BUS_DEVICE(uds), 0);
98
+}
35
+}
99
+
36
+
100
+static MemoryRegion *make_musca_a_devs(MuscaMachineState *mms, void *opaque,
37
+int main()
101
+ const char *name, hwaddr size)
102
+{
38
+{
103
+ /*
39
+ void *tmp;
104
+ * Create the container MemoryRegion for all the devices that live
105
+ * behind the Musca-A PPC's single port. These devices don't have a PPC
106
+ * port each, but we use the PPCPortInfo struct as a convenient way
107
+ * to describe them. Note that addresses here are relative to the base
108
+ * address of the PPC port region: 0x40100000, and devices appear both
109
+ * at the 0x4... NS region and the 0x5... S region.
110
+ */
111
+ int i;
112
+ MemoryRegion *container = &mms->container;
113
+
40
+
114
+ const PPCPortInfo devices[] = {
41
+ struct sigaction sa = {
115
+ { "uart0", make_unimp_dev, &mms->uart[0], 0x1000, 0x1000 },
42
+ .sa_sigaction = sigbus,
116
+ { "uart1", make_unimp_dev, &mms->uart[1], 0x2000, 0x1000 },
43
+ .sa_flags = SA_SIGINFO
117
+ { "spi", make_unimp_dev, &mms->spi, 0x3000, 0x1000 },
118
+ { "i2c0", make_unimp_dev, &mms->i2c[0], 0x4000, 0x1000 },
119
+ { "i2c1", make_unimp_dev, &mms->i2c[1], 0x5000, 0x1000 },
120
+ { "i2s", make_unimp_dev, &mms->i2s, 0x6000, 0x1000 },
121
+ { "pwm0", make_unimp_dev, &mms->pwm[0], 0x7000, 0x1000 },
122
+ { "rtc", make_unimp_dev, &mms->rtc, 0x8000, 0x1000 },
123
+ { "qspi", make_unimp_dev, &mms->qspi, 0xa000, 0x1000 },
124
+ { "timer", make_unimp_dev, &mms->timer, 0xb000, 0x1000 },
125
+ { "scc", make_unimp_dev, &mms->scc, 0xc000, 0x1000 },
126
+ { "pwm1", make_unimp_dev, &mms->pwm[1], 0xe000, 0x1000 },
127
+ { "pwm2", make_unimp_dev, &mms->pwm[2], 0xf000, 0x1000 },
128
+ { "gpio", make_unimp_dev, &mms->gpio, 0x10000, 0x1000 },
129
+ { "mpc0", make_unimp_dev, &mms->mpc[0], 0x12000, 0x1000 },
130
+ { "mpc1", make_unimp_dev, &mms->mpc[1], 0x13000, 0x1000 },
131
+ };
44
+ };
132
+
45
+
133
+ memory_region_init(container, OBJECT(mms), "musca-device-container", size);
46
+ if (sigaction(SIGBUS, &sa, NULL) < 0) {
134
+
47
+ perror("sigaction");
135
+ for (i = 0; i < ARRAY_SIZE(devices); i++) {
48
+ return EXIT_FAILURE;
136
+ const PPCPortInfo *pinfo = &devices[i];
137
+ MemoryRegion *mr;
138
+
139
+ mr = pinfo->devfn(mms, pinfo->opaque, pinfo->name, pinfo->size);
140
+ memory_region_add_subregion(container, pinfo->addr, mr);
141
+ }
49
+ }
142
+
50
+
143
+ return &mms->container;
51
+ asm volatile("adr %0, 1f + 1\n\t"
52
+ "str %0, %1\n\t"
53
+ "br %0\n"
54
+ "1:"
55
+ : "=&r"(tmp), "=m"(expected));
56
+ abort();
57
+}
58
diff --git a/tests/tcg/arm/pcalign-a32.c b/tests/tcg/arm/pcalign-a32.c
59
new file mode 100644
60
index XXXXXXX..XXXXXXX
61
--- /dev/null
62
+++ b/tests/tcg/arm/pcalign-a32.c
63
@@ -XXX,XX +XXX,XX @@
64
+/* Test PC misalignment exception */
65
+
66
+#ifdef __thumb__
67
+#error "This test must be compiled for ARM"
68
+#endif
69
+
70
+#include <assert.h>
71
+#include <signal.h>
72
+#include <stdlib.h>
73
+#include <stdio.h>
74
+
75
+static void *expected;
76
+
77
+static void sigbus(int sig, siginfo_t *info, void *vuc)
78
+{
79
+ assert(info->si_code == BUS_ADRALN);
80
+ assert(info->si_addr == expected);
81
+ exit(EXIT_SUCCESS);
144
+}
82
+}
145
+
83
+
146
static void musca_init(MachineState *machine)
84
+int main()
147
{
85
+{
148
MuscaMachineState *mms = MUSCA_MACHINE(machine);
86
+ void *tmp;
149
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
87
+
150
MachineClass *mc = MACHINE_GET_CLASS(machine);
88
+ struct sigaction sa = {
151
MemoryRegion *system_memory = get_system_memory();
89
+ .sa_sigaction = sigbus,
152
DeviceState *ssedev;
90
+ .sa_flags = SA_SIGINFO
153
+ DeviceState *dev_splitter;
91
+ };
154
+ const PPCInfo *ppcs;
92
+
155
+ int num_ppcs;
93
+ if (sigaction(SIGBUS, &sa, NULL) < 0) {
156
int i;
94
+ perror("sigaction");
157
95
+ return EXIT_FAILURE;
158
assert(mmc->num_irqs <= MUSCA_NUMIRQ_MAX);
96
+ }
159
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
97
+
160
"EXP_CPU1_IRQ", i));
98
+ asm volatile("adr %0, 1f + 2\n\t"
161
}
99
+ "str %0, %1\n\t"
162
100
+ "bx %0\n"
163
+ /*
101
+ "1:"
164
+ * The sec_resp_cfg output from the SSE-200 must be split into multiple
102
+ : "=&r"(tmp), "=m"(expected));
165
+ * lines, one for each of the PPCs we create here.
166
+ */
167
+ object_initialize(&mms->sec_resp_splitter, sizeof(mms->sec_resp_splitter),
168
+ TYPE_SPLIT_IRQ);
169
+ object_property_add_child(OBJECT(machine), "sec-resp-splitter",
170
+ OBJECT(&mms->sec_resp_splitter), &error_fatal);
171
+ object_property_set_int(OBJECT(&mms->sec_resp_splitter),
172
+ ARRAY_SIZE(mms->ppc), "num-lines", &error_fatal);
173
+ object_property_set_bool(OBJECT(&mms->sec_resp_splitter), true,
174
+ "realized", &error_fatal);
175
+ dev_splitter = DEVICE(&mms->sec_resp_splitter);
176
+ qdev_connect_gpio_out_named(ssedev, "sec_resp_cfg", 0,
177
+ qdev_get_gpio_in(dev_splitter, 0));
178
+
103
+
179
+ /*
104
+ /*
180
+ * Most of the devices in the board are behind Peripheral Protection
105
+ * From v8, it is CONSTRAINED UNPREDICTABLE whether BXWritePC aligns
181
+ * Controllers. The required order for initializing things is:
106
+ * the address or not. If so, we can legitimately fall through.
182
+ * + initialize the PPC
183
+ * + initialize, configure and realize downstream devices
184
+ * + connect downstream device MemoryRegions to the PPC
185
+ * + realize the PPC
186
+ * + map the PPC's MemoryRegions to the places in the address map
187
+ * where the downstream devices should appear
188
+ * + wire up the PPC's control lines to the SSE object
189
+ *
190
+ * The PPC mapping differs for the -A and -B1 variants; the -A version
191
+ * is much simpler, using only a single port of a single PPC and putting
192
+ * all the devices behind that.
193
+ */
107
+ */
194
+ const PPCInfo a_ppcs[] = { {
108
+ return EXIT_SUCCESS;
195
+ .name = "ahb_ppcexp0",
109
+}
196
+ .ports = {
110
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
197
+ { "musca-devices", make_musca_a_devs, 0, 0x40100000, 0x100000 },
111
index XXXXXXX..XXXXXXX 100644
198
+ },
112
--- a/tests/tcg/aarch64/Makefile.target
199
+ },
113
+++ b/tests/tcg/aarch64/Makefile.target
200
+ };
114
@@ -XXX,XX +XXX,XX @@ VPATH         += $(ARM_SRC)
115
AARCH64_SRC=$(SRC_PATH)/tests/tcg/aarch64
116
VPATH         += $(AARCH64_SRC)
117
118
-# Float-convert Tests
119
-AARCH64_TESTS=fcvt
120
+# Base architecture tests
121
+AARCH64_TESTS=fcvt pcalign-a64
122
123
fcvt: LDFLAGS+=-lm
124
125
diff --git a/tests/tcg/arm/Makefile.target b/tests/tcg/arm/Makefile.target
126
index XXXXXXX..XXXXXXX 100644
127
--- a/tests/tcg/arm/Makefile.target
128
+++ b/tests/tcg/arm/Makefile.target
129
@@ -XXX,XX +XXX,XX @@ run-fcvt: fcvt
130
    $(call run-test,fcvt,$(QEMU) $<,"$< on $(TARGET_NAME)")
131
    $(call diff-out,fcvt,$(ARM_SRC)/fcvt.ref)
132
133
+# PC alignment test
134
+ARM_TESTS += pcalign-a32
135
+pcalign-a32: CFLAGS+=-marm
201
+
136
+
202
+ /*
137
ifeq ($(CONFIG_ARM_COMPATIBLE_SEMIHOSTING),y)
203
+ * Devices listed with an 0x4.. address appear in both the NS 0x4.. region
138
204
+ * and the 0x5.. S region. Devices listed with an 0x5.. address appear
139
# Semihosting smoke test for linux-user
205
+ * only in the S region.
206
+ */
207
+ const PPCInfo b1_ppcs[] = { {
208
+ .name = "apb_ppcexp0",
209
+ .ports = {
210
+ { "eflash0", make_unimp_dev, &mms->eflash[0],
211
+ 0x52400000, 0x1000 },
212
+ { "eflash1", make_unimp_dev, &mms->eflash[1],
213
+ 0x52500000, 0x1000 },
214
+ { "qspi", make_unimp_dev, &mms->qspi, 0x42800000, 0x100000 },
215
+ { "mpc0", make_unimp_dev, &mms->mpc[0], 0x52000000, 0x1000 },
216
+ { "mpc1", make_unimp_dev, &mms->mpc[1], 0x52100000, 0x1000 },
217
+ { "mpc2", make_unimp_dev, &mms->mpc[2], 0x52200000, 0x1000 },
218
+ { "mpc3", make_unimp_dev, &mms->mpc[3], 0x52300000, 0x1000 },
219
+ { "mhu0", make_unimp_dev, &mms->mhu[0], 0x42600000, 0x100000 },
220
+ { "mhu1", make_unimp_dev, &mms->mhu[1], 0x42700000, 0x100000 },
221
+ { }, /* port 9: unused */
222
+ { }, /* port 10: unused */
223
+ { }, /* port 11: unused */
224
+ { }, /* port 12: unused */
225
+ { }, /* port 13: unused */
226
+ { "mpc4", make_unimp_dev, &mms->mpc[4], 0x52e00000, 0x1000 },
227
+ },
228
+ }, {
229
+ .name = "apb_ppcexp1",
230
+ .ports = {
231
+ { "pwm0", make_unimp_dev, &mms->pwm[0], 0x40101000, 0x1000 },
232
+ { "pwm1", make_unimp_dev, &mms->pwm[1], 0x40102000, 0x1000 },
233
+ { "pwm2", make_unimp_dev, &mms->pwm[2], 0x40103000, 0x1000 },
234
+ { "i2s", make_unimp_dev, &mms->i2s, 0x40104000, 0x1000 },
235
+ { "uart0", make_unimp_dev, &mms->uart[0], 0x40105000, 0x1000 },
236
+ { "uart1", make_unimp_dev, &mms->uart[1], 0x40106000, 0x1000 },
237
+ { "i2c0", make_unimp_dev, &mms->i2c[0], 0x40108000, 0x1000 },
238
+ { "i2c1", make_unimp_dev, &mms->i2c[1], 0x40109000, 0x1000 },
239
+ { "spi", make_unimp_dev, &mms->spi, 0x4010a000, 0x1000 },
240
+ { "scc", make_unimp_dev, &mms->scc, 0x5010b000, 0x1000 },
241
+ { "timer", make_unimp_dev, &mms->timer, 0x4010c000, 0x1000 },
242
+ { "rtc", make_unimp_dev, &mms->rtc, 0x4010d000, 0x1000 },
243
+ { "pvt", make_unimp_dev, &mms->pvt, 0x4010e000, 0x1000 },
244
+ { "sdio", make_unimp_dev, &mms->sdio, 0x4010f000, 0x1000 },
245
+ },
246
+ }, {
247
+ .name = "ahb_ppcexp0",
248
+ .ports = {
249
+ { }, /* port 0: unused */
250
+ { "gpio", make_unimp_dev, &mms->gpio, 0x41000000, 0x1000 },
251
+ },
252
+ },
253
+ };
254
+
255
+ switch (mmc->type) {
256
+ case MUSCA_A:
257
+ ppcs = a_ppcs;
258
+ num_ppcs = ARRAY_SIZE(a_ppcs);
259
+ break;
260
+ case MUSCA_B1:
261
+ ppcs = b1_ppcs;
262
+ num_ppcs = ARRAY_SIZE(b1_ppcs);
263
+ break;
264
+ default:
265
+ g_assert_not_reached();
266
+ }
267
+ assert(num_ppcs <= MUSCA_PPC_MAX);
268
+
269
+ for (i = 0; i < num_ppcs; i++) {
270
+ const PPCInfo *ppcinfo = &ppcs[i];
271
+ TZPPC *ppc = &mms->ppc[i];
272
+ DeviceState *ppcdev;
273
+ int port;
274
+ char *gpioname;
275
+
276
+ sysbus_init_child_obj(OBJECT(machine), ppcinfo->name, ppc,
277
+ sizeof(TZPPC), TYPE_TZ_PPC);
278
+ ppcdev = DEVICE(ppc);
279
+
280
+ for (port = 0; port < TZ_NUM_PORTS; port++) {
281
+ const PPCPortInfo *pinfo = &ppcinfo->ports[port];
282
+ MemoryRegion *mr;
283
+ char *portname;
284
+
285
+ if (!pinfo->devfn) {
286
+ continue;
287
+ }
288
+
289
+ mr = pinfo->devfn(mms, pinfo->opaque, pinfo->name, pinfo->size);
290
+ portname = g_strdup_printf("port[%d]", port);
291
+ object_property_set_link(OBJECT(ppc), OBJECT(mr),
292
+ portname, &error_fatal);
293
+ g_free(portname);
294
+ }
295
+
296
+ object_property_set_bool(OBJECT(ppc), true, "realized", &error_fatal);
297
+
298
+ for (port = 0; port < TZ_NUM_PORTS; port++) {
299
+ const PPCPortInfo *pinfo = &ppcinfo->ports[port];
300
+
301
+ if (!pinfo->devfn) {
302
+ continue;
303
+ }
304
+ sysbus_mmio_map(SYS_BUS_DEVICE(ppc), port, pinfo->addr);
305
+
306
+ gpioname = g_strdup_printf("%s_nonsec", ppcinfo->name);
307
+ qdev_connect_gpio_out_named(ssedev, gpioname, port,
308
+ qdev_get_gpio_in_named(ppcdev,
309
+ "cfg_nonsec",
310
+ port));
311
+ g_free(gpioname);
312
+ gpioname = g_strdup_printf("%s_ap", ppcinfo->name);
313
+ qdev_connect_gpio_out_named(ssedev, gpioname, port,
314
+ qdev_get_gpio_in_named(ppcdev,
315
+ "cfg_ap", port));
316
+ g_free(gpioname);
317
+ }
318
+
319
+ gpioname = g_strdup_printf("%s_irq_enable", ppcinfo->name);
320
+ qdev_connect_gpio_out_named(ssedev, gpioname, 0,
321
+ qdev_get_gpio_in_named(ppcdev,
322
+ "irq_enable", 0));
323
+ g_free(gpioname);
324
+ gpioname = g_strdup_printf("%s_irq_clear", ppcinfo->name);
325
+ qdev_connect_gpio_out_named(ssedev, gpioname, 0,
326
+ qdev_get_gpio_in_named(ppcdev,
327
+ "irq_clear", 0));
328
+ g_free(gpioname);
329
+ gpioname = g_strdup_printf("%s_irq_status", ppcinfo->name);
330
+ qdev_connect_gpio_out_named(ppcdev, "irq", 0,
331
+ qdev_get_gpio_in_named(ssedev,
332
+ gpioname, 0));
333
+ g_free(gpioname);
334
+
335
+ qdev_connect_gpio_out(dev_splitter, i,
336
+ qdev_get_gpio_in_named(ppcdev,
337
+ "cfg_sec_resp", 0));
338
+ }
339
+
340
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x2000000);
341
}
342
343
--
140
--
344
2.20.1
141
2.25.1
345
142
346
143
diff view generated by jsdifflib
1
In commit 4b635cf7a95e501211 we added a QOM property to the ARMSSE
1
In the SSE decode function gen_sse(), we combine a byte
2
object, but forgot to add it to the documentation comment in the
2
'b' and a value 'b1' which can be [0..3], and switch on them:
3
header. Correct the omission.
3
b |= (b1 << 8);
4
switch (b) {
5
...
6
default:
7
unknown_op:
8
gen_unknown_opcode(env, s);
9
return;
10
}
4
11
5
Fixes: 4b635cf7a95e501211 ("hw/arm/armsse: Make SRAM bank size configurable")
12
In three cases inside this switch, we were then also checking for
13
"if (b1 >= 2) { goto unknown_op; }".
14
However, this can never happen, because the 'case' values in each place
15
are 0x0nn or 0x1nn and the switch will have directed the b1 == (2, 3)
16
cases to the default already.
17
18
This check was added in commit c045af25a52e9 in 2010; the added code
19
was unnecessary then as well, and was apparently intended only to
20
ensure that we never accidentally ended up indexing off the end
21
of an sse_op_table with only 2 entries as a result of future bugs
22
in the decode logic.
23
24
Change the checks to assert() instead, and make sure they're always
25
immediately before the array access they are protecting.
26
27
Fixes: Coverity CID 1460207
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
---
30
---
9
include/hw/arm/armsse.h | 2 ++
31
target/i386/tcg/translate.c | 12 +++---------
10
1 file changed, 2 insertions(+)
32
1 file changed, 3 insertions(+), 9 deletions(-)
11
33
12
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
34
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
13
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/armsse.h
36
--- a/target/i386/tcg/translate.c
15
+++ b/include/hw/arm/armsse.h
37
+++ b/target/i386/tcg/translate.c
16
@@ -XXX,XX +XXX,XX @@
38
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
17
* being the same for both, to avoid having to have separate Property
39
case 0x171: /* shift xmm, im */
18
* lists for different variants. This restriction can be relaxed later
40
case 0x172:
19
* if necessary.)
41
case 0x173:
20
+ * + QOM property "SRAM_ADDR_WIDTH" sets the number of bits used for the
42
- if (b1 >= 2) {
21
+ * address of each SRAM bank (and thus the total amount of internal SRAM)
43
- goto unknown_op;
22
* + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts for CPU 0,
44
- }
23
* which are wired to its NVIC lines 32 .. n+32
45
val = x86_ldub_code(env, s);
24
* + Named GPIO inputs "EXP_CPU1_IRQ" 0..n are the expansion interrupts for
46
if (is_xmm) {
47
tcg_gen_movi_tl(s->T0, val);
48
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
49
offsetof(CPUX86State, mmx_t0.MMX_L(1)));
50
op1_offset = offsetof(CPUX86State,mmx_t0);
51
}
52
+ assert(b1 < 2);
53
sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
54
(((modrm >> 3)) & 7)][b1];
55
if (!sse_fn_epp) {
56
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
57
rm = modrm & 7;
58
reg = ((modrm >> 3) & 7) | REX_R(s);
59
mod = (modrm >> 6) & 3;
60
- if (b1 >= 2) {
61
- goto unknown_op;
62
- }
63
64
+ assert(b1 < 2);
65
sse_fn_epp = sse_op_table6[b].op[b1];
66
if (!sse_fn_epp) {
67
goto unknown_op;
68
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
69
rm = modrm & 7;
70
reg = ((modrm >> 3) & 7) | REX_R(s);
71
mod = (modrm >> 6) & 3;
72
- if (b1 >= 2) {
73
- goto unknown_op;
74
- }
75
76
+ assert(b1 < 2);
77
sse_fn_eppi = sse_op_table7[b].op[b1];
78
if (!sse_fn_eppi) {
79
goto unknown_op;
25
--
80
--
26
2.20.1
81
2.25.1
27
82
28
83
diff view generated by jsdifflib
1
The PL011 UART has six interrupt lines:
1
The qemu-common.h header is not supposed to be included from any
2
* RX (receive data)
2
other header files, only from .c files (as documented in a comment at
3
* TX (transmit data)
3
the start of it).
4
* RT (receive timeout)
5
* MS (modem status)
6
* E (errors)
7
* combined (logical OR of all the above)
8
4
9
So far we have only emulated the combined interrupt line;
5
include/hw/i386/x86.h and include/hw/i386/microvm.h break this rule.
10
add support for the others, so that boards that wire them
6
In fact, the include is not required at all, so we can just drop it
11
up to different interrupt controller inputs can do so.
7
from both files.
12
8
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20211129200510.1233037-2-peter.maydell@linaro.org
15
---
13
---
16
include/hw/char/pl011.h | 2 +-
14
include/hw/i386/microvm.h | 1 -
17
hw/char/pl011.c | 46 +++++++++++++++++++++++++++++++++++++++--
15
include/hw/i386/x86.h | 1 -
18
2 files changed, 45 insertions(+), 3 deletions(-)
16
2 files changed, 2 deletions(-)
19
17
20
diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h
18
diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/char/pl011.h
20
--- a/include/hw/i386/microvm.h
23
+++ b/include/hw/char/pl011.h
21
+++ b/include/hw/i386/microvm.h
24
@@ -XXX,XX +XXX,XX @@ typedef struct PL011State {
22
@@ -XXX,XX +XXX,XX @@
25
int read_count;
23
#ifndef HW_I386_MICROVM_H
26
int read_trigger;
24
#define HW_I386_MICROVM_H
27
CharBackend chr;
25
28
- qemu_irq irq;
26
-#include "qemu-common.h"
29
+ qemu_irq irq[6];
27
#include "exec/hwaddr.h"
30
const unsigned char *id;
28
#include "qemu/notify.h"
31
} PL011State;
29
32
30
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
33
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
34
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/char/pl011.c
32
--- a/include/hw/i386/x86.h
36
+++ b/hw/char/pl011.c
33
+++ b/include/hw/i386/x86.h
37
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@
38
* This code is licensed under the GPL.
35
#ifndef HW_I386_X86_H
39
*/
36
#define HW_I386_X86_H
40
37
41
+/*
38
-#include "qemu-common.h"
42
+ * QEMU interface:
39
#include "exec/hwaddr.h"
43
+ * + sysbus MMIO region 0: device registers
40
#include "qemu/notify.h"
44
+ * + sysbus IRQ 0: UARTINTR (combined interrupt line)
41
45
+ * + sysbus IRQ 1: UARTRXINTR (receive FIFO interrupt line)
46
+ * + sysbus IRQ 2: UARTTXINTR (transmit FIFO interrupt line)
47
+ * + sysbus IRQ 3: UARTRTINTR (receive timeout interrupt line)
48
+ * + sysbus IRQ 4: UARTMSINTR (momem status interrupt line)
49
+ * + sysbus IRQ 5: UARTEINTR (error interrupt line)
50
+ */
51
+
52
#include "qemu/osdep.h"
53
#include "hw/char/pl011.h"
54
#include "hw/sysbus.h"
55
@@ -XXX,XX +XXX,XX @@
56
#define PL011_FLAG_TXFF 0x20
57
#define PL011_FLAG_RXFE 0x10
58
59
+/* Interrupt status bits in UARTRIS, UARTMIS, UARTIMSC */
60
+#define INT_OE (1 << 10)
61
+#define INT_BE (1 << 9)
62
+#define INT_PE (1 << 8)
63
+#define INT_FE (1 << 7)
64
+#define INT_RT (1 << 6)
65
+#define INT_TX (1 << 5)
66
+#define INT_RX (1 << 4)
67
+#define INT_DSR (1 << 3)
68
+#define INT_DCD (1 << 2)
69
+#define INT_CTS (1 << 1)
70
+#define INT_RI (1 << 0)
71
+#define INT_E (INT_OE | INT_BE | INT_PE | INT_FE)
72
+#define INT_MS (INT_RI | INT_DSR | INT_DCD | INT_CTS)
73
+
74
static const unsigned char pl011_id_arm[8] =
75
{ 0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
76
static const unsigned char pl011_id_luminary[8] =
77
{ 0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1 };
78
79
+/* Which bits in the interrupt status matter for each outbound IRQ line ? */
80
+static const uint32_t irqmask[] = {
81
+ INT_E | INT_MS | INT_RT | INT_TX | INT_RX, /* combined IRQ */
82
+ INT_RX,
83
+ INT_TX,
84
+ INT_RT,
85
+ INT_MS,
86
+ INT_E,
87
+};
88
+
89
static void pl011_update(PL011State *s)
90
{
91
uint32_t flags;
92
+ int i;
93
94
flags = s->int_level & s->int_enabled;
95
trace_pl011_irq_state(flags != 0);
96
- qemu_set_irq(s->irq, flags != 0);
97
+ for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
98
+ qemu_set_irq(s->irq[i], (flags & irqmask[i]) != 0);
99
+ }
100
}
101
102
static uint64_t pl011_read(void *opaque, hwaddr offset,
103
@@ -XXX,XX +XXX,XX @@ static void pl011_init(Object *obj)
104
{
105
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
106
PL011State *s = PL011(obj);
107
+ int i;
108
109
memory_region_init_io(&s->iomem, OBJECT(s), &pl011_ops, s, "pl011", 0x1000);
110
sysbus_init_mmio(sbd, &s->iomem);
111
- sysbus_init_irq(sbd, &s->irq);
112
+ for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
113
+ sysbus_init_irq(sbd, &s->irq[i]);
114
+ }
115
116
s->read_trigger = 1;
117
s->ifl = 0x12;
118
--
42
--
119
2.20.1
43
2.25.1
120
44
121
45
diff view generated by jsdifflib
1
Create a new include file for the pl031's device struct,
1
The qemu-common.h header is not supposed to be included from any
2
type macros, etc, so that it can be instantiated using
2
other header files, only from .c files (as documented in a comment at
3
the "embedded struct" coding style.
3
the start of it).
4
5
Move the include to linux-user/hexagon/cpu_loop.c, which needs it for
6
the declaration of cpu_exec_step_atomic().
4
7
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
12
Message-id: 20211129200510.1233037-3-peter.maydell@linaro.org
8
---
13
---
9
include/hw/timer/pl031.h | 44 ++++++++++++++++++++++++++++++++++++++++
14
target/hexagon/cpu.h | 1 -
10
hw/timer/pl031.c | 25 +----------------------
15
linux-user/hexagon/cpu_loop.c | 1 +
11
MAINTAINERS | 1 +
16
2 files changed, 1 insertion(+), 1 deletion(-)
12
3 files changed, 46 insertions(+), 24 deletions(-)
13
create mode 100644 include/hw/timer/pl031.h
14
17
15
diff --git a/include/hw/timer/pl031.h b/include/hw/timer/pl031.h
18
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
16
new file mode 100644
17
index XXXXXXX..XXXXXXX
18
--- /dev/null
19
+++ b/include/hw/timer/pl031.h
20
@@ -XXX,XX +XXX,XX @@
21
+/*
22
+ * ARM AMBA PrimeCell PL031 RTC
23
+ *
24
+ * Copyright (c) 2007 CodeSourcery
25
+ *
26
+ * This file is free software; you can redistribute it and/or modify
27
+ * it under the terms of the GNU General Public License version 2 as
28
+ * published by the Free Software Foundation.
29
+ *
30
+ * Contributions after 2012-01-13 are licensed under the terms of the
31
+ * GNU GPL, version 2 or (at your option) any later version.
32
+ */
33
+
34
+#ifndef HW_TIMER_PL031
35
+#define HW_TIMER_PL031
36
+
37
+#include "hw/sysbus.h"
38
+
39
+#define TYPE_PL031 "pl031"
40
+#define PL031(obj) OBJECT_CHECK(PL031State, (obj), TYPE_PL031)
41
+
42
+typedef struct PL031State {
43
+ SysBusDevice parent_obj;
44
+
45
+ MemoryRegion iomem;
46
+ QEMUTimer *timer;
47
+ qemu_irq irq;
48
+
49
+ /*
50
+ * Needed to preserve the tick_count across migration, even if the
51
+ * absolute value of the rtc_clock is different on the source and
52
+ * destination.
53
+ */
54
+ uint32_t tick_offset_vmstate;
55
+ uint32_t tick_offset;
56
+
57
+ uint32_t mr;
58
+ uint32_t lr;
59
+ uint32_t cr;
60
+ uint32_t im;
61
+ uint32_t is;
62
+} PL031State;
63
+
64
+#endif
65
diff --git a/hw/timer/pl031.c b/hw/timer/pl031.c
66
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/timer/pl031.c
20
--- a/target/hexagon/cpu.h
68
+++ b/hw/timer/pl031.c
21
+++ b/target/hexagon/cpu.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct CPUHexagonState CPUHexagonState;
23
24
#include "fpu/softfloat-types.h"
25
26
-#include "qemu-common.h"
27
#include "exec/cpu-defs.h"
28
#include "hex_regs.h"
29
#include "mmvec/mmvec.h"
30
diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/linux-user/hexagon/cpu_loop.c
33
+++ b/linux-user/hexagon/cpu_loop.c
69
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@
70
*/
35
*/
71
36
72
#include "qemu/osdep.h"
37
#include "qemu/osdep.h"
73
+#include "hw/timer/pl031.h"
38
+#include "qemu-common.h"
74
#include "hw/sysbus.h"
39
#include "qemu.h"
75
#include "qemu/timer.h"
40
#include "user-internals.h"
76
#include "sysemu/sysemu.h"
41
#include "cpu_loop-common.h"
77
@@ -XXX,XX +XXX,XX @@ do { printf("pl031: " fmt , ## __VA_ARGS__); } while (0)
78
#define RTC_MIS 0x18 /* Masked interrupt status register */
79
#define RTC_ICR 0x1c /* Interrupt clear register */
80
81
-#define TYPE_PL031 "pl031"
82
-#define PL031(obj) OBJECT_CHECK(PL031State, (obj), TYPE_PL031)
83
-
84
-typedef struct PL031State {
85
- SysBusDevice parent_obj;
86
-
87
- MemoryRegion iomem;
88
- QEMUTimer *timer;
89
- qemu_irq irq;
90
-
91
- /* Needed to preserve the tick_count across migration, even if the
92
- * absolute value of the rtc_clock is different on the source and
93
- * destination.
94
- */
95
- uint32_t tick_offset_vmstate;
96
- uint32_t tick_offset;
97
-
98
- uint32_t mr;
99
- uint32_t lr;
100
- uint32_t cr;
101
- uint32_t im;
102
- uint32_t is;
103
-} PL031State;
104
-
105
static const unsigned char pl031_id[] = {
106
0x31, 0x10, 0x14, 0x00, /* Device ID */
107
0x0d, 0xf0, 0x05, 0xb1 /* Cell ID */
108
diff --git a/MAINTAINERS b/MAINTAINERS
109
index XXXXXXX..XXXXXXX 100644
110
--- a/MAINTAINERS
111
+++ b/MAINTAINERS
112
@@ -XXX,XX +XXX,XX @@ F: hw/sd/pl181.c
113
F: hw/ssi/pl022.c
114
F: include/hw/ssi/pl022.h
115
F: hw/timer/pl031.c
116
+F: include/hw/timer/pl031.h
117
F: include/hw/arm/primecell.h
118
F: hw/timer/cmsdk-apb-timer.c
119
F: include/hw/timer/cmsdk-apb-timer.h
120
--
42
--
121
2.20.1
43
2.25.1
122
44
123
45
diff view generated by jsdifflib
1
The Peripheral Protection Controller's handling of unused ports
1
The qemu-common.h header is not supposed to be included from any
2
is that if there is nothing connected to the port's downstream
2
other header files, only from .c files (as documented in a comment at
3
then it does not create the sysbus MMIO region for the upstream
3
the start of it).
4
end of the port. This results in odd behaviour when there is
5
an unused port in the middle of the range: since sysbus MMIO
6
regions are implicitly consecutively allocated, any used ports
7
above the unused ones end up with sysbus MMIO region numbers
8
that don't match the port number.
9
4
10
Avoid this numbering mismatch by creating dummy MMIO regions
5
Nothing actually relies on target/rx/cpu.h including it, so we can
11
for the unused ports. This doesn't change anything for our
6
just drop the include.
12
existing boards, which don't have any gaps in the middle of
13
the port ranges they use; but it will be needed for the Musca
14
board.
15
7
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
12
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
13
Message-id: 20211129200510.1233037-4-peter.maydell@linaro.org
18
---
14
---
19
include/hw/misc/tz-ppc.h | 8 +++++++-
15
target/rx/cpu.h | 1 -
20
hw/misc/tz-ppc.c | 32 ++++++++++++++++++++++++++++++++
16
1 file changed, 1 deletion(-)
21
2 files changed, 39 insertions(+), 1 deletion(-)
22
17
23
diff --git a/include/hw/misc/tz-ppc.h b/include/hw/misc/tz-ppc.h
18
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
24
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/misc/tz-ppc.h
20
--- a/target/rx/cpu.h
26
+++ b/include/hw/misc/tz-ppc.h
21
+++ b/target/rx/cpu.h
27
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
28
*
23
#define RX_CPU_H
29
* QEMU interface:
24
30
* + sysbus MMIO regions 0..15: MemoryRegions defining the upstream end
25
#include "qemu/bitops.h"
31
- * of each of the 16 ports of the PPC
26
-#include "qemu-common.h"
32
+ * of each of the 16 ports of the PPC. When a port is unused (i.e. no
27
#include "hw/registerfields.h"
33
+ * downstream MemoryRegion is connected to it) at the end of the 0..15
28
#include "cpu-qom.h"
34
+ * range then no sysbus MMIO region is created for its upstream. When an
35
+ * unused port lies in the middle of the range with other used ports at
36
+ * higher port numbers, a dummy MMIO region is created to ensure that
37
+ * port N's upstream is always sysbus MMIO region N. Dummy regions should
38
+ * not be mapped, and will assert if any access is made to them.
39
* + Property "port[0..15]": MemoryRegion defining the downstream device(s)
40
* for each of the 16 ports of the PPC
41
* + Named GPIO inputs "cfg_nonsec[0..15]": set to 1 if the port should be
42
diff --git a/hw/misc/tz-ppc.c b/hw/misc/tz-ppc.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/misc/tz-ppc.c
45
+++ b/hw/misc/tz-ppc.c
46
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps tz_ppc_ops = {
47
.endianness = DEVICE_LITTLE_ENDIAN,
48
};
49
50
+static bool tz_ppc_dummy_accepts(void *opaque, hwaddr addr,
51
+ unsigned size, bool is_write,
52
+ MemTxAttrs attrs)
53
+{
54
+ /*
55
+ * Board code should never map the upstream end of an unused port,
56
+ * so we should never try to make a memory access to it.
57
+ */
58
+ g_assert_not_reached();
59
+}
60
+
61
+static const MemoryRegionOps tz_ppc_dummy_ops = {
62
+ .valid.accepts = tz_ppc_dummy_accepts,
63
+};
64
+
65
static void tz_ppc_reset(DeviceState *dev)
66
{
67
TZPPC *s = TZ_PPC(dev);
68
@@ -XXX,XX +XXX,XX @@ static void tz_ppc_realize(DeviceState *dev, Error **errp)
69
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
70
TZPPC *s = TZ_PPC(dev);
71
int i;
72
+ int max_port = 0;
73
74
/* We can't create the upstream end of the port until realize,
75
* as we don't know the size of the MR used as the downstream until then.
76
*/
77
for (i = 0; i < TZ_NUM_PORTS; i++) {
78
+ if (s->port[i].downstream) {
79
+ max_port = i;
80
+ }
81
+ }
82
+
83
+ for (i = 0; i <= max_port; i++) {
84
TZPPCPort *port = &s->port[i];
85
char *name;
86
uint64_t size;
87
88
if (!port->downstream) {
89
+ /*
90
+ * Create dummy sysbus MMIO region so the sysbus region
91
+ * numbering doesn't get out of sync with the port numbers.
92
+ * The size is entirely arbitrary.
93
+ */
94
+ name = g_strdup_printf("tz-ppc-dummy-port[%d]", i);
95
+ memory_region_init_io(&port->upstream, obj, &tz_ppc_dummy_ops,
96
+ port, name, 0x10000);
97
+ sysbus_init_mmio(sbd, &port->upstream);
98
+ g_free(name);
99
continue;
100
}
101
29
102
--
30
--
103
2.20.1
31
2.25.1
104
32
105
33
diff view generated by jsdifflib
1
Create a new include file for the pl011's device struct,
1
A lot of C files in hw/arm include qemu-common.h when they don't
2
type macros, etc, so that it can be instantiated using
2
need anything from it. Drop the include lines.
3
the "embedded struct" coding style.
3
4
omap1.c, pxa2xx.c and strongarm.c retain the include because they
5
use it for the prototype of qemu_get_timedate().
4
6
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
11
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
12
Message-id: 20211129200510.1233037-5-peter.maydell@linaro.org
8
---
13
---
9
include/hw/char/pl011.h | 34 ++++++++++++++++++++++++++++++++++
14
hw/arm/boot.c | 1 -
10
hw/char/pl011.c | 31 ++-----------------------------
15
hw/arm/digic_boards.c | 1 -
11
2 files changed, 36 insertions(+), 29 deletions(-)
16
hw/arm/highbank.c | 1 -
17
hw/arm/npcm7xx_boards.c | 1 -
18
hw/arm/sbsa-ref.c | 1 -
19
hw/arm/stm32f405_soc.c | 1 -
20
hw/arm/vexpress.c | 1 -
21
hw/arm/virt.c | 1 -
22
8 files changed, 8 deletions(-)
12
23
13
diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h
24
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
14
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/char/pl011.h
26
--- a/hw/arm/boot.c
16
+++ b/include/hw/char/pl011.h
27
+++ b/hw/arm/boot.c
17
@@ -XXX,XX +XXX,XX @@
18
#ifndef HW_PL011_H
19
#define HW_PL011_H
20
21
+#include "hw/sysbus.h"
22
+#include "chardev/char-fe.h"
23
+
24
+#define TYPE_PL011 "pl011"
25
+#define PL011(obj) OBJECT_CHECK(PL011State, (obj), TYPE_PL011)
26
+
27
+/* This shares the same struct (and cast macro) as the base pl011 device */
28
+#define TYPE_PL011_LUMINARY "pl011_luminary"
29
+
30
+typedef struct PL011State {
31
+ SysBusDevice parent_obj;
32
+
33
+ MemoryRegion iomem;
34
+ uint32_t readbuff;
35
+ uint32_t flags;
36
+ uint32_t lcr;
37
+ uint32_t rsr;
38
+ uint32_t cr;
39
+ uint32_t dmacr;
40
+ uint32_t int_enabled;
41
+ uint32_t int_level;
42
+ uint32_t read_fifo[16];
43
+ uint32_t ilpr;
44
+ uint32_t ibrd;
45
+ uint32_t fbrd;
46
+ uint32_t ifl;
47
+ int read_pos;
48
+ int read_count;
49
+ int read_trigger;
50
+ CharBackend chr;
51
+ qemu_irq irq;
52
+ const unsigned char *id;
53
+} PL011State;
54
+
55
static inline DeviceState *pl011_create(hwaddr addr,
56
qemu_irq irq,
57
Chardev *chr)
58
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/hw/char/pl011.c
61
+++ b/hw/char/pl011.c
62
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
63
*/
29
*/
64
30
65
#include "qemu/osdep.h"
31
#include "qemu/osdep.h"
66
+#include "hw/char/pl011.h"
32
-#include "qemu-common.h"
33
#include "qemu/datadir.h"
34
#include "qemu/error-report.h"
35
#include "qapi/error.h"
36
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/digic_boards.c
39
+++ b/hw/arm/digic_boards.c
40
@@ -XXX,XX +XXX,XX @@
41
42
#include "qemu/osdep.h"
43
#include "qapi/error.h"
44
-#include "qemu-common.h"
45
#include "qemu/datadir.h"
46
#include "hw/boards.h"
47
#include "qemu/error-report.h"
48
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/arm/highbank.c
51
+++ b/hw/arm/highbank.c
52
@@ -XXX,XX +XXX,XX @@
53
*/
54
55
#include "qemu/osdep.h"
56
-#include "qemu-common.h"
57
#include "qemu/datadir.h"
58
#include "qapi/error.h"
67
#include "hw/sysbus.h"
59
#include "hw/sysbus.h"
68
#include "chardev/char-fe.h"
60
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
69
#include "qemu/log.h"
61
index XXXXXXX..XXXXXXX 100644
70
#include "trace.h"
62
--- a/hw/arm/npcm7xx_boards.c
71
63
+++ b/hw/arm/npcm7xx_boards.c
72
-#define TYPE_PL011 "pl011"
64
@@ -XXX,XX +XXX,XX @@
73
-#define PL011(obj) OBJECT_CHECK(PL011State, (obj), TYPE_PL011)
65
#include "hw/qdev-core.h"
74
-
66
#include "hw/qdev-properties.h"
75
-typedef struct PL011State {
67
#include "qapi/error.h"
76
- SysBusDevice parent_obj;
68
-#include "qemu-common.h"
77
-
69
#include "qemu/datadir.h"
78
- MemoryRegion iomem;
70
#include "qemu/units.h"
79
- uint32_t readbuff;
71
#include "sysemu/blockdev.h"
80
- uint32_t flags;
72
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
81
- uint32_t lcr;
73
index XXXXXXX..XXXXXXX 100644
82
- uint32_t rsr;
74
--- a/hw/arm/sbsa-ref.c
83
- uint32_t cr;
75
+++ b/hw/arm/sbsa-ref.c
84
- uint32_t dmacr;
76
@@ -XXX,XX +XXX,XX @@
85
- uint32_t int_enabled;
77
*/
86
- uint32_t int_level;
78
87
- uint32_t read_fifo[16];
79
#include "qemu/osdep.h"
88
- uint32_t ilpr;
80
-#include "qemu-common.h"
89
- uint32_t ibrd;
81
#include "qemu/datadir.h"
90
- uint32_t fbrd;
82
#include "qapi/error.h"
91
- uint32_t ifl;
83
#include "qemu/error-report.h"
92
- int read_pos;
84
diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c
93
- int read_count;
85
index XXXXXXX..XXXXXXX 100644
94
- int read_trigger;
86
--- a/hw/arm/stm32f405_soc.c
95
- CharBackend chr;
87
+++ b/hw/arm/stm32f405_soc.c
96
- qemu_irq irq;
88
@@ -XXX,XX +XXX,XX @@
97
- const unsigned char *id;
89
98
-} PL011State;
90
#include "qemu/osdep.h"
99
-
91
#include "qapi/error.h"
100
#define PL011_INT_TX 0x20
92
-#include "qemu-common.h"
101
#define PL011_INT_RX 0x10
93
#include "exec/address-spaces.h"
102
94
#include "sysemu/sysemu.h"
103
@@ -XXX,XX +XXX,XX @@ static void pl011_luminary_init(Object *obj)
95
#include "hw/arm/stm32f405_soc.h"
104
}
96
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
105
97
index XXXXXXX..XXXXXXX 100644
106
static const TypeInfo pl011_luminary_info = {
98
--- a/hw/arm/vexpress.c
107
- .name = "pl011_luminary",
99
+++ b/hw/arm/vexpress.c
108
+ .name = TYPE_PL011_LUMINARY,
100
@@ -XXX,XX +XXX,XX @@
109
.parent = TYPE_PL011,
101
110
.instance_init = pl011_luminary_init,
102
#include "qemu/osdep.h"
111
};
103
#include "qapi/error.h"
104
-#include "qemu-common.h"
105
#include "qemu/datadir.h"
106
#include "cpu.h"
107
#include "hw/sysbus.h"
108
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/arm/virt.c
111
+++ b/hw/arm/virt.c
112
@@ -XXX,XX +XXX,XX @@
113
*/
114
115
#include "qemu/osdep.h"
116
-#include "qemu-common.h"
117
#include "qemu/datadir.h"
118
#include "qemu/units.h"
119
#include "qemu/option.h"
112
--
120
--
113
2.20.1
121
2.25.1
114
122
115
123
diff view generated by jsdifflib
1
The "background region" for a v8M MPU is a default which will be used
1
The calculation of the length of TLB range invalidate operations
2
(if enabled, and if the access is privileged) if the access does
2
in tlbi_aa64_range_get_length() is incorrect in two ways:
3
not match any specific MPU region. We were incorrectly using it
3
* the NUM field is 5 bits, but we read only 4 bits
4
always (by putting the condition at the wrong nesting level). This
4
* we miscalculate the page_shift value, because of an
5
meant that we would always return the default background permissions
5
off-by-one error:
6
rather than the correct permissions for a specific region, and also
6
TG 0b00 is invalid
7
that we would not return the right information in response to a
7
TG 0b01 is 4K granule size == 4096 == 2^12
8
TT instruction.
8
TG 0b10 is 16K granule size == 16384 == 2^14
9
TG 0b11 is 64K granule size == 65536 == 2^16
10
so page_shift should be (TG - 1) * 2 + 12
9
11
10
Move the check for the background region to the same place in the
12
Thanks to the bug report submitter Cha HyunSoo for identifying
11
logic as the equivalent v8M MPUCheck() pseudocode puts it.
13
both these errors.
12
This in turn means we must adjust the condition we use to detect
13
matches in multiple regions to avoid false-positives.
14
14
15
Fixes: 84940ed82552d3c ("target/arm: Add support for FEAT_TLBIRANGE")
16
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/734
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20190214113408.10214-1-peter.maydell@linaro.org
19
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20211130173257.1274194-1-peter.maydell@linaro.org
18
---
22
---
19
target/arm/helper.c | 8 +++++---
23
target/arm/helper.c | 6 +++---
20
1 file changed, 5 insertions(+), 3 deletions(-)
24
1 file changed, 3 insertions(+), 3 deletions(-)
21
25
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
diff --git a/target/arm/helper.c b/target/arm/helper.c
23
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper.c
28
--- a/target/arm/helper.c
25
+++ b/target/arm/helper.c
29
+++ b/target/arm/helper.c
26
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
30
@@ -XXX,XX +XXX,XX @@ static uint64_t tlbi_aa64_range_get_length(CPUARMState *env,
27
hit = true;
31
uint64_t exponent;
28
} else if (m_is_ppb_region(env, address)) {
32
uint64_t length;
29
hit = true;
33
30
- } else if (pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
34
- num = extract64(value, 39, 4);
31
- hit = true;
35
+ num = extract64(value, 39, 5);
32
} else {
36
scale = extract64(value, 44, 2);
33
+ if (pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
37
page_size_granule = extract64(value, 46, 2);
34
+ hit = true;
38
35
+ }
39
- page_shift = page_size_granule * 2 + 12;
40
-
41
if (page_size_granule == 0) {
42
qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
43
page_size_granule);
44
return 0;
45
}
46
47
+ page_shift = (page_size_granule - 1) * 2 + 12;
36
+
48
+
37
for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
49
exponent = (5 * scale) + 1;
38
/* region search */
50
length = (num + 1) << (exponent + page_shift);
39
/* Note that the base address is bits [31:5] from the register
51
40
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
41
*is_subpage = true;
42
}
43
44
- if (hit) {
45
+ if (matchregion != -1) {
46
/* Multiple regions match -- always a failure (unlike
47
* PMSAv7 where highest-numbered-region wins)
48
*/
49
--
52
--
50
2.20.1
53
2.25.1
51
54
52
55
diff view generated by jsdifflib
1
Wire up the two PL011 UARTs in the Musca board.
1
From: Patrick Venture <venture@google.com>
2
2
3
The rx_active boolean change to true should always trigger a try_read
4
call that flushes the queue.
5
6
Signed-off-by: Patrick Venture <venture@google.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20211203221002.1719306-1-venture@google.com
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
---
10
---
6
hw/arm/musca.c | 34 +++++++++++++++++++++++++++++-----
11
hw/net/npcm7xx_emc.c | 18 ++++++++----------
7
1 file changed, 29 insertions(+), 5 deletions(-)
12
1 file changed, 8 insertions(+), 10 deletions(-)
8
13
9
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
14
diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c
10
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
11
--- a/hw/arm/musca.c
16
--- a/hw/net/npcm7xx_emc.c
12
+++ b/hw/arm/musca.c
17
+++ b/hw/net/npcm7xx_emc.c
13
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void emc_halt_rx(NPCM7xxEMCState *emc, uint32_t mista_flag)
14
#include "qemu/error-report.h"
19
emc_set_mista(emc, mista_flag);
15
#include "qapi/error.h"
16
#include "exec/address-spaces.h"
17
+#include "sysemu/sysemu.h"
18
#include "hw/arm/arm.h"
19
#include "hw/arm/armsse.h"
20
#include "hw/boards.h"
21
+#include "hw/char/pl011.h"
22
#include "hw/core/split-irq.h"
23
#include "hw/misc/tz-mpc.h"
24
#include "hw/misc/tz-ppc.h"
25
@@ -XXX,XX +XXX,XX @@ typedef struct {
26
UnimplementedDeviceState mhu[2];
27
UnimplementedDeviceState pwm[3];
28
UnimplementedDeviceState i2s;
29
- UnimplementedDeviceState uart[2];
30
+ PL011State uart[2];
31
UnimplementedDeviceState i2c[2];
32
UnimplementedDeviceState spi;
33
UnimplementedDeviceState scc;
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_rtc(MuscaMachineState *mms, void *opaque,
35
return sysbus_mmio_get_region(SYS_BUS_DEVICE(rtc), 0);
36
}
20
}
37
21
38
+static MemoryRegion *make_uart(MuscaMachineState *mms, void *opaque,
22
+static void emc_enable_rx_and_flush(NPCM7xxEMCState *emc)
39
+ const char *name, hwaddr size)
40
+{
23
+{
41
+ PL011State *uart = opaque;
24
+ emc->rx_active = true;
42
+ int i = uart - &mms->uart[0];
25
+ qemu_flush_queued_packets(qemu_get_queue(emc->nic));
43
+ int irqbase = 7 + i * 6;
44
+ SysBusDevice *s;
45
+
46
+ sysbus_init_child_obj(OBJECT(mms), name, uart, sizeof(mms->uart[0]),
47
+ TYPE_PL011);
48
+ qdev_prop_set_chr(DEVICE(uart), "chardev", serial_hd(i));
49
+ object_property_set_bool(OBJECT(uart), true, "realized", &error_fatal);
50
+ s = SYS_BUS_DEVICE(uart);
51
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqbase + 5)); /* combined */
52
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqbase + 0)); /* RX */
53
+ sysbus_connect_irq(s, 2, get_sse_irq_in(mms, irqbase + 1)); /* TX */
54
+ sysbus_connect_irq(s, 3, get_sse_irq_in(mms, irqbase + 2)); /* RT */
55
+ sysbus_connect_irq(s, 4, get_sse_irq_in(mms, irqbase + 3)); /* MS */
56
+ sysbus_connect_irq(s, 5, get_sse_irq_in(mms, irqbase + 4)); /* E */
57
+ return sysbus_mmio_get_region(SYS_BUS_DEVICE(uart), 0);
58
+}
26
+}
59
+
27
+
60
static MemoryRegion *make_musca_a_devs(MuscaMachineState *mms, void *opaque,
28
static void emc_set_next_tx_descriptor(NPCM7xxEMCState *emc,
61
const char *name, hwaddr size)
29
const NPCM7xxEMCTxDesc *tx_desc,
30
uint32_t desc_addr)
31
@@ -XXX,XX +XXX,XX @@ static ssize_t emc_receive(NetClientState *nc, const uint8_t *buf, size_t len1)
32
return len;
33
}
34
35
-static void emc_try_receive_next_packet(NPCM7xxEMCState *emc)
36
-{
37
- if (emc_can_receive(qemu_get_queue(emc->nic))) {
38
- qemu_flush_queued_packets(qemu_get_queue(emc->nic));
39
- }
40
-}
41
-
42
static uint64_t npcm7xx_emc_read(void *opaque, hwaddr offset, unsigned size)
62
{
43
{
63
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_musca_a_devs(MuscaMachineState *mms, void *opaque,
44
NPCM7xxEMCState *emc = opaque;
64
MemoryRegion *container = &mms->container;
45
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset,
65
46
emc->regs[REG_MGSTA] |= REG_MGSTA_RXHA;
66
const PPCPortInfo devices[] = {
47
}
67
- { "uart0", make_unimp_dev, &mms->uart[0], 0x1000, 0x1000 },
48
if (value & REG_MCMDR_RXON) {
68
- { "uart1", make_unimp_dev, &mms->uart[1], 0x2000, 0x1000 },
49
- emc->rx_active = true;
69
+ { "uart0", make_uart, &mms->uart[0], 0x1000, 0x1000 },
50
+ emc_enable_rx_and_flush(emc);
70
+ { "uart1", make_uart, &mms->uart[1], 0x2000, 0x1000 },
51
} else {
71
{ "spi", make_unimp_dev, &mms->spi, 0x3000, 0x1000 },
52
emc_halt_rx(emc, 0);
72
{ "i2c0", make_unimp_dev, &mms->i2c[0], 0x4000, 0x1000 },
53
}
73
{ "i2c1", make_unimp_dev, &mms->i2c[1], 0x5000, 0x1000 },
54
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset,
74
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
55
break;
75
{ "pwm1", make_unimp_dev, &mms->pwm[1], 0x40102000, 0x1000 },
56
case REG_RSDR:
76
{ "pwm2", make_unimp_dev, &mms->pwm[2], 0x40103000, 0x1000 },
57
if (emc->regs[REG_MCMDR] & REG_MCMDR_RXON) {
77
{ "i2s", make_unimp_dev, &mms->i2s, 0x40104000, 0x1000 },
58
- emc->rx_active = true;
78
- { "uart0", make_unimp_dev, &mms->uart[0], 0x40105000, 0x1000 },
59
- emc_try_receive_next_packet(emc);
79
- { "uart1", make_unimp_dev, &mms->uart[1], 0x40106000, 0x1000 },
60
+ emc_enable_rx_and_flush(emc);
80
+ { "uart0", make_uart, &mms->uart[0], 0x40105000, 0x1000 },
61
}
81
+ { "uart1", make_uart, &mms->uart[1], 0x40106000, 0x1000 },
62
break;
82
{ "i2c0", make_unimp_dev, &mms->i2c[0], 0x40108000, 0x1000 },
63
case REG_MIIDA:
83
{ "i2c1", make_unimp_dev, &mms->i2c[1], 0x40109000, 0x1000 },
84
{ "spi", make_unimp_dev, &mms->spi, 0x4010a000, 0x1000 },
85
--
64
--
86
2.20.1
65
2.25.1
87
66
88
67
diff view generated by jsdifflib
New patch
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
1
2
3
When a virtio-iommu is instantiated, describe it using the ACPI VIOT
4
table.
5
6
Acked-by: Igor Mammedov <imammedo@redhat.com>
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
9
Message-id: 20211210170415.583179-2-jean-philippe@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/virt-acpi-build.c | 7 +++++++
13
hw/arm/Kconfig | 1 +
14
2 files changed, 8 insertions(+)
15
16
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/virt-acpi-build.c
19
+++ b/hw/arm/virt-acpi-build.c
20
@@ -XXX,XX +XXX,XX @@
21
#include "kvm_arm.h"
22
#include "migration/vmstate.h"
23
#include "hw/acpi/ghes.h"
24
+#include "hw/acpi/viot.h"
25
26
#define ARM_SPI_BASE 32
27
28
@@ -XXX,XX +XXX,XX @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
29
}
30
#endif
31
32
+ if (vms->iommu == VIRT_IOMMU_VIRTIO) {
33
+ acpi_add_table(table_offsets, tables_blob);
34
+ build_viot(ms, tables_blob, tables->linker, vms->virtio_iommu_bdf,
35
+ vms->oem_id, vms->oem_table_id);
36
+ }
37
+
38
/* XSDT is pointed to by RSDP */
39
xsdt = tables_blob->len;
40
build_xsdt(tables_blob, tables->linker, table_offsets, vms->oem_id,
41
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/Kconfig
44
+++ b/hw/arm/Kconfig
45
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
46
select DIMM
47
select ACPI_HW_REDUCED
48
select ACPI_APEI
49
+ select ACPI_VIOT
50
51
config CHEETAH
52
bool
53
--
54
2.25.1
55
56
diff view generated by jsdifflib
1
The Musca board puts its SRAM and flash behind TrustZone
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
Memory Protection Controllers (MPCs). Each MPC sits between
3
the CPU and the RAM/flash, and also has a set of memory mapped
4
control registers. Wire up the MPCs, and the memory behind them.
5
For the moment we implement the flash as simple ROM, which
6
cannot be reprogrammed by the guest.
7
2
3
virtio-iommu is now supported with ACPI VIOT as well as device tree.
4
Remove the restriction that prevents from instantiating a virtio-iommu
5
device under ACPI.
6
7
Acked-by: Igor Mammedov <imammedo@redhat.com>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
10
Message-id: 20211210170415.583179-3-jean-philippe@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
---
12
---
11
hw/arm/musca.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++---
13
hw/arm/virt.c | 10 ++--------
12
1 file changed, 147 insertions(+), 8 deletions(-)
14
hw/virtio/virtio-iommu-pci.c | 12 ++----------
15
2 files changed, 4 insertions(+), 18 deletions(-)
13
16
14
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/musca.c
19
--- a/hw/arm/virt.c
17
+++ b/hw/arm/musca.c
20
+++ b/hw/arm/virt.c
18
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
19
#include "hw/arm/armsse.h"
22
MachineClass *mc = MACHINE_GET_CLASS(machine);
20
#include "hw/boards.h"
23
21
#include "hw/core/split-irq.h"
24
if (device_is_dynamic_sysbus(mc, dev) ||
22
+#include "hw/misc/tz-mpc.h"
25
- (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM))) {
23
#include "hw/misc/tz-ppc.h"
26
+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
24
#include "hw/misc/unimp.h"
27
+ object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
25
28
return HOTPLUG_HANDLER(machine);
26
#define MUSCA_NUMIRQ_MAX 96
29
}
27
#define MUSCA_PPC_MAX 3
30
- if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
28
+#define MUSCA_MPC_MAX 5
31
- VirtMachineState *vms = VIRT_MACHINE(machine);
29
+
32
-
30
+typedef struct MPCInfo MPCInfo;
33
- if (!vms->bootinfo.firmware_loaded || !virt_is_acpi_enabled(vms)) {
31
34
- return HOTPLUG_HANDLER(machine);
32
typedef enum MuscaType {
35
- }
33
MUSCA_A,
36
- }
34
@@ -XXX,XX +XXX,XX @@ typedef struct {
37
return NULL;
35
uint32_t init_svtor;
36
int sram_addr_width;
37
int num_irqs;
38
+ const MPCInfo *mpc_info;
39
+ int num_mpcs;
40
} MuscaMachineClass;
41
42
typedef struct {
43
MachineState parent;
44
45
ARMSSE sse;
46
+ /* RAM and flash */
47
+ MemoryRegion ram[MUSCA_MPC_MAX];
48
SplitIRQ cpu_irq_splitter[MUSCA_NUMIRQ_MAX];
49
SplitIRQ sec_resp_splitter;
50
TZPPC ppc[MUSCA_PPC_MAX];
51
MemoryRegion container;
52
UnimplementedDeviceState eflash[2];
53
UnimplementedDeviceState qspi;
54
- UnimplementedDeviceState mpc[5];
55
+ TZMPC mpc[MUSCA_MPC_MAX];
56
UnimplementedDeviceState mhu[2];
57
UnimplementedDeviceState pwm[3];
58
UnimplementedDeviceState i2s;
59
@@ -XXX,XX +XXX,XX @@ typedef struct {
60
UnimplementedDeviceState pvt;
61
UnimplementedDeviceState sdio;
62
UnimplementedDeviceState gpio;
63
+ UnimplementedDeviceState cryptoisland;
64
} MuscaMachineState;
65
66
#define TYPE_MUSCA_MACHINE "musca"
67
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MuscaMachineState *mms,
68
return sysbus_mmio_get_region(SYS_BUS_DEVICE(uds), 0);
69
}
38
}
70
39
71
+typedef enum MPCInfoType {
40
diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c
72
+ MPC_RAM,
41
index XXXXXXX..XXXXXXX 100644
73
+ MPC_ROM,
42
--- a/hw/virtio/virtio-iommu-pci.c
74
+ MPC_CRYPTOISLAND,
43
+++ b/hw/virtio/virtio-iommu-pci.c
75
+} MPCInfoType;
44
@@ -XXX,XX +XXX,XX @@ static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
76
+
45
VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
77
+struct MPCInfo {
46
78
+ const char *name;
47
if (!qdev_get_machine_hotplug_handler(DEVICE(vpci_dev))) {
79
+ hwaddr addr;
48
- MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
80
+ hwaddr size;
49
-
81
+ MPCInfoType type;
50
- error_setg(errp,
82
+};
51
- "%s machine fails to create iommu-map device tree bindings",
83
+
52
- mc->name);
84
+/* Order of the MPCs here must match the order of the bits in SECMPCINTSTATUS */
53
- error_append_hint(errp,
85
+static const MPCInfo a_mpc_info[] = { {
54
- "Check your machine implements a hotplug handler "
86
+ .name = "qspi",
55
- "for the virtio-iommu-pci device\n");
87
+ .type = MPC_ROM,
56
- error_append_hint(errp, "Check the guest is booted without FW or with "
88
+ .addr = 0x00200000,
57
- "-no-acpi\n");
89
+ .size = 0x00800000,
58
+ error_setg(errp, "Check your machine implements a hotplug handler "
90
+ }, {
59
+ "for the virtio-iommu-pci device");
91
+ .name = "sram",
60
return;
92
+ .type = MPC_RAM,
61
}
93
+ .addr = 0x00000000,
62
for (int i = 0; i < s->nb_reserved_regions; i++) {
94
+ .size = 0x00200000,
95
+ }
96
+};
97
+
98
+static const MPCInfo b1_mpc_info[] = { {
99
+ .name = "qspi",
100
+ .type = MPC_ROM,
101
+ .addr = 0x00000000,
102
+ .size = 0x02000000,
103
+ }, {
104
+ .name = "sram",
105
+ .type = MPC_RAM,
106
+ .addr = 0x0a400000,
107
+ .size = 0x00080000,
108
+ }, {
109
+ .name = "eflash0",
110
+ .type = MPC_ROM,
111
+ .addr = 0x0a000000,
112
+ .size = 0x00200000,
113
+ }, {
114
+ .name = "eflash1",
115
+ .type = MPC_ROM,
116
+ .addr = 0x0a200000,
117
+ .size = 0x00200000,
118
+ }, {
119
+ .name = "cryptoisland",
120
+ .type = MPC_CRYPTOISLAND,
121
+ .addr = 0x0a000000,
122
+ .size = 0x00200000,
123
+ }
124
+};
125
+
126
+static MemoryRegion *make_mpc(MuscaMachineState *mms, void *opaque,
127
+ const char *name, hwaddr size)
128
+{
129
+ /*
130
+ * Create an MPC and the RAM or flash behind it.
131
+ * MPC 0: eFlash 0
132
+ * MPC 1: eFlash 1
133
+ * MPC 2: SRAM
134
+ * MPC 3: QSPI flash
135
+ * MPC 4: CryptoIsland
136
+ * For now we implement the flash regions as ROM (ie not programmable)
137
+ * (with their control interface memory regions being unimplemented
138
+ * stubs behind the PPCs).
139
+ * The whole CryptoIsland region behind its MPC is an unimplemented stub.
140
+ */
141
+ MuscaMachineClass *mmc = MUSCA_MACHINE_GET_CLASS(mms);
142
+ TZMPC *mpc = opaque;
143
+ int i = mpc - &mms->mpc[0];
144
+ MemoryRegion *downstream;
145
+ MemoryRegion *upstream;
146
+ UnimplementedDeviceState *uds;
147
+ char *mpcname;
148
+ const MPCInfo *mpcinfo = mmc->mpc_info;
149
+
150
+ mpcname = g_strdup_printf("%s-mpc", mpcinfo[i].name);
151
+
152
+ switch (mpcinfo[i].type) {
153
+ case MPC_ROM:
154
+ downstream = &mms->ram[i];
155
+ memory_region_init_rom(downstream, NULL, mpcinfo[i].name,
156
+ mpcinfo[i].size, &error_fatal);
157
+ break;
158
+ case MPC_RAM:
159
+ downstream = &mms->ram[i];
160
+ memory_region_init_ram(downstream, NULL, mpcinfo[i].name,
161
+ mpcinfo[i].size, &error_fatal);
162
+ break;
163
+ case MPC_CRYPTOISLAND:
164
+ /* We don't implement the CryptoIsland yet */
165
+ uds = &mms->cryptoisland;
166
+ sysbus_init_child_obj(OBJECT(mms), name, uds,
167
+ sizeof(UnimplementedDeviceState),
168
+ TYPE_UNIMPLEMENTED_DEVICE);
169
+ qdev_prop_set_string(DEVICE(uds), "name", mpcinfo[i].name);
170
+ qdev_prop_set_uint64(DEVICE(uds), "size", mpcinfo[i].size);
171
+ object_property_set_bool(OBJECT(uds), true, "realized", &error_fatal);
172
+ downstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(uds), 0);
173
+ break;
174
+ default:
175
+ g_assert_not_reached();
176
+ }
177
+
178
+ sysbus_init_child_obj(OBJECT(mms), mpcname, mpc, sizeof(mms->mpc[0]),
179
+ TYPE_TZ_MPC);
180
+ object_property_set_link(OBJECT(mpc), OBJECT(downstream),
181
+ "downstream", &error_fatal);
182
+ object_property_set_bool(OBJECT(mpc), true, "realized", &error_fatal);
183
+ /* Map the upstream end of the MPC into system memory */
184
+ upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 1);
185
+ memory_region_add_subregion(get_system_memory(), mpcinfo[i].addr, upstream);
186
+ /* and connect its interrupt to the SSE-200 */
187
+ qdev_connect_gpio_out_named(DEVICE(mpc), "irq", 0,
188
+ qdev_get_gpio_in_named(DEVICE(&mms->sse),
189
+ "mpcexp_status", i));
190
+
191
+ g_free(mpcname);
192
+ /* Return the register interface MR for our caller to map behind the PPC */
193
+ return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
194
+}
195
+
196
static MemoryRegion *make_musca_a_devs(MuscaMachineState *mms, void *opaque,
197
const char *name, hwaddr size)
198
{
199
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_musca_a_devs(MuscaMachineState *mms, void *opaque,
200
{ "pwm1", make_unimp_dev, &mms->pwm[1], 0xe000, 0x1000 },
201
{ "pwm2", make_unimp_dev, &mms->pwm[2], 0xf000, 0x1000 },
202
{ "gpio", make_unimp_dev, &mms->gpio, 0x10000, 0x1000 },
203
- { "mpc0", make_unimp_dev, &mms->mpc[0], 0x12000, 0x1000 },
204
- { "mpc1", make_unimp_dev, &mms->mpc[1], 0x13000, 0x1000 },
205
+ { "mpc0", make_mpc, &mms->mpc[0], 0x12000, 0x1000 },
206
+ { "mpc1", make_mpc, &mms->mpc[1], 0x13000, 0x1000 },
207
};
208
209
memory_region_init(container, OBJECT(mms), "musca-device-container", size);
210
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
211
int i;
212
213
assert(mmc->num_irqs <= MUSCA_NUMIRQ_MAX);
214
+ assert(mmc->num_mpcs <= MUSCA_MPC_MAX);
215
216
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
217
error_report("This board can only be used with CPU %s",
218
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
219
{ "eflash1", make_unimp_dev, &mms->eflash[1],
220
0x52500000, 0x1000 },
221
{ "qspi", make_unimp_dev, &mms->qspi, 0x42800000, 0x100000 },
222
- { "mpc0", make_unimp_dev, &mms->mpc[0], 0x52000000, 0x1000 },
223
- { "mpc1", make_unimp_dev, &mms->mpc[1], 0x52100000, 0x1000 },
224
- { "mpc2", make_unimp_dev, &mms->mpc[2], 0x52200000, 0x1000 },
225
- { "mpc3", make_unimp_dev, &mms->mpc[3], 0x52300000, 0x1000 },
226
+ { "mpc0", make_mpc, &mms->mpc[0], 0x52000000, 0x1000 },
227
+ { "mpc1", make_mpc, &mms->mpc[1], 0x52100000, 0x1000 },
228
+ { "mpc2", make_mpc, &mms->mpc[2], 0x52200000, 0x1000 },
229
+ { "mpc3", make_mpc, &mms->mpc[3], 0x52300000, 0x1000 },
230
{ "mhu0", make_unimp_dev, &mms->mhu[0], 0x42600000, 0x100000 },
231
{ "mhu1", make_unimp_dev, &mms->mhu[1], 0x42700000, 0x100000 },
232
{ }, /* port 9: unused */
233
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
234
{ }, /* port 11: unused */
235
{ }, /* port 12: unused */
236
{ }, /* port 13: unused */
237
- { "mpc4", make_unimp_dev, &mms->mpc[4], 0x52e00000, 0x1000 },
238
+ { "mpc4", make_mpc, &mms->mpc[4], 0x52e00000, 0x1000 },
239
},
240
}, {
241
.name = "apb_ppcexp1",
242
@@ -XXX,XX +XXX,XX @@ static void musca_a_class_init(ObjectClass *oc, void *data)
243
mmc->init_svtor = 0x10200000;
244
mmc->sram_addr_width = 15;
245
mmc->num_irqs = 64;
246
+ mmc->mpc_info = a_mpc_info;
247
+ mmc->num_mpcs = ARRAY_SIZE(a_mpc_info);
248
}
249
250
static void musca_b1_class_init(ObjectClass *oc, void *data)
251
@@ -XXX,XX +XXX,XX @@ static void musca_b1_class_init(ObjectClass *oc, void *data)
252
mmc->init_svtor = 0x10000000;
253
mmc->sram_addr_width = 17;
254
mmc->num_irqs = 96;
255
+ mmc->mpc_info = b1_mpc_info;
256
+ mmc->num_mpcs = ARRAY_SIZE(b1_mpc_info);
257
}
258
259
static const TypeInfo musca_info = {
260
--
63
--
261
2.20.1
64
2.25.1
262
65
263
66
diff view generated by jsdifflib
New patch
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
1
2
3
We do not support instantiating multiple IOMMUs. Before adding a
4
virtio-iommu, check that no other IOMMU is present. This will detect
5
both "iommu=smmuv3" machine parameter and another virtio-iommu instance.
6
7
Fixes: 70e89132c9 ("hw/arm/virt: Add the virtio-iommu device tree mappings")
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
11
Message-id: 20211210170415.583179-4-jean-philippe@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/arm/virt.c | 5 +++++
15
1 file changed, 5 insertions(+)
16
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/virt.c
20
+++ b/hw/arm/virt.c
21
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
22
hwaddr db_start = 0, db_end = 0;
23
char *resv_prop_str;
24
25
+ if (vms->iommu != VIRT_IOMMU_NONE) {
26
+ error_setg(errp, "virt machine does not support multiple IOMMUs");
27
+ return;
28
+ }
29
+
30
switch (vms->msi_controller) {
31
case VIRT_MSI_CTRL_NONE:
32
return;
33
--
34
2.25.1
35
36
diff view generated by jsdifflib
1
The pl011 logs when the guest makes a bad access. It prints
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
the address offset in hex but confusingly omits the '0x'
3
prefix; add it.
4
2
3
To propagate errors to the caller of the pre_plug callback, use the
4
object_poperty_set*() functions directly instead of the qdev_prop_set*()
5
helpers.
6
7
Suggested-by: Igor Mammedov <imammedo@redhat.com>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
11
Message-id: 20211210170415.583179-5-jean-philippe@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
---
13
---
9
hw/char/pl011.c | 4 ++--
14
hw/arm/virt.c | 5 +++--
10
1 file changed, 2 insertions(+), 2 deletions(-)
15
1 file changed, 3 insertions(+), 2 deletions(-)
11
16
12
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/char/pl011.c
19
--- a/hw/arm/virt.c
15
+++ b/hw/char/pl011.c
20
+++ b/hw/arm/virt.c
16
@@ -XXX,XX +XXX,XX @@ static uint64_t pl011_read(void *opaque, hwaddr offset,
21
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
17
break;
22
db_start, db_end,
18
default:
23
VIRTIO_IOMMU_RESV_MEM_T_MSI);
19
qemu_log_mask(LOG_GUEST_ERROR,
24
20
- "pl011_read: Bad offset %x\n", (int)offset);
25
- qdev_prop_set_uint32(dev, "len-reserved-regions", 1);
21
+ "pl011_read: Bad offset 0x%x\n", (int)offset);
26
- qdev_prop_set_string(dev, "reserved-regions[0]", resv_prop_str);
22
r = 0;
27
+ object_property_set_uint(OBJECT(dev), "len-reserved-regions", 1, errp);
23
break;
28
+ object_property_set_str(OBJECT(dev), "reserved-regions[0]",
24
}
29
+ resv_prop_str, errp);
25
@@ -XXX,XX +XXX,XX @@ static void pl011_write(void *opaque, hwaddr offset,
30
g_free(resv_prop_str);
26
break;
27
default:
28
qemu_log_mask(LOG_GUEST_ERROR,
29
- "pl011_write: Bad offset %x\n", (int)offset);
30
+ "pl011_write: Bad offset 0x%x\n", (int)offset);
31
}
31
}
32
}
32
}
33
34
--
33
--
35
2.20.1
34
2.25.1
36
35
37
36
diff view generated by jsdifflib
New patch
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
1
2
3
Create empty data files and allow updates for the upcoming VIOT tests.
4
5
Acked-by: Igor Mammedov <imammedo@redhat.com>
6
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
8
Message-id: 20211210170415.583179-6-jean-philippe@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
12
tests/data/acpi/q35/DSDT.viot | 0
13
tests/data/acpi/q35/VIOT.viot | 0
14
tests/data/acpi/virt/VIOT | 0
15
4 files changed, 3 insertions(+)
16
create mode 100644 tests/data/acpi/q35/DSDT.viot
17
create mode 100644 tests/data/acpi/q35/VIOT.viot
18
create mode 100644 tests/data/acpi/virt/VIOT
19
20
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/tests/qtest/bios-tables-test-allowed-diff.h
23
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
24
@@ -1 +1,4 @@
25
/* List of comma-separated changed AML files to ignore */
26
+"tests/data/acpi/virt/VIOT",
27
+"tests/data/acpi/q35/DSDT.viot",
28
+"tests/data/acpi/q35/VIOT.viot",
29
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
30
new file mode 100644
31
index XXXXXXX..XXXXXXX
32
diff --git a/tests/data/acpi/q35/VIOT.viot b/tests/data/acpi/q35/VIOT.viot
33
new file mode 100644
34
index XXXXXXX..XXXXXXX
35
diff --git a/tests/data/acpi/virt/VIOT b/tests/data/acpi/virt/VIOT
36
new file mode 100644
37
index XXXXXXX..XXXXXXX
38
--
39
2.25.1
40
41
diff view generated by jsdifflib
1
Wire up the PL031 RTC for the Musca board.
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
Add two test cases for VIOT, one on the q35 machine and the other on
4
virt. To test complex topologies the q35 test has two PCIe buses that
5
bypass the IOMMU (and are therefore not described by VIOT), and two
6
buses that are translated by virtio-iommu.
7
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
11
Message-id: 20211210170415.583179-7-jean-philippe@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
---
13
---
6
hw/arm/musca.c | 26 +++++++++++++++++++++++---
14
tests/qtest/bios-tables-test.c | 38 ++++++++++++++++++++++++++++++++++
7
1 file changed, 23 insertions(+), 3 deletions(-)
15
1 file changed, 38 insertions(+)
8
16
9
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
17
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
10
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
11
--- a/hw/arm/musca.c
19
--- a/tests/qtest/bios-tables-test.c
12
+++ b/hw/arm/musca.c
20
+++ b/tests/qtest/bios-tables-test.c
13
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void test_acpi_virt_tcg(void)
14
#include "hw/misc/tz-mpc.h"
22
free_test_data(&data);
15
#include "hw/misc/tz-ppc.h"
23
}
16
#include "hw/misc/unimp.h"
24
17
+#include "hw/timer/pl031.h"
25
+static void test_acpi_q35_viot(void)
18
19
#define MUSCA_NUMIRQ_MAX 96
20
#define MUSCA_PPC_MAX 3
21
@@ -XXX,XX +XXX,XX @@ typedef struct {
22
UnimplementedDeviceState spi;
23
UnimplementedDeviceState scc;
24
UnimplementedDeviceState timer;
25
- UnimplementedDeviceState rtc;
26
+ PL031State rtc;
27
UnimplementedDeviceState pvt;
28
UnimplementedDeviceState sdio;
29
UnimplementedDeviceState gpio;
30
@@ -XXX,XX +XXX,XX @@ typedef struct {
31
*/
32
#define SYSCLK_FRQ 40000000
33
34
+static qemu_irq get_sse_irq_in(MuscaMachineState *mms, int irqno)
35
+{
26
+{
36
+ /* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
27
+ test_data data = {
37
+ assert(irqno < MUSCA_NUMIRQ_MAX);
28
+ .machine = MACHINE_Q35,
29
+ .variant = ".viot",
30
+ };
38
+
31
+
39
+ return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
32
+ /*
33
+ * To keep things interesting, two buses bypass the IOMMU.
34
+ * VIOT should only describes the other two buses.
35
+ */
36
+ test_acpi_one("-machine default_bus_bypass_iommu=on "
37
+ "-device virtio-iommu-pci "
38
+ "-device pxb-pcie,bus_nr=0x10,id=pcie.100,bus=pcie.0 "
39
+ "-device pxb-pcie,bus_nr=0x20,id=pcie.200,bus=pcie.0,bypass_iommu=on "
40
+ "-device pxb-pcie,bus_nr=0x30,id=pcie.300,bus=pcie.0",
41
+ &data);
42
+ free_test_data(&data);
40
+}
43
+}
41
+
44
+
42
/*
45
+static void test_acpi_virt_viot(void)
43
* Most of the devices in the Musca board sit behind Peripheral Protection
44
* Controllers. These data structures define the layout of which devices
45
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MuscaMachineState *mms, void *opaque,
46
return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
47
}
48
49
+static MemoryRegion *make_rtc(MuscaMachineState *mms, void *opaque,
50
+ const char *name, hwaddr size)
51
+{
46
+{
52
+ PL031State *rtc = opaque;
47
+ test_data data = {
48
+ .machine = "virt",
49
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
50
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
51
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
52
+ .ram_start = 0x40000000ULL,
53
+ .scan_len = 128ULL * 1024 * 1024,
54
+ };
53
+
55
+
54
+ sysbus_init_child_obj(OBJECT(mms), name, rtc, sizeof(mms->rtc), TYPE_PL031);
56
+ test_acpi_one("-cpu cortex-a57 "
55
+ object_property_set_bool(OBJECT(rtc), true, "realized", &error_fatal);
57
+ "-device virtio-iommu-pci", &data);
56
+ sysbus_connect_irq(SYS_BUS_DEVICE(rtc), 0, get_sse_irq_in(mms, 39));
58
+ free_test_data(&data);
57
+ return sysbus_mmio_get_region(SYS_BUS_DEVICE(rtc), 0);
58
+}
59
+}
59
+
60
+
60
static MemoryRegion *make_musca_a_devs(MuscaMachineState *mms, void *opaque,
61
static void test_oem_fields(test_data *data)
61
const char *name, hwaddr size)
62
{
62
{
63
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_musca_a_devs(MuscaMachineState *mms, void *opaque,
63
int i;
64
{ "i2c1", make_unimp_dev, &mms->i2c[1], 0x5000, 0x1000 },
64
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
65
{ "i2s", make_unimp_dev, &mms->i2s, 0x6000, 0x1000 },
65
qtest_add_func("acpi/q35/kvm/xapic", test_acpi_q35_kvm_xapic);
66
{ "pwm0", make_unimp_dev, &mms->pwm[0], 0x7000, 0x1000 },
66
qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar);
67
- { "rtc", make_unimp_dev, &mms->rtc, 0x8000, 0x1000 },
67
}
68
+ { "rtc", make_rtc, &mms->rtc, 0x8000, 0x1000 },
68
+ qtest_add_func("acpi/q35/viot", test_acpi_q35_viot);
69
{ "qspi", make_unimp_dev, &mms->qspi, 0xa000, 0x1000 },
69
} else if (strcmp(arch, "aarch64") == 0) {
70
{ "timer", make_unimp_dev, &mms->timer, 0xb000, 0x1000 },
70
if (has_tcg) {
71
{ "scc", make_unimp_dev, &mms->scc, 0xc000, 0x1000 },
71
qtest_add_func("acpi/virt", test_acpi_virt_tcg);
72
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
72
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
73
{ "spi", make_unimp_dev, &mms->spi, 0x4010a000, 0x1000 },
73
qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp);
74
{ "scc", make_unimp_dev, &mms->scc, 0x5010b000, 0x1000 },
74
qtest_add_func("acpi/virt/pxb", test_acpi_virt_tcg_pxb);
75
{ "timer", make_unimp_dev, &mms->timer, 0x4010c000, 0x1000 },
75
qtest_add_func("acpi/virt/oem-fields", test_acpi_oem_fields_virt);
76
- { "rtc", make_unimp_dev, &mms->rtc, 0x4010d000, 0x1000 },
76
+ qtest_add_func("acpi/virt/viot", test_acpi_virt_viot);
77
+ { "rtc", make_rtc, &mms->rtc, 0x4010d000, 0x1000 },
77
}
78
{ "pvt", make_unimp_dev, &mms->pvt, 0x4010e000, 0x1000 },
78
}
79
{ "sdio", make_unimp_dev, &mms->sdio, 0x4010f000, 0x1000 },
79
ret = g_test_run();
80
},
81
--
80
--
82
2.20.1
81
2.25.1
83
82
84
83
diff view generated by jsdifflib
New patch
1
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
3
Add expected blobs of the VIOT and DSDT table for the VIOT test on the
4
q35 machine.
5
6
Since the test instantiates a virtio device and two PCIe expander
7
bridges, DSDT.viot has more blocks than the base DSDT.
8
9
The VIOT table generated for the q35 test is:
10
11
[000h 0000 4] Signature : "VIOT" [Virtual I/O Translation Table]
12
[004h 0004 4] Table Length : 00000070
13
[008h 0008 1] Revision : 00
14
[009h 0009 1] Checksum : 3D
15
[00Ah 0010 6] Oem ID : "BOCHS "
16
[010h 0016 8] Oem Table ID : "BXPC "
17
[018h 0024 4] Oem Revision : 00000001
18
[01Ch 0028 4] Asl Compiler ID : "BXPC"
19
[020h 0032 4] Asl Compiler Revision : 00000001
20
21
[024h 0036 2] Node count : 0003
22
[026h 0038 2] Node offset : 0030
23
[028h 0040 8] Reserved : 0000000000000000
24
25
[030h 0048 1] Type : 03 [VirtIO-PCI IOMMU]
26
[031h 0049 1] Reserved : 00
27
[032h 0050 2] Length : 0010
28
29
[034h 0052 2] PCI Segment : 0000
30
[036h 0054 2] PCI BDF number : 0010
31
[038h 0056 8] Reserved : 0000000000000000
32
33
[040h 0064 1] Type : 01 [PCI Range]
34
[041h 0065 1] Reserved : 00
35
[042h 0066 2] Length : 0018
36
37
[044h 0068 4] Endpoint start : 00003000
38
[048h 0072 2] PCI Segment start : 0000
39
[04Ah 0074 2] PCI Segment end : 0000
40
[04Ch 0076 2] PCI BDF start : 3000
41
[04Eh 0078 2] PCI BDF end : 30FF
42
[050h 0080 2] Output node : 0030
43
[052h 0082 6] Reserved : 000000000000
44
45
[058h 0088 1] Type : 01 [PCI Range]
46
[059h 0089 1] Reserved : 00
47
[05Ah 0090 2] Length : 0018
48
49
[05Ch 0092 4] Endpoint start : 00001000
50
[060h 0096 2] PCI Segment start : 0000
51
[062h 0098 2] PCI Segment end : 0000
52
[064h 0100 2] PCI BDF start : 1000
53
[066h 0102 2] PCI BDF end : 10FF
54
[068h 0104 2] Output node : 0030
55
[06Ah 0106 6] Reserved : 000000000000
56
57
And the DSDT diff is:
58
59
@@ -XXX,XX +XXX,XX @@
60
*
61
* Disassembling to symbolic ASL+ operators
62
*
63
- * Disassembly of tests/data/acpi/q35/DSDT, Fri Dec 10 15:03:08 2021
64
+ * Disassembly of /tmp/aml-H9Y5D1, Fri Dec 10 15:02:27 2021
65
*
66
* Original Table Header:
67
* Signature "DSDT"
68
- * Length 0x00002061 (8289)
69
+ * Length 0x000024B6 (9398)
70
* Revision 0x01 **** 32-bit table (V1), no 64-bit math support
71
- * Checksum 0xFA
72
+ * Checksum 0xA7
73
* OEM ID "BOCHS "
74
* OEM Table ID "BXPC "
75
* OEM Revision 0x00000001 (1)
76
@@ -XXX,XX +XXX,XX @@
77
}
78
}
79
80
+ Scope (\_SB)
81
+ {
82
+ Device (PC30)
83
+ {
84
+ Name (_UID, 0x30) // _UID: Unique ID
85
+ Name (_BBN, 0x30) // _BBN: BIOS Bus Number
86
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
87
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
88
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
89
+ {
90
+ CreateDWordField (Arg3, Zero, CDW1)
91
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
92
+ {
93
+ CreateDWordField (Arg3, 0x04, CDW2)
94
+ CreateDWordField (Arg3, 0x08, CDW3)
95
+ Local0 = CDW3 /* \_SB_.PC30._OSC.CDW3 */
96
+ Local0 &= 0x1F
97
+ If ((Arg1 != One))
98
+ {
99
+ CDW1 |= 0x08
100
+ }
101
+
102
+ If ((CDW3 != Local0))
103
+ {
104
+ CDW1 |= 0x10
105
+ }
106
+
107
+ CDW3 = Local0
108
+ }
109
+ Else
110
+ {
111
+ CDW1 |= 0x04
112
+ }
113
+
114
+ Return (Arg3)
115
+ }
116
+
117
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
118
+ {
119
+ Local0 = Package (0x80){}
120
+ Local1 = Zero
121
+ While ((Local1 < 0x80))
122
+ {
123
+ Local2 = (Local1 >> 0x02)
124
+ Local3 = ((Local1 + Local2) & 0x03)
125
+ If ((Local3 == Zero))
126
+ {
127
+ Local4 = Package (0x04)
128
+ {
129
+ Zero,
130
+ Zero,
131
+ LNKD,
132
+ Zero
133
+ }
134
+ }
135
+
136
+ If ((Local3 == One))
137
+ {
138
+ Local4 = Package (0x04)
139
+ {
140
+ Zero,
141
+ Zero,
142
+ LNKA,
143
+ Zero
144
+ }
145
+ }
146
+
147
+ If ((Local3 == 0x02))
148
+ {
149
+ Local4 = Package (0x04)
150
+ {
151
+ Zero,
152
+ Zero,
153
+ LNKB,
154
+ Zero
155
+ }
156
+ }
157
+
158
+ If ((Local3 == 0x03))
159
+ {
160
+ Local4 = Package (0x04)
161
+ {
162
+ Zero,
163
+ Zero,
164
+ LNKC,
165
+ Zero
166
+ }
167
+ }
168
+
169
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
170
+ Local4 [One] = (Local1 & 0x03)
171
+ Local0 [Local1] = Local4
172
+ Local1++
173
+ }
174
+
175
+ Return (Local0)
176
+ }
177
+
178
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
179
+ {
180
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
181
+ 0x0000, // Granularity
182
+ 0x0030, // Range Minimum
183
+ 0x0030, // Range Maximum
184
+ 0x0000, // Translation Offset
185
+ 0x0001, // Length
186
+ ,, )
187
+ })
188
+ }
189
+ }
190
+
191
+ Scope (\_SB)
192
+ {
193
+ Device (PC20)
194
+ {
195
+ Name (_UID, 0x20) // _UID: Unique ID
196
+ Name (_BBN, 0x20) // _BBN: BIOS Bus Number
197
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
198
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
199
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
200
+ {
201
+ CreateDWordField (Arg3, Zero, CDW1)
202
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
203
+ {
204
+ CreateDWordField (Arg3, 0x04, CDW2)
205
+ CreateDWordField (Arg3, 0x08, CDW3)
206
+ Local0 = CDW3 /* \_SB_.PC20._OSC.CDW3 */
207
+ Local0 &= 0x1F
208
+ If ((Arg1 != One))
209
+ {
210
+ CDW1 |= 0x08
211
+ }
212
+
213
+ If ((CDW3 != Local0))
214
+ {
215
+ CDW1 |= 0x10
216
+ }
217
+
218
+ CDW3 = Local0
219
+ }
220
+ Else
221
+ {
222
+ CDW1 |= 0x04
223
+ }
224
+
225
+ Return (Arg3)
226
+ }
227
+
228
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
229
+ {
230
+ Local0 = Package (0x80){}
231
+ Local1 = Zero
232
+ While ((Local1 < 0x80))
233
+ {
234
+ Local2 = (Local1 >> 0x02)
235
+ Local3 = ((Local1 + Local2) & 0x03)
236
+ If ((Local3 == Zero))
237
+ {
238
+ Local4 = Package (0x04)
239
+ {
240
+ Zero,
241
+ Zero,
242
+ LNKD,
243
+ Zero
244
+ }
245
+ }
246
+
247
+ If ((Local3 == One))
248
+ {
249
+ Local4 = Package (0x04)
250
+ {
251
+ Zero,
252
+ Zero,
253
+ LNKA,
254
+ Zero
255
+ }
256
+ }
257
+
258
+ If ((Local3 == 0x02))
259
+ {
260
+ Local4 = Package (0x04)
261
+ {
262
+ Zero,
263
+ Zero,
264
+ LNKB,
265
+ Zero
266
+ }
267
+ }
268
+
269
+ If ((Local3 == 0x03))
270
+ {
271
+ Local4 = Package (0x04)
272
+ {
273
+ Zero,
274
+ Zero,
275
+ LNKC,
276
+ Zero
277
+ }
278
+ }
279
+
280
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
281
+ Local4 [One] = (Local1 & 0x03)
282
+ Local0 [Local1] = Local4
283
+ Local1++
284
+ }
285
+
286
+ Return (Local0)
287
+ }
288
+
289
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
290
+ {
291
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
292
+ 0x0000, // Granularity
293
+ 0x0020, // Range Minimum
294
+ 0x0020, // Range Maximum
295
+ 0x0000, // Translation Offset
296
+ 0x0001, // Length
297
+ ,, )
298
+ })
299
+ }
300
+ }
301
+
302
+ Scope (\_SB)
303
+ {
304
+ Device (PC10)
305
+ {
306
+ Name (_UID, 0x10) // _UID: Unique ID
307
+ Name (_BBN, 0x10) // _BBN: BIOS Bus Number
308
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
309
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
310
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
311
+ {
312
+ CreateDWordField (Arg3, Zero, CDW1)
313
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
314
+ {
315
+ CreateDWordField (Arg3, 0x04, CDW2)
316
+ CreateDWordField (Arg3, 0x08, CDW3)
317
+ Local0 = CDW3 /* \_SB_.PC10._OSC.CDW3 */
318
+ Local0 &= 0x1F
319
+ If ((Arg1 != One))
320
+ {
321
+ CDW1 |= 0x08
322
+ }
323
+
324
+ If ((CDW3 != Local0))
325
+ {
326
+ CDW1 |= 0x10
327
+ }
328
+
329
+ CDW3 = Local0
330
+ }
331
+ Else
332
+ {
333
+ CDW1 |= 0x04
334
+ }
335
+
336
+ Return (Arg3)
337
+ }
338
+
339
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
340
+ {
341
+ Local0 = Package (0x80){}
342
+ Local1 = Zero
343
+ While ((Local1 < 0x80))
344
+ {
345
+ Local2 = (Local1 >> 0x02)
346
+ Local3 = ((Local1 + Local2) & 0x03)
347
+ If ((Local3 == Zero))
348
+ {
349
+ Local4 = Package (0x04)
350
+ {
351
+ Zero,
352
+ Zero,
353
+ LNKD,
354
+ Zero
355
+ }
356
+ }
357
+
358
+ If ((Local3 == One))
359
+ {
360
+ Local4 = Package (0x04)
361
+ {
362
+ Zero,
363
+ Zero,
364
+ LNKA,
365
+ Zero
366
+ }
367
+ }
368
+
369
+ If ((Local3 == 0x02))
370
+ {
371
+ Local4 = Package (0x04)
372
+ {
373
+ Zero,
374
+ Zero,
375
+ LNKB,
376
+ Zero
377
+ }
378
+ }
379
+
380
+ If ((Local3 == 0x03))
381
+ {
382
+ Local4 = Package (0x04)
383
+ {
384
+ Zero,
385
+ Zero,
386
+ LNKC,
387
+ Zero
388
+ }
389
+ }
390
+
391
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
392
+ Local4 [One] = (Local1 & 0x03)
393
+ Local0 [Local1] = Local4
394
+ Local1++
395
+ }
396
+
397
+ Return (Local0)
398
+ }
399
+
400
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
401
+ {
402
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
403
+ 0x0000, // Granularity
404
+ 0x0010, // Range Minimum
405
+ 0x0010, // Range Maximum
406
+ 0x0000, // Translation Offset
407
+ 0x0001, // Length
408
+ ,, )
409
+ })
410
+ }
411
+ }
412
+
413
Scope (\_SB.PCI0)
414
{
415
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
416
@@ -XXX,XX +XXX,XX @@
417
WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
418
0x0000, // Granularity
419
0x0000, // Range Minimum
420
- 0x00FF, // Range Maximum
421
+ 0x000F, // Range Maximum
422
0x0000, // Translation Offset
423
- 0x0100, // Length
424
+ 0x0010, // Length
425
,, )
426
IO (Decode16,
427
0x0CF8, // Range Minimum
428
@@ -XXX,XX +XXX,XX @@
429
}
430
}
431
432
+ Device (S10)
433
+ {
434
+ Name (_ADR, 0x00020000) // _ADR: Address
435
+ }
436
+
437
+ Device (S18)
438
+ {
439
+ Name (_ADR, 0x00030000) // _ADR: Address
440
+ }
441
+
442
+ Device (S20)
443
+ {
444
+ Name (_ADR, 0x00040000) // _ADR: Address
445
+ }
446
+
447
+ Device (S28)
448
+ {
449
+ Name (_ADR, 0x00050000) // _ADR: Address
450
+ }
451
+
452
Method (PCNT, 0, NotSerialized)
453
{
454
}
455
456
Reviewed-by: Eric Auger <eric.auger@redhat.com>
457
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
458
Message-id: 20211210170415.583179-8-jean-philippe@linaro.org
459
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
460
---
461
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
462
tests/data/acpi/q35/DSDT.viot | Bin 0 -> 9398 bytes
463
tests/data/acpi/q35/VIOT.viot | Bin 0 -> 112 bytes
464
3 files changed, 2 deletions(-)
465
466
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
467
index XXXXXXX..XXXXXXX 100644
468
--- a/tests/qtest/bios-tables-test-allowed-diff.h
469
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
470
@@ -XXX,XX +XXX,XX @@
471
/* List of comma-separated changed AML files to ignore */
472
"tests/data/acpi/virt/VIOT",
473
-"tests/data/acpi/q35/DSDT.viot",
474
-"tests/data/acpi/q35/VIOT.viot",
475
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
476
index XXXXXXX..XXXXXXX 100644
477
GIT binary patch
478
literal 9398
479
zcmeHNO>7&-8J*>iv|O&FB}G~Oi$yp||57BBoWHhc5OS9yDTx$CQgH$r;8Idr*-4Q_
480
z5(9Az1F`}niVsB-)<KW7p`g9Br(A2Gm-gmc1N78GFS!;)e2V(MnH_0{q<{#yMgn&C
481
zn|*J-d9yqFhO_H6z19~`FlPL*u<DkZ*}|)JH;X@mF-FI<cPg<fti9tEN*yB^i5czN
482
zNq&q?!OZ;BE3B7{KWzJ-`Tn~f`9?Qj8~2^N8{Oc8J%57{==w%rS#;nOCp*nTr@iZ1
483
zb+?i;JLQUJ=O0?8*>S~D)a>NF1~WVB6^~_B#yhJ`H+JU@=6aXs`?Yv)J2h=N?drcS
484
zeLZ*n<<Bm^n}6`jfBx#u8&(W}1?)}iF9o#mZ~E2+zwdn7yK3AbIzKnxpZ>JRPm3~#
485
z&ICS{+_OayRW-l=Mtk=~uaS3o8z<_udd|(wqg`&JnVPfCe>BUOO`Su3e>pff_^UW%
486
z&JE^NO`)=Amg~iqRB1pPscP?(>#ZuY8GHCmlEvD$9g3%4Db~Dfz2SATnddvrR-Oe^
487
z;s;dJec!hnzi)ri^I6YN9vtkm{^TdUF8h7gX8-<Qe4p)GQ=)AtYx2VcwdLVAEXEjG
488
z^Mj|UHPqkj-LsWuzQem1>F3atdZn=zv3$#RmZzSHN+6-yyU#8cJb=YDilX&sl}vNm
489
znkgAR^O<3kj4if>{ly5fwRfMWuC5=lrlvKPX~i#654Cp}R_d*JS$9laZ$ra6)<ns8
490
zFZy28G%xP(nit&F>LDi%G<tIc=TY=gl$jSD&Uv!Yat~XR46h%rI$!}a%!|xG7u8Zn
491
zeY8_|n=K>xz_v_W8VX$W-Fg-qFWcT}7MCyz{%%{ia7hZ>Law-k6NOr}VI&_48U=2l
492
zwqDKFE8eTwwozDdms#e?x?5a|v>&JF;2_v0L~z5n%BYU^52<*cWuD4|GYUm@1+?))
493
zte^45>Rz)t*<T5V#={r>@t@{%?^i#W{i=HAZ*Dc9y59Va-+#P!jrGs;u38a{fLr`N
494
zvT@rUu>DljxJ?^&Z?-?vyJn3C>3D=qux{Y*bs5|5n)Qmi$TD^Zdn4GU$ocJS2Hh-<
495
z`xPI^^+v0nUVdjMos8k`WGl7hA`{03ju%<lrgAHSpd^DRf-*}_#Ly0mB!LSfVgWcQ
496
z&T$@~G9)JI=hz5m0vkrel+Xy{Oh7pkAu-V!j*W7rY(bO}Q$nMH2`FbGB&N)QaV4<4
497
zo)~9JXiP9=;}NPl<C@MmXG&;XFlFNrsyfFsonxFSp<}vEgsRSQP3O3#b6nSnP}ON_
498
zI!#Tdsp~|j>ckUB>FI=~GokB5sOq#dotCE4(sd$KbtW~PNlj-`*NIToiD#j5J#9^=
499
zt?NXn>YUJYPG~wObe#xQos*i*NloXZt`niEb4t@WrRki~bs|)CI+{*L)9L6s5vn><
500
zn$DD_Go|Z9sOn5>I@6lYw5}7Os&iV?Ij!lO)^#FOb!If38BJ$K*NIToIiu;E(R9w}
501
zIuWWmPiZ<&X*y5oIuWWmF_XaEC!a&Jn$B5WCqh-{X-(&8P3LJ{Cqh-{8P3dyPr@^t
502
zSqL9?X9Uwd3W@23*s~h*tj0X6GZCuHa~kuU#yqDp5vt7d8uPryJg+kms?5hU=3^T3
503
zF`bD}WnSP+=`t5MQ$FJ_2&Q~+BP6E0f^%BVIW6a$o)e+SX~IDBih-7z6{O~7YTy`&
504
zLjy&Cv?7QikV#>n0>>@MV8oK`Gmun34-FKdlm-J8SZSaNlnhir4-FI{S|bfqV8e)V
505
zss<{chX#reE#g=hsKAC%sF6d-Km}BWs!kZFsFpKfpbC@>6rprQGEjt4Ck#|zITHq|
506
zK*>M_l;<P^MJRQ`Kn0dFVW0|>3{*fllMEE0)CmI>Sk8ojDo`>|0p(0GP=xY&!axO<
507
zGhv_#lnhirIg<<&q0|Wj6<E%MfhtfkPyyvkGEjt4Ck#|zITHq|K*>M_lrzad5lWpf
508
zP=V!47^ngz0~JutBm+e#b;3XemNQ|X3X}{~Ksl2P6rt1!0~J`#gn=qhGEf2KOfpb}
509
zQYQ>lU^x>8szAv=1(Y+%KoLrvFi?TzOc<yFB?A>u&LjgxD0RX>1(q{mpbC@>R6seC
510
z3>2Z%2?G^a&V+#~P%=;f<xDbAgi<FARA4z12C6{GKn0XD$v_cGoiI>=<xCi;0wn_#
511
zP|hR+MJRQ`Kn0dFVW0|>3{*fllMEE0)CmI>Sk8ojDo`>|0p(0GP=rz^3{+q_69%e4
512
z$v_2^Gs!>^N}VuJf#pmXr~)Me6;RG314Srx!axxz28u{EP=u<1B2)}iVZuNaCK;&0
513
zBm-5LFi?dF167!0pbC==RAItE6($T+VUmF=Ofpb~2?JG_Fi?d_2C6X0Kouqo6p_5T
514
zFi=FeV!SiSKoR0H$dH(_Z(*Q_WZ%L-5y`$K14StNmJAdjmWs}HV4<vU_xO+1efmLq
515
zZ;W>N_U)fP6Qy6Nw5mbt9Y(#emWSi66=>tq#xoh#Ue=0qyhxi8ZOUe5y0V7VfPUhp
516
zwX=;ymc+i5%sg9Ja~lZ&8oAV@mHc>&CHP9v4R(jhtT?un;O4e9#pno)Xkh7OWgK&a
517
zyj=3Iv0OuoK_;5rOr5f(Kb~ZXDBO+V`OWYo#_C08imwChQxnjdd?wZLDou8aj;$SD
518
zGDYiA3<$Tu<JnHL(KPOChi#zrR32t83}naR$+ym4P_h?z_5#|cW-nw$XD_sOtE62l
519
zrD3@*)NVyiklt0&yF9%+klsBey&I<Y2E<!f(E8TuJte)z(|ZHyy<^gQVfx}=`q&B5
520
z7nSryp1wGczIaUfVwiq$Fn#<4=@*ssi#+|}K>EdF(l3VTOM~ghPLRH&q%ZOGrGfON
521
zW73zx^yR_y<0nX8R??Sw`tm^f@-gYlNFSp|*<gA{q?Zp5Oe-+l#rmyYmKozi9y=P>
522
zVReJU*h=ZuVXiS$ohTbw-O#v9>(yZbGE|)?8(H1ZIKvV!jWa0>vy!3eMA^vdhQ>`s
523
zuMSg{q3T50$m)j1!HixV<}X9liL#N^4c*tL^y)CF8LCc{jjV3yKAqL8!%SzWI#H%q
524
z=bSrQ&)%JCRttF5g4Zf`6l?y@>PzD7MA^D>wBlcH6r1ucwJ<p0O%rZ?JzIY3-QdmZ
525
zzs|n>`a5r3e|z)wcUaqS>nqFQ-8x}eCF4u`OWUxqst-@1rSmUs%WmKP5e0dcb?e2N
526
z;Z|x*!);VwF|Yuhqs^khqOM!@u*jY!WYldISF(V6`BoNd&6Qfk3>X#SuD^7J>p_D=
527
zBPa51y^_n#=cpOt#Zf$ya$Ae9Mfz56n|<i!a=ELS@)%a{^NIH3SDuN<R~sah1km#P
528
zU@?*f%<rG=4W1wgfi;C?_n|W@%lm$&8YfvNOJodIg&IcIpIJQRHr<+ej11GQ6)&eF
529
z2Lam*jIH}#y0>KnY%4JQfOYS$*uU%f#@$U6`N8I3N-lV?5ErFCdv~xDmu2(wexld4
530
z4v^;aVAT2k6GJ^m*FD(Wqc(Qg^)6a<?}h$zLoj}4;PP!+(O{@!a1y-hoAhF_7!z+6
531
zslpAmNtYbjHrw-~#SPVk_FUf>-Obg6yV`8o$8_`PyJe_;bY5_EMBfBfWU!Q=*9HsG
532
z%_Cda{@_Krr!oHVhv9+y+T5qR8zZ2aZ>5r!$*|f$^U%yBUYfR&B!+EYy_PwL!BeUi
533
zJH^}r3r9Q+B)X@Z)fk=P13w&7x#wBtXTZ)g>WITPg5r&pQc!nmyrmk#S(>>b9xnNr
534
zx_b#v9Xv-Y><Wb%?S^0Xe&<)bbKl_=Z|3C$tf|F<bYzE*mfHB;uC)`q-?buaBe?l?
535
zcLTpK*k<49Z32`K?|nSBMFqxTK^_IE-li2fEGdK~(ZdoKBl6ab4a;Hler#`xvEXJG
536
zb?<E%EZExfX>jcOVhS*0rS~RS1dA#xhkv@Nct@#q?LyeKS<$uFec!bw>{@uu$gZ6a
537
zyVen1i{1BKd%~`D7|m$;U0a<I*3I7%^N%N%lGYdU_GS!gaR8T$NA@GzFi~z`l7hdl
538
zarZy6590|88pi(1zq;V(>38zM0sT&<zX;R5$1w3;`_JMG`;&I&0Y23DMx1%@(w(R9
539
z4M$j;D5J+Gy%fijRQsctzFKf&cv|BAz#YLq3CZJWDdtL4u1u1|mkdcUp7|sxJC+?Y
540
z_@@s`v3j}Q7*z>6X~cwUxUL8G1KT)_XTp!KAbs;vCp{K3&~_X@+ew=-D}v`2MbFV0
541
zQsVsL=rXi-pI*G|iiz;VTCutgUs)hDzV1+4?8KcoP3xROf<M%qC6lgVdpFt4<-|uM
542
z=#rl_b1#YjSIl6Toj2z_hOZcKupkdE(LozC(fN=FY(x|sk)ym|;Rq2E1xJWD%Z!ol
543
Gu>S+TT-130
544
545
literal 0
546
HcmV?d00001
547
548
diff --git a/tests/data/acpi/q35/VIOT.viot b/tests/data/acpi/q35/VIOT.viot
549
index XXXXXXX..XXXXXXX 100644
550
GIT binary patch
551
literal 112
552
zcmWIZ^baXu00LVle`k+i1*eDrX9XZ&1PX!JAex!M0Hgv8m>C3sGzdcgBZCA3T-xBj
553
Q0Zb)W9Hva*zW_`e0M!8s0RR91
554
555
literal 0
556
HcmV?d00001
557
558
--
559
2.25.1
560
561
diff view generated by jsdifflib
New patch
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
1
2
3
The VIOT blob contains the following:
4
5
[000h 0000 4] Signature : "VIOT" [Virtual I/O Translation Table]
6
[004h 0004 4] Table Length : 00000058
7
[008h 0008 1] Revision : 00
8
[009h 0009 1] Checksum : 66
9
[00Ah 0010 6] Oem ID : "BOCHS "
10
[010h 0016 8] Oem Table ID : "BXPC "
11
[018h 0024 4] Oem Revision : 00000001
12
[01Ch 0028 4] Asl Compiler ID : "BXPC"
13
[020h 0032 4] Asl Compiler Revision : 00000001
14
15
[024h 0036 2] Node count : 0002
16
[026h 0038 2] Node offset : 0030
17
[028h 0040 8] Reserved : 0000000000000000
18
19
[030h 0048 1] Type : 03 [VirtIO-PCI IOMMU]
20
[031h 0049 1] Reserved : 00
21
[032h 0050 2] Length : 0010
22
23
[034h 0052 2] PCI Segment : 0000
24
[036h 0054 2] PCI BDF number : 0008
25
[038h 0056 8] Reserved : 0000000000000000
26
27
[040h 0064 1] Type : 01 [PCI Range]
28
[041h 0065 1] Reserved : 00
29
[042h 0066 2] Length : 0018
30
31
[044h 0068 4] Endpoint start : 00000000
32
[048h 0072 2] PCI Segment start : 0000
33
[04Ah 0074 2] PCI Segment end : 0000
34
[04Ch 0076 2] PCI BDF start : 0000
35
[04Eh 0078 2] PCI BDF end : 00FF
36
[050h 0080 2] Output node : 0030
37
[052h 0082 6] Reserved : 000000000000
38
39
Acked-by: Ani Sinha <ani@anisinha.ca>
40
Reviewed-by: Eric Auger <eric.auger@redhat.com>
41
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
42
Message-id: 20211210170415.583179-9-jean-philippe@linaro.org
43
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
44
---
45
tests/qtest/bios-tables-test-allowed-diff.h | 1 -
46
tests/data/acpi/virt/VIOT | Bin 0 -> 88 bytes
47
2 files changed, 1 deletion(-)
48
49
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
50
index XXXXXXX..XXXXXXX 100644
51
--- a/tests/qtest/bios-tables-test-allowed-diff.h
52
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
53
@@ -1,2 +1 @@
54
/* List of comma-separated changed AML files to ignore */
55
-"tests/data/acpi/virt/VIOT",
56
diff --git a/tests/data/acpi/virt/VIOT b/tests/data/acpi/virt/VIOT
57
index XXXXXXX..XXXXXXX 100644
58
GIT binary patch
59
literal 88
60
zcmWIZ^bd((0D?3pe`k+i1*eDrX9XZ&1PX!JAexE60Hgv8m>C3sGzXN&z`)2L0cSHX
61
I{D-Rq0Q5fy0RR91
62
63
literal 0
64
HcmV?d00001
65
66
--
67
2.25.1
68
69
diff view generated by jsdifflib