1
Small pile of bug fixes for rc1. I've included my patches to get
1
The following changes since commit 64ada298b98a51eb2512607f6e6180cb330c47b1:
2
our docs building with Sphinx 3, just for convenience...
3
2
4
-- PMM
3
Merge remote-tracking branch 'remotes/legoater/tags/pull-ppc-20220302' into staging (2022-03-02 12:38:46 +0000)
5
6
The following changes since commit b149dea55cce97cb226683d06af61984a1c11e96:
7
8
Merge remote-tracking branch 'remotes/cschoenebeck/tags/pull-9p-20201102' into staging (2020-11-02 10:57:48 +0000)
9
4
10
are available in the Git repository at:
5
are available in the Git repository at:
11
6
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201102
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220302
13
8
14
for you to fetch changes up to ffb4fbf90a2f63c9cb33e4bb9f854c79bf04ca4a:
9
for you to fetch changes up to 268c11984e67867c22f53beb3c7f8b98900d66b2:
15
10
16
tests/qtest/npcm7xx_rng-test: Disable randomness tests (2020-11-02 16:52:18 +0000)
11
ui/cocoa.m: Remove unnecessary NSAutoreleasePools (2022-03-02 19:27:37 +0000)
17
12
18
----------------------------------------------------------------
13
----------------------------------------------------------------
19
target-arm queue:
14
target-arm queue:
20
* target/arm: Fix Neon emulation bugs on big-endian hosts
15
* mps3-an547: Add missing user ahb interfaces
21
* target/arm: fix handling of HCR.FB
16
* hw/arm/mps2-tz.c: Update AN547 documentation URL
22
* target/arm: fix LORID_EL1 access check
17
* hw/input/tsc210x: Don't abort on bad SPI word widths
23
* disas/capstone: Fix monitor disassembly of >32 bytes
18
* hw/i2c: flatten pca954x mux device
24
* hw/arm/smmuv3: Fix potential integer overflow (CID 1432363)
19
* target/arm: Support PSCI 1.1 and SMCCC 1.0
25
* hw/arm/boot: fix SVE for EL3 direct kernel boot
20
* target/arm: Fix early free of TCG temp in handle_simd_shift_fpint_conv()
26
* hw/display/omap_lcdc: Fix potential NULL pointer dereference
21
* tests/qtest: add qtests for npcm7xx sdhci
27
* hw/display/exynos4210_fimd: Fix potential NULL pointer dereference
22
* Implement FEAT_LVA
28
* target/arm: Get correct MMU index for other-security-state
23
* Implement FEAT_LPA
29
* configure: Test that gio libs from pkg-config work
24
* Implement FEAT_LPA2 (but do not enable it yet)
30
* hw/intc/arm_gicv3_cpuif: Make GIC maintenance interrupts work
25
* Report KVM's actual PSCI version to guest in dtb
31
* docs: Fix building with Sphinx 3
26
* ui/cocoa.m: Fix updateUIInfo threading issues
32
* tests/qtest/npcm7xx_rng-test: Disable randomness tests
27
* ui/cocoa.m: Remove unnecessary NSAutoreleasePools
33
28
34
----------------------------------------------------------------
29
----------------------------------------------------------------
35
AlexChen (2):
30
Akihiko Odaki (1):
36
hw/display/omap_lcdc: Fix potential NULL pointer dereference
31
target/arm: Support PSCI 1.1 and SMCCC 1.0
37
hw/display/exynos4210_fimd: Fix potential NULL pointer dereference
38
32
39
Peter Maydell (9):
33
Jimmy Brisson (1):
40
target/arm: Fix float16 pairwise Neon ops on big-endian hosts
34
mps3-an547: Add missing user ahb interfaces
41
target/arm: Fix VUDOT/VSDOT (scalar) on big-endian hosts
42
disas/capstone: Fix monitor disassembly of >32 bytes
43
target/arm: Get correct MMU index for other-security-state
44
configure: Test that gio libs from pkg-config work
45
hw/intc/arm_gicv3_cpuif: Make GIC maintenance interrupts work
46
scripts/kerneldoc: For Sphinx 3 use c:macro for macros with arguments
47
qemu-option-trace.rst.inc: Don't use option:: markup
48
tests/qtest/npcm7xx_rng-test: Disable randomness tests
49
35
50
Philippe Mathieu-Daudé (1):
36
Patrick Venture (1):
51
hw/arm/smmuv3: Fix potential integer overflow (CID 1432363)
37
hw/i2c: flatten pca954x mux device
52
38
53
Richard Henderson (11):
39
Peter Maydell (5):
54
target/arm: Introduce neon_full_reg_offset
40
hw/arm/mps2-tz.c: Update AN547 documentation URL
55
target/arm: Move neon_element_offset to translate.c
41
hw/input/tsc210x: Don't abort on bad SPI word widths
56
target/arm: Use neon_element_offset in neon_load/store_reg
42
target/arm: Report KVM's actual PSCI version to guest in dtb
57
target/arm: Use neon_element_offset in vfp_reg_offset
43
ui/cocoa.m: Fix updateUIInfo threading issues
58
target/arm: Add read/write_neon_element32
44
ui/cocoa.m: Remove unnecessary NSAutoreleasePools
59
target/arm: Expand read/write_neon_element32 to all MemOp
60
target/arm: Rename neon_load_reg32 to vfp_load_reg32
61
target/arm: Add read/write_neon_element64
62
target/arm: Rename neon_load_reg64 to vfp_load_reg64
63
target/arm: Simplify do_long_3d and do_2scalar_long
64
target/arm: Improve do_prewiden_3d
65
45
66
Rémi Denis-Courmont (3):
46
Richard Henderson (16):
67
target/arm: fix handling of HCR.FB
47
hw/registerfields: Add FIELD_SEX<N> and FIELD_SDP<N>
68
target/arm: fix LORID_EL1 access check
48
target/arm: Set TCR_EL1.TSZ for user-only
69
hw/arm/boot: fix SVE for EL3 direct kernel boot
49
target/arm: Fault on invalid TCR_ELx.TxSZ
50
target/arm: Move arm_pamax out of line
51
target/arm: Pass outputsize down to check_s2_mmu_setup
52
target/arm: Use MAKE_64BIT_MASK to compute indexmask
53
target/arm: Honor TCR_ELx.{I}PS
54
target/arm: Prepare DBGBVR and DBGWVR for FEAT_LVA
55
target/arm: Implement FEAT_LVA
56
target/arm: Implement FEAT_LPA
57
target/arm: Extend arm_fi_to_lfsc to level -1
58
target/arm: Introduce tlbi_aa64_get_range
59
target/arm: Fix TLBIRange.base for 16k and 64k pages
60
target/arm: Validate tlbi TG matches translation granule in use
61
target/arm: Advertise all page sizes for -cpu max
62
target/arm: Implement FEAT_LPA2
70
63
71
docs/qemu-option-trace.rst.inc | 6 +-
64
Shengtan Mao (1):
72
configure | 10 +-
65
tests/qtest: add qtests for npcm7xx sdhci
73
include/hw/intc/arm_gicv3_common.h | 1 -
74
disas/capstone.c | 2 +-
75
hw/arm/boot.c | 3 +
76
hw/arm/smmuv3.c | 3 +-
77
hw/display/exynos4210_fimd.c | 4 +-
78
hw/display/omap_lcdc.c | 10 +-
79
hw/intc/arm_gicv3_cpuif.c | 5 +-
80
target/arm/helper.c | 24 +-
81
target/arm/m_helper.c | 3 +-
82
target/arm/translate.c | 153 +++++++++---
83
target/arm/vec_helper.c | 12 +-
84
tests/qtest/npcm7xx_rng-test.c | 14 +-
85
scripts/kernel-doc | 18 +-
86
target/arm/translate-neon.c.inc | 472 ++++++++++++++++++++-----------------
87
target/arm/translate-vfp.c.inc | 341 +++++++++++----------------
88
17 files changed, 588 insertions(+), 493 deletions(-)
89
66
67
Wentao_Liang (1):
68
target/arm: Fix early free of TCG temp in handle_simd_shift_fpint_conv()
69
70
docs/system/arm/emulation.rst | 3 +
71
include/hw/registerfields.h | 48 +++++-
72
target/arm/cpu-param.h | 4 +-
73
target/arm/cpu.h | 27 ++++
74
target/arm/internals.h | 58 ++++---
75
target/arm/kvm-consts.h | 14 +-
76
hw/arm/boot.c | 11 +-
77
hw/arm/mps2-tz.c | 6 +-
78
hw/i2c/i2c_mux_pca954x.c | 77 ++-------
79
hw/input/tsc210x.c | 8 +-
80
target/arm/cpu.c | 8 +-
81
target/arm/cpu64.c | 7 +-
82
target/arm/helper.c | 332 ++++++++++++++++++++++++++++++---------
83
target/arm/hvf/hvf.c | 27 +++-
84
target/arm/kvm64.c | 14 +-
85
target/arm/psci.c | 35 ++++-
86
target/arm/translate-a64.c | 2 +-
87
tests/qtest/npcm7xx_sdhci-test.c | 215 +++++++++++++++++++++++++
88
tests/qtest/meson.build | 1 +
89
ui/cocoa.m | 31 ++--
90
20 files changed, 736 insertions(+), 192 deletions(-)
91
create mode 100644 tests/qtest/npcm7xx_sdhci-test.c
diff view generated by jsdifflib
1
Sphinx 3.2 is pickier than earlier versions about the option:: markup,
1
From: Jimmy Brisson <jimmy.brisson@linaro.org>
2
and complains about our usage in qemu-option-trace.rst:
3
2
4
../../docs/qemu-option-trace.rst.inc:4:Malformed option description
3
With these interfaces missing, TFM would delegate peripherals 0, 1,
5
'[enable=]PATTERN', should look like "opt", "-opt args", "--opt args",
4
2, 3 and 8, and qemu would ignore the delegation of interface 8, as
6
"/opt args" or "+opt args"
5
it thought interface 4 was eth & USB.
7
6
8
In this file, we're really trying to document the different parts of
7
This patch corrects this behavior and allows TFM to delegate the
9
the top-level --trace option, which qemu-nbd.rst and qemu-img.rst
8
eth & USB peripheral to NS mode.
10
have already introduced with an option:: markup. So it's not right
11
to use option:: here anyway. Switch to a different markup
12
(definition lists) which gives about the same formatted output.
13
9
14
(Unlike option::, this markup doesn't produce index entries; but
10
(The old QEMU behaviour was based on revision B of the AN547
15
at the moment we don't do anything much with indexes anyway, and
11
appnote; revision C corrects this error in the documentation,
16
in any case I think it doesn't make much sense to have individual
12
and this commit brings QEMU in to line with how the FPGA
17
index entries for the sub-parts of the --trace option.)
13
image really behaves.)
18
14
15
Signed-off-by: Jimmy Brisson <jimmy.brisson@linaro.org>
16
Message-id: 20220210210227.3203883-1-jimmy.brisson@linaro.org
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
[PMM: added commit message note clarifying that the old behaviour
19
was a docs issue, not because there were two different versions
20
of the FPGA image]
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
21
Tested-by: Stefan Hajnoczi <stefanha@redhat.com>
22
Message-id: 20201030174700.7204-3-peter.maydell@linaro.org
23
---
22
---
24
docs/qemu-option-trace.rst.inc | 6 +++---
23
hw/arm/mps2-tz.c | 4 ++++
25
1 file changed, 3 insertions(+), 3 deletions(-)
24
1 file changed, 4 insertions(+)
26
25
27
diff --git a/docs/qemu-option-trace.rst.inc b/docs/qemu-option-trace.rst.inc
26
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
28
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
29
--- a/docs/qemu-option-trace.rst.inc
28
--- a/hw/arm/mps2-tz.c
30
+++ b/docs/qemu-option-trace.rst.inc
29
+++ b/hw/arm/mps2-tz.c
31
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
32
31
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
33
Specify tracing options.
32
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
34
33
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
35
-.. option:: [enable=]PATTERN
34
+ { /* port 4 USER AHB interface 0 */ },
36
+``[enable=]PATTERN``
35
+ { /* port 5 USER AHB interface 1 */ },
37
36
+ { /* port 6 USER AHB interface 2 */ },
38
Immediately enable events matching *PATTERN*
37
+ { /* port 7 USER AHB interface 3 */ },
39
(either event name or a globbing pattern). This option is only
38
{ "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 49 } },
40
@@ -XXX,XX +XXX,XX @@ Specify tracing options.
39
},
41
40
},
42
Use :option:`-trace help` to print a list of names of trace points.
43
44
-.. option:: events=FILE
45
+``events=FILE``
46
47
Immediately enable events listed in *FILE*.
48
The file must contain one event name (as listed in the ``trace-events-all``
49
@@ -XXX,XX +XXX,XX @@ Specify tracing options.
50
available if QEMU has been compiled with the ``simple``, ``log`` or
51
``ftrace`` tracing backend.
52
53
-.. option:: file=FILE
54
+``file=FILE``
55
56
Log output traces to *FILE*.
57
This option is only available if QEMU has been compiled with
58
--
41
--
59
2.20.1
42
2.25.1
60
61
diff view generated by jsdifflib
1
If we're using the capstone disassembler, disassembly of a run of
1
The AN547 application note URL has changed: update our comment
2
instructions more than 32 bytes long disassembles the wrong data for
2
accordingly. (Rev B is still downloadable from the old URL,
3
instructions beyond the 32 byte mark:
3
but there is a new Rev C of the document now.)
4
4
5
(qemu) xp /16x 0x100
6
0000000000000100: 0x00000005 0x54410001 0x00000001 0x00001000
7
0000000000000110: 0x00000000 0x00000004 0x54410002 0x3c000000
8
0000000000000120: 0x00000000 0x00000004 0x54410009 0x74736574
9
0000000000000130: 0x00000000 0x00000000 0x00000000 0x00000000
10
(qemu) xp /16i 0x100
11
0x00000100: 00000005 andeq r0, r0, r5
12
0x00000104: 54410001 strbpl r0, [r1], #-1
13
0x00000108: 00000001 andeq r0, r0, r1
14
0x0000010c: 00001000 andeq r1, r0, r0
15
0x00000110: 00000000 andeq r0, r0, r0
16
0x00000114: 00000004 andeq r0, r0, r4
17
0x00000118: 54410002 strbpl r0, [r1], #-2
18
0x0000011c: 3c000000 .byte 0x00, 0x00, 0x00, 0x3c
19
0x00000120: 54410001 strbpl r0, [r1], #-1
20
0x00000124: 00000001 andeq r0, r0, r1
21
0x00000128: 00001000 andeq r1, r0, r0
22
0x0000012c: 00000000 andeq r0, r0, r0
23
0x00000130: 00000004 andeq r0, r0, r4
24
0x00000134: 54410002 strbpl r0, [r1], #-2
25
0x00000138: 3c000000 .byte 0x00, 0x00, 0x00, 0x3c
26
0x0000013c: 00000000 andeq r0, r0, r0
27
28
Here the disassembly of 0x120..0x13f is using the data that is in
29
0x104..0x123.
30
31
This is caused by passing the wrong value to the read_memory_func().
32
The intention is that at this point in the loop the 'cap_buf' buffer
33
already contains 'csize' bytes of data for the instruction at guest
34
addr 'pc', and we want to read in an extra 'tsize' bytes. Those
35
extra bytes are therefore at 'pc + csize', not 'pc'. On the first
36
time through the loop 'csize' happens to be zero, so the initial read
37
of 32 bytes into cap_buf is correct and as long as the disassembly
38
never needs to read more data we return the correct information.
39
40
Use the correct guest address in the call to read_memory_func().
41
42
Cc: qemu-stable@nongnu.org
43
Fixes: https://bugs.launchpad.net/qemu/+bug/1900779
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
45
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
46
Message-id: 20201022132445.25039-1-peter.maydell@linaro.org
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20220221094144.426191-1-peter.maydell@linaro.org
47
---
9
---
48
disas/capstone.c | 2 +-
10
hw/arm/mps2-tz.c | 2 +-
49
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 1 insertion(+), 1 deletion(-)
50
12
51
diff --git a/disas/capstone.c b/disas/capstone.c
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
52
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
53
--- a/disas/capstone.c
15
--- a/hw/arm/mps2-tz.c
54
+++ b/disas/capstone.c
16
+++ b/hw/arm/mps2-tz.c
55
@@ -XXX,XX +XXX,XX @@ bool cap_disas_monitor(disassemble_info *info, uint64_t pc, int count)
17
@@ -XXX,XX +XXX,XX @@
56
18
* Application Note AN524:
57
/* Make certain that we can make progress. */
19
* https://developer.arm.com/documentation/dai0524/latest/
58
assert(tsize != 0);
20
* Application Note AN547:
59
- info->read_memory_func(pc, cap_buf + csize, tsize, info);
21
- * https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/DAI0547B_SSE300_PLUS_U55_FPGA_for_mps3.pdf
60
+ info->read_memory_func(pc + csize, cap_buf + csize, tsize, info);
22
+ * https://developer.arm.com/documentation/dai0547/latest/
61
csize += tsize;
23
*
62
24
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
63
if (cs_disasm_iter(handle, &cbuf, &csize, &pc, insn)) {
25
* (ARM ECM0601256) for the details of some of the device layout:
64
--
26
--
65
2.20.1
27
2.25.1
66
28
67
29
diff view generated by jsdifflib
1
The randomness tests in the NPCM7xx RNG test fail intermittently
1
The tsc210x doesn't support anything other than 16-bit reads on the
2
but fairly frequently. On my machine running the test in a loop:
2
SPI bus, but the guest can program the SPI controller to attempt
3
while QTEST_QEMU_BINARY=./qemu-system-aarch64 ./tests/qtest/npcm7xx_rng-test; do true; done
3
them anyway. If this happens, don't abort QEMU, just log this as
4
a guest error.
4
5
5
will fail in less than a minute with an error like:
6
This fixes our machine_arm_n8x0.py:N8x0Machine.test_n800
6
ERROR:../../tests/qtest/npcm7xx_rng-test.c:256:test_first_byte_runs:
7
acceptance test, which hits this assertion.
7
assertion failed (calc_runs_p(buf.l, sizeof(buf) * BITS_PER_BYTE) > 0.01): (0.00286205989 > 0.01)
8
8
9
(Failures have been observed on all 4 of the randomness tests,
9
The reason we hit the assertion is because the guest kernel thinks
10
not just first_byte_runs.)
10
there is a TSC2005 on this SPI bus address, not a TSC210x. (The n810
11
*does* have a TSC2005 at this address.) The TSC2005 supports the
12
24-bit accesses which the guest driver makes, and the TSC210x does
13
not (that is, our TSC210x emulation is not missing support for a word
14
width the hardware can handle). It's not clear whether the problem
15
here is that the guest kernel incorrectly thinks the n800 has the
16
same device at this SPI bus address as the n810, or that QEMU's n810
17
board model doesn't get the SPI devices right. At this late date
18
there no longer appears to be any reliable information on the web
19
about the hardware behaviour, but I am inclined to think this is a
20
guest kernel bug. In any case, we prefer not to abort QEMU for
21
guest-triggerable conditions, so logging the error is the right thing
22
to do.
11
23
12
It's not clear why these tests are failing like this, but intermittent
24
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/736
13
failures make CI and merge testing awkward, so disable running them
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
unless a developer specifically sets QEMU_TEST_FLAKY_RNG_TESTS when
26
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
running the test suite, until we work out the cause.
27
Message-id: 20220221140750.514557-1-peter.maydell@linaro.org
28
---
29
hw/input/tsc210x.c | 8 ++++++--
30
1 file changed, 6 insertions(+), 2 deletions(-)
16
31
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
Message-id: 20201102152454.8287-1-peter.maydell@linaro.org
20
Reviewed-by: Havard Skinnemoen <hskinnemoen@google.com>
21
---
22
tests/qtest/npcm7xx_rng-test.c | 14 ++++++++++----
23
1 file changed, 10 insertions(+), 4 deletions(-)
24
25
diff --git a/tests/qtest/npcm7xx_rng-test.c b/tests/qtest/npcm7xx_rng-test.c
26
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/qtest/npcm7xx_rng-test.c
34
--- a/hw/input/tsc210x.c
28
+++ b/tests/qtest/npcm7xx_rng-test.c
35
+++ b/hw/input/tsc210x.c
29
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
36
@@ -XXX,XX +XXX,XX @@
30
37
#include "hw/hw.h"
31
qtest_add_func("npcm7xx_rng/enable_disable", test_enable_disable);
38
#include "audio/audio.h"
32
qtest_add_func("npcm7xx_rng/rosel", test_rosel);
39
#include "qemu/timer.h"
33
- qtest_add_func("npcm7xx_rng/continuous/monobit", test_continuous_monobit);
40
+#include "qemu/log.h"
34
- qtest_add_func("npcm7xx_rng/continuous/runs", test_continuous_runs);
41
#include "sysemu/reset.h"
35
- qtest_add_func("npcm7xx_rng/first_byte/monobit", test_first_byte_monobit);
42
#include "ui/console.h"
36
- qtest_add_func("npcm7xx_rng/first_byte/runs", test_first_byte_runs);
43
#include "hw/arm/omap.h" /* For I2SCodec */
37
+ /*
44
@@ -XXX,XX +XXX,XX @@ uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len)
38
+ * These tests fail intermittently; only run them on explicit
45
TSC210xState *s = opaque;
39
+ * request until we figure out why.
46
uint32_t ret = 0;
40
+ */
47
41
+ if (getenv("QEMU_TEST_FLAKY_RNG_TESTS")) {
48
- if (len != 16)
42
+ qtest_add_func("npcm7xx_rng/continuous/monobit", test_continuous_monobit);
49
- hw_error("%s: FIXME: bad SPI word width %i\n", __func__, len);
43
+ qtest_add_func("npcm7xx_rng/continuous/runs", test_continuous_runs);
50
+ if (len != 16) {
44
+ qtest_add_func("npcm7xx_rng/first_byte/monobit", test_first_byte_monobit);
51
+ qemu_log_mask(LOG_GUEST_ERROR,
45
+ qtest_add_func("npcm7xx_rng/first_byte/runs", test_first_byte_runs);
52
+ "%s: bad SPI word width %i\n", __func__, len);
53
+ return 0;
46
+ }
54
+ }
47
55
48
qtest_start("-machine npcm750-evb");
56
/* TODO: sequential reads etc - how do we make sure the host doesn't
49
ret = g_test_run();
57
* unintentionally read out a conversion result from a register while
50
--
58
--
51
2.20.1
59
2.25.1
52
60
53
61
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Patrick Venture <venture@google.com>
2
2
3
We can then use this to improve VMOV (scalar to gp) and
3
Previously this device created N subdevices which each owned an i2c bus.
4
VMOV (gp to scalar) so that we simply perform the memory
4
Now this device simply owns the N i2c busses directly.
5
operation that we wanted, rather than inserting or
6
extracting from a 32-bit quantity.
7
5
8
These were the last uses of neon_load/store_reg, so remove them.
6
Tested: Verified devices behind mux are still accessible via qmp and i2c
7
from within an arm32 SoC.
9
8
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Hao Wu <wuhaotsh@google.com>
11
Message-id: 20201030022618.785675-7-richard.henderson@linaro.org
10
Signed-off-by: Patrick Venture <venture@google.com>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20220202164533.1283668-1-venture@google.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
---
15
target/arm/translate.c | 50 +++++++++++++-----------
16
hw/i2c/i2c_mux_pca954x.c | 77 +++++++---------------------------------
16
target/arm/translate-vfp.c.inc | 71 +++++-----------------------------
17
1 file changed, 13 insertions(+), 64 deletions(-)
17
2 files changed, 37 insertions(+), 84 deletions(-)
18
18
19
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
diff --git a/hw/i2c/i2c_mux_pca954x.c b/hw/i2c/i2c_mux_pca954x.c
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate.c
21
--- a/hw/i2c/i2c_mux_pca954x.c
22
+++ b/target/arm/translate.c
22
+++ b/hw/i2c/i2c_mux_pca954x.c
23
@@ -XXX,XX +XXX,XX @@ static long neon_full_reg_offset(unsigned reg)
23
@@ -XXX,XX +XXX,XX @@
24
* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
24
#define PCA9548_CHANNEL_COUNT 8
25
* where 0 is the least significant end of the register.
25
#define PCA9546_CHANNEL_COUNT 4
26
*/
26
27
-static long neon_element_offset(int reg, int element, MemOp size)
27
-/*
28
+static long neon_element_offset(int reg, int element, MemOp memop)
28
- * struct Pca954xChannel - The i2c mux device will have N of these states
29
{
29
- * that own the i2c channel bus.
30
- int element_size = 1 << size;
30
- * @bus: The owned channel bus.
31
+ int element_size = 1 << (memop & MO_SIZE);
31
- * @enabled: Is this channel active?
32
int ofs = element * element_size;
32
- */
33
#ifdef HOST_WORDS_BIGENDIAN
33
-typedef struct Pca954xChannel {
34
/*
34
- SysBusDevice parent;
35
@@ -XXX,XX +XXX,XX @@ static long vfp_reg_offset(bool dp, unsigned reg)
35
-
36
- I2CBus *bus;
37
-
38
- bool enabled;
39
-} Pca954xChannel;
40
-
41
-#define TYPE_PCA954X_CHANNEL "pca954x-channel"
42
-#define PCA954X_CHANNEL(obj) \
43
- OBJECT_CHECK(Pca954xChannel, (obj), TYPE_PCA954X_CHANNEL)
44
-
45
/*
46
* struct Pca954xState - The pca954x state object.
47
* @control: The value written to the mux control.
48
@@ -XXX,XX +XXX,XX @@ typedef struct Pca954xState {
49
50
uint8_t control;
51
52
- /* The channel i2c buses. */
53
- Pca954xChannel channel[PCA9548_CHANNEL_COUNT];
54
+ bool enabled[PCA9548_CHANNEL_COUNT];
55
+ I2CBus *bus[PCA9548_CHANNEL_COUNT];
56
} Pca954xState;
57
58
/*
59
@@ -XXX,XX +XXX,XX @@ static bool pca954x_match(I2CSlave *candidate, uint8_t address,
60
}
61
62
for (i = 0; i < mc->nchans; i++) {
63
- if (!mux->channel[i].enabled) {
64
+ if (!mux->enabled[i]) {
65
continue;
66
}
67
68
- if (i2c_scan_bus(mux->channel[i].bus, address, broadcast,
69
+ if (i2c_scan_bus(mux->bus[i], address, broadcast,
70
current_devs)) {
71
if (!broadcast) {
72
return true;
73
@@ -XXX,XX +XXX,XX @@ static void pca954x_enable_channel(Pca954xState *s, uint8_t enable_mask)
74
*/
75
for (i = 0; i < mc->nchans; i++) {
76
if (enable_mask & (1 << i)) {
77
- s->channel[i].enabled = true;
78
+ s->enabled[i] = true;
79
} else {
80
- s->channel[i].enabled = false;
81
+ s->enabled[i] = false;
82
}
36
}
83
}
37
}
84
}
38
85
@@ -XXX,XX +XXX,XX @@ I2CBus *pca954x_i2c_get_bus(I2CSlave *mux, uint8_t channel)
39
-static TCGv_i32 neon_load_reg(int reg, int pass)
86
Pca954xState *pca954x = PCA954X(mux);
40
-{
87
41
- TCGv_i32 tmp = tcg_temp_new_i32();
88
g_assert(channel < pc->nchans);
42
- tcg_gen_ld_i32(tmp, cpu_env, neon_element_offset(reg, pass, MO_32));
89
- return I2C_BUS(qdev_get_child_bus(DEVICE(&pca954x->channel[channel]),
43
- return tmp;
90
- "i2c-bus"));
44
-}
91
-}
45
-
92
-
46
-static void neon_store_reg(int reg, int pass, TCGv_i32 var)
93
-static void pca954x_channel_init(Object *obj)
47
-{
94
-{
48
- tcg_gen_st_i32(var, cpu_env, neon_element_offset(reg, pass, MO_32));
95
- Pca954xChannel *s = PCA954X_CHANNEL(obj);
49
- tcg_temp_free_i32(var);
96
- s->bus = i2c_init_bus(DEVICE(s), "i2c-bus");
97
-
98
- /* Start all channels as disabled. */
99
- s->enabled = false;
50
-}
100
-}
51
-
101
-
52
static inline void neon_load_reg64(TCGv_i64 var, int reg)
102
-static void pca954x_channel_class_init(ObjectClass *klass, void *data)
103
-{
104
- DeviceClass *dc = DEVICE_CLASS(klass);
105
- dc->desc = "Pca954x Channel";
106
+ return pca954x->bus[channel];
107
}
108
109
static void pca9546_class_init(ObjectClass *klass, void *data)
110
@@ -XXX,XX +XXX,XX @@ static void pca9548_class_init(ObjectClass *klass, void *data)
111
s->nchans = PCA9548_CHANNEL_COUNT;
112
}
113
114
-static void pca954x_realize(DeviceState *dev, Error **errp)
115
-{
116
- Pca954xState *s = PCA954X(dev);
117
- Pca954xClass *c = PCA954X_GET_CLASS(s);
118
- int i;
119
-
120
- /* SMBus modules. Cannot fail. */
121
- for (i = 0; i < c->nchans; i++) {
122
- sysbus_realize(SYS_BUS_DEVICE(&s->channel[i]), &error_abort);
123
- }
124
-}
125
-
126
static void pca954x_init(Object *obj)
53
{
127
{
54
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
128
Pca954xState *s = PCA954X(obj);
55
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg32(TCGv_i32 var, int reg)
129
Pca954xClass *c = PCA954X_GET_CLASS(obj);
56
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
130
int i;
57
}
131
58
132
- /* Only initialize the children we expect. */
59
-static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
133
+ /* SMBus modules. Cannot fail. */
60
+static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
134
for (i = 0; i < c->nchans; i++) {
61
{
135
- object_initialize_child(obj, "channel[*]", &s->channel[i],
62
- long off = neon_element_offset(reg, ele, size);
136
- TYPE_PCA954X_CHANNEL);
63
+ long off = neon_element_offset(reg, ele, memop);
137
+ g_autofree gchar *bus_name = g_strdup_printf("i2c.%d", i);
64
138
+
65
- switch (size) {
139
+ /* start all channels as disabled. */
66
- case MO_32:
140
+ s->enabled[i] = false;
67
+ switch (memop) {
141
+ s->bus[i] = i2c_init_bus(DEVICE(s), bus_name);
68
+ case MO_SB:
69
+ tcg_gen_ld8s_i32(dest, cpu_env, off);
70
+ break;
71
+ case MO_UB:
72
+ tcg_gen_ld8u_i32(dest, cpu_env, off);
73
+ break;
74
+ case MO_SW:
75
+ tcg_gen_ld16s_i32(dest, cpu_env, off);
76
+ break;
77
+ case MO_UW:
78
+ tcg_gen_ld16u_i32(dest, cpu_env, off);
79
+ break;
80
+ case MO_UL:
81
+ case MO_SL:
82
tcg_gen_ld_i32(dest, cpu_env, off);
83
break;
84
default:
85
@@ -XXX,XX +XXX,XX @@ static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
86
}
142
}
87
}
143
}
88
144
89
-static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp size)
145
@@ -XXX,XX +XXX,XX @@ static void pca954x_class_init(ObjectClass *klass, void *data)
90
+static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
146
rc->phases.enter = pca954x_enter_reset;
91
{
147
92
- long off = neon_element_offset(reg, ele, size);
148
dc->desc = "Pca954x i2c-mux";
93
+ long off = neon_element_offset(reg, ele, memop);
149
- dc->realize = pca954x_realize;
94
150
95
- switch (size) {
151
k->write_data = pca954x_write_data;
96
+ switch (memop) {
152
k->receive_byte = pca954x_read_byte;
97
+ case MO_8:
153
@@ -XXX,XX +XXX,XX @@ static const TypeInfo pca954x_info[] = {
98
+ tcg_gen_st8_i32(src, cpu_env, off);
154
.parent = TYPE_PCA954X,
99
+ break;
155
.class_init = pca9548_class_init,
100
+ case MO_16:
156
},
101
+ tcg_gen_st16_i32(src, cpu_env, off);
157
- {
102
+ break;
158
- .name = TYPE_PCA954X_CHANNEL,
103
case MO_32:
159
- .parent = TYPE_SYS_BUS_DEVICE,
104
tcg_gen_st_i32(src, cpu_env, off);
160
- .class_init = pca954x_channel_class_init,
105
break;
161
- .instance_size = sizeof(Pca954xChannel),
106
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
162
- .instance_init = pca954x_channel_init,
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-vfp.c.inc
109
+++ b/target/arm/translate-vfp.c.inc
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
111
{
112
/* VMOV scalar to general purpose register */
113
TCGv_i32 tmp;
114
- int pass;
115
- uint32_t offset;
116
117
- /* SIZE == 2 is a VFP instruction; otherwise NEON. */
118
- if (a->size == 2
119
+ /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
120
+ if (a->size == MO_32
121
? !dc_isar_feature(aa32_fpsp_v2, s)
122
: !arm_dc_feature(s, ARM_FEATURE_NEON)) {
123
return false;
124
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
125
return false;
126
}
127
128
- offset = a->index << a->size;
129
- pass = extract32(offset, 2, 1);
130
- offset = extract32(offset, 0, 2) * 8;
131
-
132
if (!vfp_access_check(s)) {
133
return true;
134
}
135
136
- tmp = neon_load_reg(a->vn, pass);
137
- switch (a->size) {
138
- case 0:
139
- if (offset) {
140
- tcg_gen_shri_i32(tmp, tmp, offset);
141
- }
142
- if (a->u) {
143
- gen_uxtb(tmp);
144
- } else {
145
- gen_sxtb(tmp);
146
- }
147
- break;
148
- case 1:
149
- if (a->u) {
150
- if (offset) {
151
- tcg_gen_shri_i32(tmp, tmp, 16);
152
- } else {
153
- gen_uxth(tmp);
154
- }
155
- } else {
156
- if (offset) {
157
- tcg_gen_sari_i32(tmp, tmp, 16);
158
- } else {
159
- gen_sxth(tmp);
160
- }
161
- }
162
- break;
163
- case 2:
164
- break;
165
- }
163
- }
166
+ tmp = tcg_temp_new_i32();
164
};
167
+ read_neon_element32(tmp, a->vn, a->index, a->size | (a->u ? 0 : MO_SIGN));
165
168
store_reg(s, a->rt, tmp);
166
DEFINE_TYPES(pca954x_info)
169
170
return true;
171
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
172
static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
173
{
174
/* VMOV general purpose register to scalar */
175
- TCGv_i32 tmp, tmp2;
176
- int pass;
177
- uint32_t offset;
178
+ TCGv_i32 tmp;
179
180
- /* SIZE == 2 is a VFP instruction; otherwise NEON. */
181
- if (a->size == 2
182
+ /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
183
+ if (a->size == MO_32
184
? !dc_isar_feature(aa32_fpsp_v2, s)
185
: !arm_dc_feature(s, ARM_FEATURE_NEON)) {
186
return false;
187
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
188
return false;
189
}
190
191
- offset = a->index << a->size;
192
- pass = extract32(offset, 2, 1);
193
- offset = extract32(offset, 0, 2) * 8;
194
-
195
if (!vfp_access_check(s)) {
196
return true;
197
}
198
199
tmp = load_reg(s, a->rt);
200
- switch (a->size) {
201
- case 0:
202
- tmp2 = neon_load_reg(a->vn, pass);
203
- tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
204
- tcg_temp_free_i32(tmp2);
205
- break;
206
- case 1:
207
- tmp2 = neon_load_reg(a->vn, pass);
208
- tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
209
- tcg_temp_free_i32(tmp2);
210
- break;
211
- case 2:
212
- break;
213
- }
214
- neon_store_reg(a->vn, pass, tmp);
215
+ write_neon_element32(tmp, a->vn, a->index, a->size);
216
+ tcg_temp_free_i32(tmp);
217
218
return true;
219
}
220
--
167
--
221
2.20.1
168
2.25.1
222
169
223
170
diff view generated by jsdifflib
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
1
From: Akihiko Odaki <akihiko.odaki@gmail.com>
2
2
3
When booting a CPU with EL3 using the -kernel flag, set up CPTR_EL3 so
3
Support the latest PSCI on TCG and HVF. A 64-bit function called from
4
that SVE will not trap to EL3.
4
AArch32 now returns NOT_SUPPORTED, which is necessary to adhere to SMC
5
Calling Convention 1.0. It is still not compliant with SMCCC 1.3 since
6
they do not implement mandatory functions.
5
7
6
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
8
Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220213035753.34577-1-akihiko.odaki@gmail.com
8
Message-id: 20201030151541.11976-1-remi@remlab.net
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
[PMM: update MISMATCH_CHECK checks on PSCI_VERSION macros to match]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
hw/arm/boot.c | 3 +++
14
target/arm/kvm-consts.h | 13 +++++++++----
12
1 file changed, 3 insertions(+)
15
hw/arm/boot.c | 12 +++++++++---
16
target/arm/cpu.c | 5 +++--
17
target/arm/hvf/hvf.c | 27 ++++++++++++++++++++++++++-
18
target/arm/kvm64.c | 2 +-
19
target/arm/psci.c | 35 ++++++++++++++++++++++++++++++++---
20
6 files changed, 80 insertions(+), 14 deletions(-)
13
21
22
diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/kvm-consts.h
25
+++ b/target/arm/kvm-consts.h
26
@@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_0_1_FN_MIGRATE, KVM_PSCI_FN_MIGRATE);
27
#define QEMU_PSCI_0_2_FN64_AFFINITY_INFO QEMU_PSCI_0_2_FN64(4)
28
#define QEMU_PSCI_0_2_FN64_MIGRATE QEMU_PSCI_0_2_FN64(5)
29
30
+#define QEMU_PSCI_1_0_FN_PSCI_FEATURES QEMU_PSCI_0_2_FN(10)
31
+
32
MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_SUSPEND, PSCI_0_2_FN_CPU_SUSPEND);
33
MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_OFF, PSCI_0_2_FN_CPU_OFF);
34
MISMATCH_CHECK(QEMU_PSCI_0_2_FN_CPU_ON, PSCI_0_2_FN_CPU_ON);
35
@@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_0_2_FN_MIGRATE, PSCI_0_2_FN_MIGRATE);
36
MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_SUSPEND, PSCI_0_2_FN64_CPU_SUSPEND);
37
MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_CPU_ON, PSCI_0_2_FN64_CPU_ON);
38
MISMATCH_CHECK(QEMU_PSCI_0_2_FN64_MIGRATE, PSCI_0_2_FN64_MIGRATE);
39
+MISMATCH_CHECK(QEMU_PSCI_1_0_FN_PSCI_FEATURES, PSCI_1_0_FN_PSCI_FEATURES);
40
41
/* PSCI v0.2 return values used by TCG emulation of PSCI */
42
43
/* No Trusted OS migration to worry about when offlining CPUs */
44
#define QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED 2
45
46
-/* We implement version 0.2 only */
47
-#define QEMU_PSCI_0_2_RET_VERSION_0_2 2
48
+#define QEMU_PSCI_VERSION_0_1 0x00001
49
+#define QEMU_PSCI_VERSION_0_2 0x00002
50
+#define QEMU_PSCI_VERSION_1_1 0x10001
51
52
MISMATCH_CHECK(QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED, PSCI_0_2_TOS_MP);
53
-MISMATCH_CHECK(QEMU_PSCI_0_2_RET_VERSION_0_2,
54
- (PSCI_VERSION_MAJOR(0) | PSCI_VERSION_MINOR(2)));
55
+/* We don't bother to check every possible version value */
56
+MISMATCH_CHECK(QEMU_PSCI_VERSION_0_2, PSCI_VERSION(0, 2));
57
+MISMATCH_CHECK(QEMU_PSCI_VERSION_1_1, PSCI_VERSION(1, 1));
58
59
/* PSCI return values (inclusive of all PSCI versions) */
60
#define QEMU_PSCI_RET_SUCCESS 0
14
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
61
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
15
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/boot.c
63
--- a/hw/arm/boot.c
17
+++ b/hw/arm/boot.c
64
+++ b/hw/arm/boot.c
18
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
65
@@ -XXX,XX +XXX,XX @@ static void fdt_add_psci_node(void *fdt)
19
if (cpu_isar_feature(aa64_mte, cpu)) {
66
}
20
env->cp15.scr_el3 |= SCR_ATA;
67
21
}
68
qemu_fdt_add_subnode(fdt, "/psci");
22
+ if (cpu_isar_feature(aa64_sve, cpu)) {
69
- if (armcpu->psci_version == 2) {
23
+ env->cp15.cptr_el[3] |= CPTR_EZ;
70
- const char comp[] = "arm,psci-0.2\0arm,psci";
24
+ }
71
- qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
25
/* AArch64 kernels never boot in secure mode */
72
+ if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2 ||
26
assert(!info->secure_boot);
73
+ armcpu->psci_version == QEMU_PSCI_VERSION_1_1) {
27
/* This hook is only supported for AArch32 currently:
74
+ if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2) {
75
+ const char comp[] = "arm,psci-0.2\0arm,psci";
76
+ qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
77
+ } else {
78
+ const char comp[] = "arm,psci-1.0\0arm,psci-0.2\0arm,psci";
79
+ qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
80
+ }
81
82
cpu_off_fn = QEMU_PSCI_0_2_FN_CPU_OFF;
83
if (arm_feature(&armcpu->env, ARM_FEATURE_AARCH64)) {
84
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/cpu.c
87
+++ b/target/arm/cpu.c
88
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_initfn(Object *obj)
89
* picky DTB consumer will also provide a helpful error message.
90
*/
91
cpu->dtb_compatible = "qemu,unknown";
92
- cpu->psci_version = 1; /* By default assume PSCI v0.1 */
93
+ cpu->psci_version = QEMU_PSCI_VERSION_0_1; /* By default assume PSCI v0.1 */
94
cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
95
96
if (tcg_enabled() || hvf_enabled()) {
97
- cpu->psci_version = 2; /* TCG and HVF implement PSCI 0.2 */
98
+ /* TCG and HVF implement PSCI 1.1 */
99
+ cpu->psci_version = QEMU_PSCI_VERSION_1_1;
100
}
101
}
102
103
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/target/arm/hvf/hvf.c
106
+++ b/target/arm/hvf/hvf.c
107
@@ -XXX,XX +XXX,XX @@ static bool hvf_handle_psci_call(CPUState *cpu)
108
109
switch (param[0]) {
110
case QEMU_PSCI_0_2_FN_PSCI_VERSION:
111
- ret = QEMU_PSCI_0_2_RET_VERSION_0_2;
112
+ ret = QEMU_PSCI_VERSION_1_1;
113
break;
114
case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
115
ret = QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED; /* No trusted OS */
116
@@ -XXX,XX +XXX,XX @@ static bool hvf_handle_psci_call(CPUState *cpu)
117
case QEMU_PSCI_0_2_FN_MIGRATE:
118
ret = QEMU_PSCI_RET_NOT_SUPPORTED;
119
break;
120
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
121
+ switch (param[1]) {
122
+ case QEMU_PSCI_0_2_FN_PSCI_VERSION:
123
+ case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
124
+ case QEMU_PSCI_0_2_FN_AFFINITY_INFO:
125
+ case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:
126
+ case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
127
+ case QEMU_PSCI_0_2_FN_SYSTEM_OFF:
128
+ case QEMU_PSCI_0_1_FN_CPU_ON:
129
+ case QEMU_PSCI_0_2_FN_CPU_ON:
130
+ case QEMU_PSCI_0_2_FN64_CPU_ON:
131
+ case QEMU_PSCI_0_1_FN_CPU_OFF:
132
+ case QEMU_PSCI_0_2_FN_CPU_OFF:
133
+ case QEMU_PSCI_0_1_FN_CPU_SUSPEND:
134
+ case QEMU_PSCI_0_2_FN_CPU_SUSPEND:
135
+ case QEMU_PSCI_0_2_FN64_CPU_SUSPEND:
136
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
137
+ ret = 0;
138
+ break;
139
+ case QEMU_PSCI_0_1_FN_MIGRATE:
140
+ case QEMU_PSCI_0_2_FN_MIGRATE:
141
+ default:
142
+ ret = QEMU_PSCI_RET_NOT_SUPPORTED;
143
+ }
144
+ break;
145
default:
146
return false;
147
}
148
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/target/arm/kvm64.c
151
+++ b/target/arm/kvm64.c
152
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
153
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_POWER_OFF;
154
}
155
if (kvm_check_extension(cs->kvm_state, KVM_CAP_ARM_PSCI_0_2)) {
156
- cpu->psci_version = 2;
157
+ cpu->psci_version = QEMU_PSCI_VERSION_0_2;
158
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_PSCI_0_2;
159
}
160
if (!arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
161
diff --git a/target/arm/psci.c b/target/arm/psci.c
162
index XXXXXXX..XXXXXXX 100644
163
--- a/target/arm/psci.c
164
+++ b/target/arm/psci.c
165
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
166
{
167
/*
168
* This function partially implements the logic for dispatching Power State
169
- * Coordination Interface (PSCI) calls (as described in ARM DEN 0022B.b),
170
+ * Coordination Interface (PSCI) calls (as described in ARM DEN 0022D.b),
171
* to the extent required for bringing up and taking down secondary cores,
172
* and for handling reset and poweroff requests.
173
* Additional information about the calling convention used is available in
174
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
175
}
176
177
if ((param[0] & QEMU_PSCI_0_2_64BIT) && !is_a64(env)) {
178
- ret = QEMU_PSCI_RET_INVALID_PARAMS;
179
+ ret = QEMU_PSCI_RET_NOT_SUPPORTED;
180
goto err;
181
}
182
183
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
184
ARMCPU *target_cpu;
185
186
case QEMU_PSCI_0_2_FN_PSCI_VERSION:
187
- ret = QEMU_PSCI_0_2_RET_VERSION_0_2;
188
+ ret = QEMU_PSCI_VERSION_1_1;
189
break;
190
case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
191
ret = QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED; /* No trusted OS */
192
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
193
}
194
helper_wfi(env, 4);
195
break;
196
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
197
+ switch (param[1]) {
198
+ case QEMU_PSCI_0_2_FN_PSCI_VERSION:
199
+ case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
200
+ case QEMU_PSCI_0_2_FN_AFFINITY_INFO:
201
+ case QEMU_PSCI_0_2_FN64_AFFINITY_INFO:
202
+ case QEMU_PSCI_0_2_FN_SYSTEM_RESET:
203
+ case QEMU_PSCI_0_2_FN_SYSTEM_OFF:
204
+ case QEMU_PSCI_0_1_FN_CPU_ON:
205
+ case QEMU_PSCI_0_2_FN_CPU_ON:
206
+ case QEMU_PSCI_0_2_FN64_CPU_ON:
207
+ case QEMU_PSCI_0_1_FN_CPU_OFF:
208
+ case QEMU_PSCI_0_2_FN_CPU_OFF:
209
+ case QEMU_PSCI_0_1_FN_CPU_SUSPEND:
210
+ case QEMU_PSCI_0_2_FN_CPU_SUSPEND:
211
+ case QEMU_PSCI_0_2_FN64_CPU_SUSPEND:
212
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
213
+ if (!(param[1] & QEMU_PSCI_0_2_64BIT) || is_a64(env)) {
214
+ ret = 0;
215
+ break;
216
+ }
217
+ /* fallthrough */
218
+ case QEMU_PSCI_0_1_FN_MIGRATE:
219
+ case QEMU_PSCI_0_2_FN_MIGRATE:
220
+ default:
221
+ ret = QEMU_PSCI_RET_NOT_SUPPORTED;
222
+ break;
223
+ }
224
+ break;
225
case QEMU_PSCI_0_1_FN_MIGRATE:
226
case QEMU_PSCI_0_2_FN_MIGRATE:
227
default:
28
--
228
--
29
2.20.1
229
2.25.1
30
31
diff view generated by jsdifflib
1
From: AlexChen <alex.chen@huawei.com>
1
From: Wentao_Liang <Wentao_Liang_g@163.com>
2
2
3
In exynos4210_fimd_update(), the pointer s is dereferinced before
3
handle_simd_shift_fpint_conv() was accidentally freeing the TCG
4
being check if it is valid, which may lead to NULL pointer dereference.
4
temporary tcg_fpstatus too early, before the last use of it. Move
5
So move the assignment to global_width after checking that the s is valid.
5
the free down to where it belongs.
6
6
7
Reported-by: Euler Robot <euler.robot@huawei.com>
7
Signed-off-by: Wentao_Liang <Wentao_Liang_g@163.com>
8
Signed-off-by: Alex Chen <alex.chen@huawei.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
[PMM: cleaned up commit message]
10
Message-id: 5F9F8D88.9030102@huawei.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
hw/display/exynos4210_fimd.c | 4 +++-
12
target/arm/translate-a64.c | 2 +-
14
1 file changed, 3 insertions(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
15
14
16
diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/display/exynos4210_fimd.c
17
--- a/target/arm/translate-a64.c
19
+++ b/hw/display/exynos4210_fimd.c
18
+++ b/target/arm/translate-a64.c
20
@@ -XXX,XX +XXX,XX @@ static void exynos4210_fimd_update(void *opaque)
19
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
21
bool blend = false;
20
}
22
uint8_t *host_fb_addr;
23
bool is_dirty = false;
24
- const int global_width = (s->vidtcon[2] & FIMD_VIDTCON2_SIZE_MASK) + 1;
25
+ int global_width;
26
27
if (!s || !s->console || !s->enabled ||
28
surface_bits_per_pixel(qemu_console_surface(s->console)) == 0) {
29
return;
30
}
21
}
31
+
22
32
+ global_width = (s->vidtcon[2] & FIMD_VIDTCON2_SIZE_MASK) + 1;
23
- tcg_temp_free_ptr(tcg_fpstatus);
33
exynos4210_update_resolution(s);
24
tcg_temp_free_i32(tcg_shift);
34
surface = qemu_console_surface(s->console);
25
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
26
+ tcg_temp_free_ptr(tcg_fpstatus);
27
tcg_temp_free_i32(tcg_rmode);
28
}
35
29
36
--
30
--
37
2.20.1
31
2.25.1
38
39
diff view generated by jsdifflib
1
The kerneldoc script currently emits Sphinx markup for a macro with
1
From: Shengtan Mao <stmao@google.com>
2
arguments that uses the c:function directive. This is correct for
3
Sphinx versions earlier than Sphinx 3, where c:macro doesn't allow
4
documentation of macros with arguments and c:function is not picky
5
about the syntax of what it is passed. However, in Sphinx 3 the
6
c:macro directive was enhanced to support macros with arguments,
7
and c:function was made more picky about what syntax it accepted.
8
2
9
When kerneldoc is told that it needs to produce output for Sphinx
3
Reviewed-by: Hao Wu <wuhaotsh@google.com>
10
3 or later, make it emit c:function only for functions and c:macro
4
Reviewed-by: Chris Rauer <crauer@google.com>
11
for macros with arguments. We assume that anything with a return
5
Signed-off-by: Shengtan Mao <stmao@google.com>
12
type is a function and anything without is a macro.
6
Signed-off-by: Patrick Venture <venture@google.com>
7
Message-id: 20220225174451.192304-1-wuhaotsh@google.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
tests/qtest/npcm7xx_sdhci-test.c | 215 +++++++++++++++++++++++++++++++
11
tests/qtest/meson.build | 1 +
12
2 files changed, 216 insertions(+)
13
create mode 100644 tests/qtest/npcm7xx_sdhci-test.c
13
14
14
This fixes the Sphinx error:
15
diff --git a/tests/qtest/npcm7xx_sdhci-test.c b/tests/qtest/npcm7xx_sdhci-test.c
15
16
new file mode 100644
16
/home/petmay01/linaro/qemu-from-laptop/qemu/docs/../include/qom/object.h:155:Error in declarator
17
index XXXXXXX..XXXXXXX
17
If declarator-id with parameters (e.g., 'void f(int arg)'):
18
--- /dev/null
18
Invalid C declaration: Expected identifier in nested name. [error at 25]
19
+++ b/tests/qtest/npcm7xx_sdhci-test.c
19
DECLARE_INSTANCE_CHECKER ( InstanceType, OBJ_NAME, TYPENAME)
20
@@ -XXX,XX +XXX,XX @@
20
-------------------------^
21
+/*
21
If parenthesis in noptr-declarator (e.g., 'void (*f(int arg))(double)'):
22
+ * QTests for NPCM7xx SD-3.0 / MMC-4.51 Host Controller
22
Error in declarator or parameters
23
+ *
23
Invalid C declaration: Expecting "(" in parameters. [error at 39]
24
+ * Copyright (c) 2022 Google LLC
24
DECLARE_INSTANCE_CHECKER ( InstanceType, OBJ_NAME, TYPENAME)
25
+ *
25
---------------------------------------^
26
+ * This program is free software; you can redistribute it and/or modify it
26
27
+ * under the terms of the GNU General Public License as published by the
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
+ * Free Software Foundation; either version 2 of the License, or
28
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
29
+ * (at your option) any later version.
29
Tested-by: Stefan Hajnoczi <stefanha@redhat.com>
30
+ *
30
Message-id: 20201030174700.7204-2-peter.maydell@linaro.org
31
+ * This program is distributed in the hope that it will be useful, but WITHOUT
31
---
32
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
32
scripts/kernel-doc | 18 +++++++++++++++++-
33
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
33
1 file changed, 17 insertions(+), 1 deletion(-)
34
+ * for more details.
34
35
+ */
35
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
36
+
36
index XXXXXXX..XXXXXXX 100755
37
+#include "qemu/osdep.h"
37
--- a/scripts/kernel-doc
38
+#include "hw/sd/npcm7xx_sdhci.h"
38
+++ b/scripts/kernel-doc
39
+
39
@@ -XXX,XX +XXX,XX @@ sub output_function_rst(%) {
40
+#include "libqos/libqtest.h"
40
    output_highlight_rst($args{'purpose'});
41
+#include "libqtest-single.h"
41
    $start = "\n\n**Syntax**\n\n ``";
42
+#include "libqos/sdhci-cmd.h"
42
} else {
43
+
43
-    print ".. c:function:: ";
44
+#define NPCM7XX_REG_SIZE 0x100
44
+ if ((split(/\./, $sphinx_version))[0] >= 3) {
45
+#define NPCM7XX_MMC_BA 0xF0842000
45
+ # Sphinx 3 and later distinguish macros and functions and
46
+#define NPCM7XX_BLK_SIZE 512
46
+ # complain if you use c:function with something that's not
47
+#define NPCM7XX_TEST_IMAGE_SIZE (1 << 30)
47
+ # syntactically valid as a function declaration.
48
+
48
+ # We assume that anything with a return type is a function
49
+char *sd_path;
49
+ # and anything without is a macro.
50
+
50
+ if ($args{'functiontype'} ne "") {
51
+static QTestState *setup_sd_card(void)
51
+ print ".. c:function:: ";
52
+{
52
+ } else {
53
+ QTestState *qts = qtest_initf(
53
+ print ".. c:macro:: ";
54
+ "-machine kudo-bmc "
55
+ "-device sd-card,drive=drive0 "
56
+ "-drive id=drive0,if=none,file=%s,format=raw,auto-read-only=off",
57
+ sd_path);
58
+
59
+ qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_SWRST, SDHC_RESET_ALL);
60
+ qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_CLKCON,
61
+ SDHC_CLOCK_SDCLK_EN | SDHC_CLOCK_INT_STABLE |
62
+ SDHC_CLOCK_INT_EN);
63
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_APP_CMD);
64
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x41200000, 0, (41 << 8));
65
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_ALL_SEND_CID);
66
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_SEND_RELATIVE_ADDR);
67
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x45670000, 0,
68
+ SDHC_SELECT_DESELECT_CARD);
69
+
70
+ return qts;
71
+}
72
+
73
+static void write_sdread(QTestState *qts, const char *msg)
74
+{
75
+ int fd, ret;
76
+ size_t len = strlen(msg);
77
+ char *rmsg = g_malloc(len);
78
+
79
+ /* write message to sd */
80
+ fd = open(sd_path, O_WRONLY);
81
+ g_assert(fd >= 0);
82
+ ret = write(fd, msg, len);
83
+ close(fd);
84
+ g_assert(ret == len);
85
+
86
+ /* read message using sdhci */
87
+ ret = sdhci_read_cmd(qts, NPCM7XX_MMC_BA, rmsg, len);
88
+ g_assert(ret == len);
89
+ g_assert(!memcmp(rmsg, msg, len));
90
+
91
+ g_free(rmsg);
92
+}
93
+
94
+/* Check MMC can read values from sd */
95
+static void test_read_sd(void)
96
+{
97
+ QTestState *qts = setup_sd_card();
98
+
99
+ write_sdread(qts, "hello world");
100
+ write_sdread(qts, "goodbye");
101
+
102
+ qtest_quit(qts);
103
+}
104
+
105
+static void sdwrite_read(QTestState *qts, const char *msg)
106
+{
107
+ int fd, ret;
108
+ size_t len = strlen(msg);
109
+ char *rmsg = g_malloc(len);
110
+
111
+ /* write message using sdhci */
112
+ sdhci_write_cmd(qts, NPCM7XX_MMC_BA, msg, len, NPCM7XX_BLK_SIZE);
113
+
114
+ /* read message from sd */
115
+ fd = open(sd_path, O_RDONLY);
116
+ g_assert(fd >= 0);
117
+ ret = read(fd, rmsg, len);
118
+ close(fd);
119
+ g_assert(ret == len);
120
+
121
+ g_assert(!memcmp(rmsg, msg, len));
122
+
123
+ g_free(rmsg);
124
+}
125
+
126
+/* Check MMC can write values to sd */
127
+static void test_write_sd(void)
128
+{
129
+ QTestState *qts = setup_sd_card();
130
+
131
+ sdwrite_read(qts, "hello world");
132
+ sdwrite_read(qts, "goodbye");
133
+
134
+ qtest_quit(qts);
135
+}
136
+
137
+/* Check SDHCI has correct default values. */
138
+static void test_reset(void)
139
+{
140
+ QTestState *qts = qtest_init("-machine kudo-bmc");
141
+ uint64_t addr = NPCM7XX_MMC_BA;
142
+ uint64_t end_addr = addr + NPCM7XX_REG_SIZE;
143
+ uint16_t prstvals_resets[] = {NPCM7XX_PRSTVALS_0_RESET,
144
+ NPCM7XX_PRSTVALS_1_RESET,
145
+ 0,
146
+ NPCM7XX_PRSTVALS_3_RESET,
147
+ 0,
148
+ 0};
149
+ int i;
150
+ uint32_t mask;
151
+
152
+ while (addr < end_addr) {
153
+ switch (addr - NPCM7XX_MMC_BA) {
154
+ case SDHC_PRNSTS:
155
+ /*
156
+ * ignores bits 20 to 24: they are changed when reading registers
157
+ */
158
+ mask = 0x1f00000;
159
+ g_assert_cmphex(qtest_readl(qts, addr) | mask, ==,
160
+ NPCM7XX_PRSNTS_RESET | mask);
161
+ addr += 4;
162
+ break;
163
+ case SDHC_BLKGAP:
164
+ g_assert_cmphex(qtest_readb(qts, addr), ==, NPCM7XX_BLKGAP_RESET);
165
+ addr += 1;
166
+ break;
167
+ case SDHC_CAPAB:
168
+ g_assert_cmphex(qtest_readq(qts, addr), ==, NPCM7XX_CAPAB_RESET);
169
+ addr += 8;
170
+ break;
171
+ case SDHC_MAXCURR:
172
+ g_assert_cmphex(qtest_readq(qts, addr), ==, NPCM7XX_MAXCURR_RESET);
173
+ addr += 8;
174
+ break;
175
+ case SDHC_HCVER:
176
+ g_assert_cmphex(qtest_readw(qts, addr), ==, NPCM7XX_HCVER_RESET);
177
+ addr += 2;
178
+ break;
179
+ case NPCM7XX_PRSTVALS:
180
+ for (i = 0; i < NPCM7XX_PRSTVALS_SIZE; ++i) {
181
+ g_assert_cmphex(qtest_readw(qts, addr + 2 * i), ==,
182
+ prstvals_resets[i]);
54
+ }
183
+ }
55
+ } else {
184
+ addr += NPCM7XX_PRSTVALS_SIZE * 2;
56
+ # Older Sphinx don't support documenting macros that take
185
+ break;
57
+ # arguments with c:macro, and don't complain about the use
186
+ default:
58
+ # of c:function for this.
187
+ g_assert_cmphex(qtest_readb(qts, addr), ==, 0);
59
+ print ".. c:function:: ";
188
+ addr += 1;
60
+ }
189
+ }
61
}
190
+ }
62
if ($args{'functiontype'} ne "") {
191
+
63
    $start .= $args{'functiontype'} . " " . $args{'function'} . " (";
192
+ qtest_quit(qts);
193
+}
194
+
195
+static void drive_destroy(void)
196
+{
197
+ unlink(sd_path);
198
+ g_free(sd_path);
199
+}
200
+
201
+static void drive_create(void)
202
+{
203
+ int fd, ret;
204
+ GError *error = NULL;
205
+
206
+ /* Create a temporary raw image */
207
+ fd = g_file_open_tmp("sdhci_XXXXXX", &sd_path, &error);
208
+ if (fd == -1) {
209
+ fprintf(stderr, "unable to create sdhci file: %s\n", error->message);
210
+ g_error_free(error);
211
+ }
212
+ g_assert(sd_path != NULL);
213
+
214
+ ret = ftruncate(fd, NPCM7XX_TEST_IMAGE_SIZE);
215
+ g_assert_cmpint(ret, ==, 0);
216
+ g_message("%s", sd_path);
217
+ close(fd);
218
+}
219
+
220
+int main(int argc, char **argv)
221
+{
222
+ int ret;
223
+
224
+ drive_create();
225
+
226
+ g_test_init(&argc, &argv, NULL);
227
+
228
+ qtest_add_func("npcm7xx_sdhci/reset", test_reset);
229
+ qtest_add_func("npcm7xx_sdhci/write_sd", test_write_sd);
230
+ qtest_add_func("npcm7xx_sdhci/read_sd", test_read_sd);
231
+
232
+ ret = g_test_run();
233
+ drive_destroy();
234
+ return ret;
235
+}
236
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
237
index XXXXXXX..XXXXXXX 100644
238
--- a/tests/qtest/meson.build
239
+++ b/tests/qtest/meson.build
240
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
241
'npcm7xx_gpio-test',
242
'npcm7xx_pwm-test',
243
'npcm7xx_rng-test',
244
+ 'npcm7xx_sdhci-test',
245
'npcm7xx_smbus-test',
246
'npcm7xx_timer-test',
247
'npcm7xx_watchdog_timer-test'] + \
64
--
248
--
65
2.20.1
249
2.25.1
66
67
diff view generated by jsdifflib
1
On some hosts (eg Ubuntu Bionic) pkg-config returns a set of
1
From: Richard Henderson <richard.henderson@linaro.org>
2
libraries for gio-2.0 which don't actually work when compiling
3
statically. (Specifically, the returned library string includes
4
-lmount, but not -lblkid which -lmount depends upon, so linking
5
fails due to missing symbols.)
6
2
7
Check that the libraries work, and don't enable gio if they don't,
3
Add new macros to manipulate signed fields within the register.
8
in the same way we do for gnutls.
9
4
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220301215958.157011-2-richard.henderson@linaro.org
8
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Message-id: 20200928160402.7961-1-peter.maydell@linaro.org
14
---
11
---
15
configure | 10 +++++++++-
12
include/hw/registerfields.h | 48 ++++++++++++++++++++++++++++++++++++-
16
1 file changed, 9 insertions(+), 1 deletion(-)
13
1 file changed, 47 insertions(+), 1 deletion(-)
17
14
18
diff --git a/configure b/configure
15
diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h
19
index XXXXXXX..XXXXXXX 100755
16
index XXXXXXX..XXXXXXX 100644
20
--- a/configure
17
--- a/include/hw/registerfields.h
21
+++ b/configure
18
+++ b/include/hw/registerfields.h
22
@@ -XXX,XX +XXX,XX @@ if test "$static" = yes && test "$mingw32" = yes; then
19
@@ -XXX,XX +XXX,XX @@
23
fi
20
extract64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
24
21
R_ ## reg ## _ ## field ## _LENGTH)
25
if $pkg_config --atleast-version=$glib_req_ver gio-2.0; then
22
26
- gio=yes
23
+#define FIELD_SEX8(storage, reg, field) \
27
gio_cflags=$($pkg_config --cflags gio-2.0)
24
+ sextract8((storage), R_ ## reg ## _ ## field ## _SHIFT, \
28
gio_libs=$($pkg_config --libs gio-2.0)
25
+ R_ ## reg ## _ ## field ## _LENGTH)
29
gdbus_codegen=$($pkg_config --variable=gdbus_codegen gio-2.0)
26
+#define FIELD_SEX16(storage, reg, field) \
30
if [ ! -x "$gdbus_codegen" ]; then
27
+ sextract16((storage), R_ ## reg ## _ ## field ## _SHIFT, \
31
gdbus_codegen=
28
+ R_ ## reg ## _ ## field ## _LENGTH)
32
fi
29
+#define FIELD_SEX32(storage, reg, field) \
33
+ # Check that the libraries actually work -- Ubuntu 18.04 ships
30
+ sextract32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
34
+ # with pkg-config --static --libs data for gio-2.0 that is missing
31
+ R_ ## reg ## _ ## field ## _LENGTH)
35
+ # -lblkid and will give a link error.
32
+#define FIELD_SEX64(storage, reg, field) \
36
+ write_c_skeleton
33
+ sextract64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
37
+ if compile_prog "" "gio_libs" ; then
34
+ R_ ## reg ## _ ## field ## _LENGTH)
38
+ gio=yes
35
+
39
+ else
36
/* Extract a field from an array of registers */
40
+ gio=no
37
#define ARRAY_FIELD_EX32(regs, reg, field) \
41
+ fi
38
FIELD_EX32((regs)[R_ ## reg], reg, field)
42
else
39
@@ -XXX,XX +XXX,XX @@
43
gio=no
40
_d; })
44
fi
41
#define FIELD_DP64(storage, reg, field, val) ({ \
42
struct { \
43
- uint64_t v:R_ ## reg ## _ ## field ## _LENGTH; \
44
+ uint64_t v:R_ ## reg ## _ ## field ## _LENGTH; \
45
+ } _v = { .v = val }; \
46
+ uint64_t _d; \
47
+ _d = deposit64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
48
+ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
49
+ _d; })
50
+
51
+#define FIELD_SDP8(storage, reg, field, val) ({ \
52
+ struct { \
53
+ signed int v:R_ ## reg ## _ ## field ## _LENGTH; \
54
+ } _v = { .v = val }; \
55
+ uint8_t _d; \
56
+ _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
57
+ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
58
+ _d; })
59
+#define FIELD_SDP16(storage, reg, field, val) ({ \
60
+ struct { \
61
+ signed int v:R_ ## reg ## _ ## field ## _LENGTH; \
62
+ } _v = { .v = val }; \
63
+ uint16_t _d; \
64
+ _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
65
+ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
66
+ _d; })
67
+#define FIELD_SDP32(storage, reg, field, val) ({ \
68
+ struct { \
69
+ signed int v:R_ ## reg ## _ ## field ## _LENGTH; \
70
+ } _v = { .v = val }; \
71
+ uint32_t _d; \
72
+ _d = deposit32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
73
+ R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
74
+ _d; })
75
+#define FIELD_SDP64(storage, reg, field, val) ({ \
76
+ struct { \
77
+ int64_t v:R_ ## reg ## _ ## field ## _LENGTH; \
78
} _v = { .v = val }; \
79
uint64_t _d; \
80
_d = deposit64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
45
--
81
--
46
2.20.1
82
2.25.1
47
83
48
84
diff view generated by jsdifflib
1
In arm_v7m_mmu_idx_for_secstate() we get the 'priv' level to pass to
1
From: Richard Henderson <richard.henderson@linaro.org>
2
armv7m_mmu_idx_for_secstate_and_priv() by calling arm_current_el().
3
This is incorrect when the security state being queried is not the
4
current one, because arm_current_el() uses the current security state
5
to determine which of the banked CONTROL.nPRIV bits to look at.
6
The effect was that if (for instance) Secure state was in privileged
7
mode but Non-Secure was not then we would return the wrong MMU index.
8
2
9
The only places where we are using this function in a way that could
3
Set this as the kernel would, to 48 bits, to keep the computation
10
trigger this bug are for the stack loads during a v8M function-return
4
of the address space correct for PAuth.
11
and for the instruction fetch of a v8M SG insn.
12
5
13
Fix the bug by expanding out the M-profile version of the
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
arm_current_el() logic inline so it can use the passed in secstate
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
rather than env->v7m.secure.
8
Message-id: 20220301215958.157011-3-richard.henderson@linaro.org
16
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20201022164408.13214-1-peter.maydell@linaro.org
20
---
10
---
21
target/arm/m_helper.c | 3 ++-
11
target/arm/cpu.c | 3 ++-
22
1 file changed, 2 insertions(+), 1 deletion(-)
12
1 file changed, 2 insertions(+), 1 deletion(-)
23
13
24
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/m_helper.c
16
--- a/target/arm/cpu.c
27
+++ b/target/arm/m_helper.c
17
+++ b/target/arm/cpu.c
28
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
29
/* Return the MMU index for a v7M CPU in the specified security state */
19
aarch64_sve_zcr_get_valid_len(cpu, cpu->sve_default_vq - 1);
30
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
20
}
31
{
21
/*
32
- bool priv = arm_current_el(env) != 0;
22
+ * Enable 48-bit address space (TODO: take reserved_va into account).
33
+ bool priv = arm_v7m_is_handler_mode(env) ||
23
* Enable TBI0 but not TBI1.
34
+ !(env->v7m.control[secstate] & 1);
24
* Note that this must match useronly_clean_ptr.
35
25
*/
36
return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
26
- env->cp15.tcr_el[1].raw_tcr = (1ULL << 37);
37
}
27
+ env->cp15.tcr_el[1].raw_tcr = 5 | (1ULL << 37);
28
29
/* Enable MTE */
30
if (cpu_isar_feature(aa64_mte, cpu)) {
38
--
31
--
39
2.20.1
32
2.25.1
40
41
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The only uses of this function are for loading VFP
3
Without FEAT_LVA, the behaviour of programming an invalid value
4
double-precision values, and nothing to do with NEON.
4
is IMPLEMENTATION DEFINED. With FEAT_LVA, programming an invalid
5
minimum value requires a Translation fault.
5
6
7
It is most self-consistent to choose to generate the fault always.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201030022618.785675-10-richard.henderson@linaro.org
11
Message-id: 20220301215958.157011-4-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
target/arm/translate.c | 8 ++--
14
target/arm/internals.h | 1 +
12
target/arm/translate-vfp.c.inc | 84 +++++++++++++++++-----------------
15
target/arm/helper.c | 32 ++++++++++++++++++++++++++++----
13
2 files changed, 46 insertions(+), 46 deletions(-)
16
2 files changed, 29 insertions(+), 4 deletions(-)
14
17
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
18
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
20
--- a/target/arm/internals.h
18
+++ b/target/arm/translate.c
21
+++ b/target/arm/internals.h
19
@@ -XXX,XX +XXX,XX @@ static long vfp_reg_offset(bool dp, unsigned reg)
22
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
23
bool hpd : 1;
24
bool using16k : 1;
25
bool using64k : 1;
26
+ bool tsz_oob : 1; /* tsz has been clamped to legal range */
27
} ARMVAParameters;
28
29
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.c
33
+++ b/target/arm/helper.c
34
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
35
ARMMMUIdx mmu_idx, bool data)
36
{
37
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
38
- bool epd, hpd, using16k, using64k;
39
- int select, tsz, tbi, max_tsz;
40
+ bool epd, hpd, using16k, using64k, tsz_oob;
41
+ int select, tsz, tbi, max_tsz, min_tsz;
42
43
if (!regime_has_2_ranges(mmu_idx)) {
44
select = 0;
45
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
46
} else {
47
max_tsz = 39;
20
}
48
}
49
+ min_tsz = 16; /* TODO: ARMv8.2-LVA */
50
51
- tsz = MIN(tsz, max_tsz);
52
- tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
53
+ if (tsz > max_tsz) {
54
+ tsz = max_tsz;
55
+ tsz_oob = true;
56
+ } else if (tsz < min_tsz) {
57
+ tsz = min_tsz;
58
+ tsz_oob = true;
59
+ } else {
60
+ tsz_oob = false;
61
+ }
62
63
/* Present TBI as a composite with TBID. */
64
tbi = aa64_va_parameter_tbi(tcr, mmu_idx);
65
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
66
.hpd = hpd,
67
.using16k = using16k,
68
.using64k = using64k,
69
+ .tsz_oob = tsz_oob,
70
};
21
}
71
}
22
72
23
-static inline void neon_load_reg64(TCGv_i64 var, int reg)
73
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
24
+static inline void vfp_load_reg64(TCGv_i64 var, int reg)
74
param = aa64_va_parameters(env, address, mmu_idx,
25
{
75
access_type != MMU_INST_FETCH);
26
- tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
76
level = 0;
27
+ tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(true, reg));
77
+
28
}
78
+ /*
29
79
+ * If TxSZ is programmed to a value larger than the maximum,
30
-static inline void neon_store_reg64(TCGv_i64 var, int reg)
80
+ * or smaller than the effective minimum, it is IMPLEMENTATION
31
+static inline void vfp_store_reg64(TCGv_i64 var, int reg)
81
+ * DEFINED whether we behave as if the field were programmed
32
{
82
+ * within bounds, or if a level 0 Translation fault is generated.
33
- tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
83
+ *
34
+ tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(true, reg));
84
+ * With FEAT_LVA, fault on less than minimum becomes required,
35
}
85
+ * so our choice is to always raise the fault.
36
86
+ */
37
static inline void vfp_load_reg32(TCGv_i32 var, int reg)
87
+ if (param.tsz_oob) {
38
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
88
+ fault_type = ARMFault_Translation;
39
index XXXXXXX..XXXXXXX 100644
89
+ goto do_fault;
40
--- a/target/arm/translate-vfp.c.inc
90
+ }
41
+++ b/target/arm/translate-vfp.c.inc
91
+
42
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
92
addrsize = 64 - 8 * param.tbi;
43
tcg_gen_ext_i32_i64(nf, cpu_NF);
93
inputsize = 64 - param.tsz;
44
tcg_gen_ext_i32_i64(vf, cpu_VF);
45
46
- neon_load_reg64(frn, rn);
47
- neon_load_reg64(frm, rm);
48
+ vfp_load_reg64(frn, rn);
49
+ vfp_load_reg64(frm, rm);
50
switch (a->cc) {
51
case 0: /* eq: Z */
52
tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
53
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
54
tcg_temp_free_i64(tmp);
55
break;
56
}
57
- neon_store_reg64(dest, rd);
58
+ vfp_store_reg64(dest, rd);
59
tcg_temp_free_i64(frn);
60
tcg_temp_free_i64(frm);
61
tcg_temp_free_i64(dest);
62
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
63
TCGv_i64 tcg_res;
64
tcg_op = tcg_temp_new_i64();
65
tcg_res = tcg_temp_new_i64();
66
- neon_load_reg64(tcg_op, rm);
67
+ vfp_load_reg64(tcg_op, rm);
68
gen_helper_rintd(tcg_res, tcg_op, fpst);
69
- neon_store_reg64(tcg_res, rd);
70
+ vfp_store_reg64(tcg_res, rd);
71
tcg_temp_free_i64(tcg_op);
72
tcg_temp_free_i64(tcg_res);
73
} else {
94
} else {
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
75
tcg_double = tcg_temp_new_i64();
76
tcg_res = tcg_temp_new_i64();
77
tcg_tmp = tcg_temp_new_i32();
78
- neon_load_reg64(tcg_double, rm);
79
+ vfp_load_reg64(tcg_double, rm);
80
if (is_signed) {
81
gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
82
} else {
83
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
84
tmp = tcg_temp_new_i64();
85
if (a->l) {
86
gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
87
- neon_store_reg64(tmp, a->vd);
88
+ vfp_store_reg64(tmp, a->vd);
89
} else {
90
- neon_load_reg64(tmp, a->vd);
91
+ vfp_load_reg64(tmp, a->vd);
92
gen_aa32_st64(s, tmp, addr, get_mem_index(s));
93
}
94
tcg_temp_free_i64(tmp);
95
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
96
if (a->l) {
97
/* load */
98
gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
99
- neon_store_reg64(tmp, a->vd + i);
100
+ vfp_store_reg64(tmp, a->vd + i);
101
} else {
102
/* store */
103
- neon_load_reg64(tmp, a->vd + i);
104
+ vfp_load_reg64(tmp, a->vd + i);
105
gen_aa32_st64(s, tmp, addr, get_mem_index(s));
106
}
107
tcg_gen_addi_i32(addr, addr, offset);
108
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
109
fd = tcg_temp_new_i64();
110
fpst = fpstatus_ptr(FPST_FPCR);
111
112
- neon_load_reg64(f0, vn);
113
- neon_load_reg64(f1, vm);
114
+ vfp_load_reg64(f0, vn);
115
+ vfp_load_reg64(f1, vm);
116
117
for (;;) {
118
if (reads_vd) {
119
- neon_load_reg64(fd, vd);
120
+ vfp_load_reg64(fd, vd);
121
}
122
fn(fd, f0, f1, fpst);
123
- neon_store_reg64(fd, vd);
124
+ vfp_store_reg64(fd, vd);
125
126
if (veclen == 0) {
127
break;
128
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
129
veclen--;
130
vd = vfp_advance_dreg(vd, delta_d);
131
vn = vfp_advance_dreg(vn, delta_d);
132
- neon_load_reg64(f0, vn);
133
+ vfp_load_reg64(f0, vn);
134
if (delta_m) {
135
vm = vfp_advance_dreg(vm, delta_m);
136
- neon_load_reg64(f1, vm);
137
+ vfp_load_reg64(f1, vm);
138
}
139
}
140
141
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
142
f0 = tcg_temp_new_i64();
143
fd = tcg_temp_new_i64();
144
145
- neon_load_reg64(f0, vm);
146
+ vfp_load_reg64(f0, vm);
147
148
for (;;) {
149
fn(fd, f0);
150
- neon_store_reg64(fd, vd);
151
+ vfp_store_reg64(fd, vd);
152
153
if (veclen == 0) {
154
break;
155
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
156
/* single source one-many */
157
while (veclen--) {
158
vd = vfp_advance_dreg(vd, delta_d);
159
- neon_store_reg64(fd, vd);
160
+ vfp_store_reg64(fd, vd);
161
}
162
break;
163
}
164
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
165
veclen--;
166
vd = vfp_advance_dreg(vd, delta_d);
167
vd = vfp_advance_dreg(vm, delta_m);
168
- neon_load_reg64(f0, vm);
169
+ vfp_load_reg64(f0, vm);
170
}
171
172
tcg_temp_free_i64(f0);
173
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
174
vm = tcg_temp_new_i64();
175
vd = tcg_temp_new_i64();
176
177
- neon_load_reg64(vn, a->vn);
178
- neon_load_reg64(vm, a->vm);
179
+ vfp_load_reg64(vn, a->vn);
180
+ vfp_load_reg64(vm, a->vm);
181
if (neg_n) {
182
/* VFNMS, VFMS */
183
gen_helper_vfp_negd(vn, vn);
184
}
185
- neon_load_reg64(vd, a->vd);
186
+ vfp_load_reg64(vd, a->vd);
187
if (neg_d) {
188
/* VFNMA, VFNMS */
189
gen_helper_vfp_negd(vd, vd);
190
}
191
fpst = fpstatus_ptr(FPST_FPCR);
192
gen_helper_vfp_muladdd(vd, vn, vm, vd, fpst);
193
- neon_store_reg64(vd, a->vd);
194
+ vfp_store_reg64(vd, a->vd);
195
196
tcg_temp_free_ptr(fpst);
197
tcg_temp_free_i64(vn);
198
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
199
fd = tcg_const_i64(vfp_expand_imm(MO_64, a->imm));
200
201
for (;;) {
202
- neon_store_reg64(fd, vd);
203
+ vfp_store_reg64(fd, vd);
204
205
if (veclen == 0) {
206
break;
207
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_dp(DisasContext *s, arg_VCMP_dp *a)
208
vd = tcg_temp_new_i64();
209
vm = tcg_temp_new_i64();
210
211
- neon_load_reg64(vd, a->vd);
212
+ vfp_load_reg64(vd, a->vd);
213
if (a->z) {
214
tcg_gen_movi_i64(vm, 0);
215
} else {
216
- neon_load_reg64(vm, a->vm);
217
+ vfp_load_reg64(vm, a->vm);
218
}
219
220
if (a->e) {
221
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
222
tcg_gen_ld16u_i32(tmp, cpu_env, vfp_f16_offset(a->vm, a->t));
223
vd = tcg_temp_new_i64();
224
gen_helper_vfp_fcvt_f16_to_f64(vd, tmp, fpst, ahp_mode);
225
- neon_store_reg64(vd, a->vd);
226
+ vfp_store_reg64(vd, a->vd);
227
tcg_temp_free_i32(ahp_mode);
228
tcg_temp_free_ptr(fpst);
229
tcg_temp_free_i32(tmp);
230
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
231
tmp = tcg_temp_new_i32();
232
vm = tcg_temp_new_i64();
233
234
- neon_load_reg64(vm, a->vm);
235
+ vfp_load_reg64(vm, a->vm);
236
gen_helper_vfp_fcvt_f64_to_f16(tmp, vm, fpst, ahp_mode);
237
tcg_temp_free_i64(vm);
238
tcg_gen_st16_i32(tmp, cpu_env, vfp_f16_offset(a->vd, a->t));
239
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
240
}
241
242
tmp = tcg_temp_new_i64();
243
- neon_load_reg64(tmp, a->vm);
244
+ vfp_load_reg64(tmp, a->vm);
245
fpst = fpstatus_ptr(FPST_FPCR);
246
gen_helper_rintd(tmp, tmp, fpst);
247
- neon_store_reg64(tmp, a->vd);
248
+ vfp_store_reg64(tmp, a->vd);
249
tcg_temp_free_ptr(fpst);
250
tcg_temp_free_i64(tmp);
251
return true;
252
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
253
}
254
255
tmp = tcg_temp_new_i64();
256
- neon_load_reg64(tmp, a->vm);
257
+ vfp_load_reg64(tmp, a->vm);
258
fpst = fpstatus_ptr(FPST_FPCR);
259
tcg_rmode = tcg_const_i32(float_round_to_zero);
260
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
261
gen_helper_rintd(tmp, tmp, fpst);
262
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
263
- neon_store_reg64(tmp, a->vd);
264
+ vfp_store_reg64(tmp, a->vd);
265
tcg_temp_free_ptr(fpst);
266
tcg_temp_free_i64(tmp);
267
tcg_temp_free_i32(tcg_rmode);
268
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
269
}
270
271
tmp = tcg_temp_new_i64();
272
- neon_load_reg64(tmp, a->vm);
273
+ vfp_load_reg64(tmp, a->vm);
274
fpst = fpstatus_ptr(FPST_FPCR);
275
gen_helper_rintd_exact(tmp, tmp, fpst);
276
- neon_store_reg64(tmp, a->vd);
277
+ vfp_store_reg64(tmp, a->vd);
278
tcg_temp_free_ptr(fpst);
279
tcg_temp_free_i64(tmp);
280
return true;
281
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
282
vd = tcg_temp_new_i64();
283
vfp_load_reg32(vm, a->vm);
284
gen_helper_vfp_fcvtds(vd, vm, cpu_env);
285
- neon_store_reg64(vd, a->vd);
286
+ vfp_store_reg64(vd, a->vd);
287
tcg_temp_free_i32(vm);
288
tcg_temp_free_i64(vd);
289
return true;
290
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
291
292
vd = tcg_temp_new_i32();
293
vm = tcg_temp_new_i64();
294
- neon_load_reg64(vm, a->vm);
295
+ vfp_load_reg64(vm, a->vm);
296
gen_helper_vfp_fcvtsd(vd, vm, cpu_env);
297
vfp_store_reg32(vd, a->vd);
298
tcg_temp_free_i32(vd);
299
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
300
/* u32 -> f64 */
301
gen_helper_vfp_uitod(vd, vm, fpst);
302
}
303
- neon_store_reg64(vd, a->vd);
304
+ vfp_store_reg64(vd, a->vd);
305
tcg_temp_free_i32(vm);
306
tcg_temp_free_i64(vd);
307
tcg_temp_free_ptr(fpst);
308
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
309
310
vm = tcg_temp_new_i64();
311
vd = tcg_temp_new_i32();
312
- neon_load_reg64(vm, a->vm);
313
+ vfp_load_reg64(vm, a->vm);
314
gen_helper_vjcvt(vd, vm, cpu_env);
315
vfp_store_reg32(vd, a->vd);
316
tcg_temp_free_i64(vm);
317
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
318
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
319
320
vd = tcg_temp_new_i64();
321
- neon_load_reg64(vd, a->vd);
322
+ vfp_load_reg64(vd, a->vd);
323
324
fpst = fpstatus_ptr(FPST_FPCR);
325
shift = tcg_const_i32(frac_bits);
326
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
327
g_assert_not_reached();
328
}
329
330
- neon_store_reg64(vd, a->vd);
331
+ vfp_store_reg64(vd, a->vd);
332
tcg_temp_free_i64(vd);
333
tcg_temp_free_i32(shift);
334
tcg_temp_free_ptr(fpst);
335
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
336
fpst = fpstatus_ptr(FPST_FPCR);
337
vm = tcg_temp_new_i64();
338
vd = tcg_temp_new_i32();
339
- neon_load_reg64(vm, a->vm);
340
+ vfp_load_reg64(vm, a->vm);
341
342
if (a->s) {
343
if (a->rz) {
344
--
95
--
345
2.20.1
96
2.25.1
346
347
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Replace all uses of neon_load/store_reg64 within translate-neon.c.inc.
3
We will shortly share parts of this function with other portions
4
of address translation.
4
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20201030022618.785675-9-richard.henderson@linaro.org
10
Message-id: 20220301215958.157011-5-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
12
---
10
target/arm/translate.c | 26 +++++++++
13
target/arm/internals.h | 19 +------------------
11
target/arm/translate-neon.c.inc | 94 ++++++++++++++++-----------------
14
target/arm/helper.c | 22 ++++++++++++++++++++++
12
2 files changed, 73 insertions(+), 47 deletions(-)
15
2 files changed, 23 insertions(+), 18 deletions(-)
13
16
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
19
--- a/target/arm/internals.h
17
+++ b/target/arm/translate.c
20
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
21
@@ -XXX,XX +XXX,XX @@ static inline void update_spsel(CPUARMState *env, uint32_t imm)
19
}
22
* Returns the implementation defined bit-width of physical addresses.
23
* The ARMv8 reference manuals refer to this as PAMax().
24
*/
25
-static inline unsigned int arm_pamax(ARMCPU *cpu)
26
-{
27
- static const unsigned int pamax_map[] = {
28
- [0] = 32,
29
- [1] = 36,
30
- [2] = 40,
31
- [3] = 42,
32
- [4] = 44,
33
- [5] = 48,
34
- };
35
- unsigned int parange =
36
- FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
37
-
38
- /* id_aa64mmfr0 is a read-only register so values outside of the
39
- * supported mappings can be considered an implementation error. */
40
- assert(parange < ARRAY_SIZE(pamax_map));
41
- return pamax_map[parange];
42
-}
43
+unsigned int arm_pamax(ARMCPU *cpu);
44
45
/* Return true if extended addresses are enabled.
46
* This is always the case if our translation regime is 64 bit,
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/helper.c
50
+++ b/target/arm/helper.c
51
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
20
}
52
}
21
53
#endif /* !CONFIG_USER_ONLY */
22
+static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
54
55
+/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
56
+unsigned int arm_pamax(ARMCPU *cpu)
23
+{
57
+{
24
+ long off = neon_element_offset(reg, ele, memop);
58
+ static const unsigned int pamax_map[] = {
59
+ [0] = 32,
60
+ [1] = 36,
61
+ [2] = 40,
62
+ [3] = 42,
63
+ [4] = 44,
64
+ [5] = 48,
65
+ };
66
+ unsigned int parange =
67
+ FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
25
+
68
+
26
+ switch (memop) {
69
+ /*
27
+ case MO_Q:
70
+ * id_aa64mmfr0 is a read-only register so values outside of the
28
+ tcg_gen_ld_i64(dest, cpu_env, off);
71
+ * supported mappings can be considered an implementation error.
29
+ break;
72
+ */
30
+ default:
73
+ assert(parange < ARRAY_SIZE(pamax_map));
31
+ g_assert_not_reached();
74
+ return pamax_map[parange];
32
+ }
33
+}
75
+}
34
+
76
+
35
static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
77
static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
36
{
78
{
37
long off = neon_element_offset(reg, ele, memop);
79
if (regime_has_2_ranges(mmu_idx)) {
38
@@ -XXX,XX +XXX,XX @@ static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
39
}
40
}
41
42
+static void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
43
+{
44
+ long off = neon_element_offset(reg, ele, memop);
45
+
46
+ switch (memop) {
47
+ case MO_64:
48
+ tcg_gen_st_i64(src, cpu_env, off);
49
+ break;
50
+ default:
51
+ g_assert_not_reached();
52
+ }
53
+}
54
+
55
static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
56
{
57
TCGv_ptr ret = tcg_temp_new_ptr();
58
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/translate-neon.c.inc
61
+++ b/target/arm/translate-neon.c.inc
62
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_64(DisasContext *s, arg_2reg_shift *a,
63
for (pass = 0; pass < a->q + 1; pass++) {
64
TCGv_i64 tmp = tcg_temp_new_i64();
65
66
- neon_load_reg64(tmp, a->vm + pass);
67
+ read_neon_element64(tmp, a->vm, pass, MO_64);
68
fn(tmp, cpu_env, tmp, constimm);
69
- neon_store_reg64(tmp, a->vd + pass);
70
+ write_neon_element64(tmp, a->vd, pass, MO_64);
71
tcg_temp_free_i64(tmp);
72
}
73
tcg_temp_free_i64(constimm);
74
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a,
75
rd = tcg_temp_new_i32();
76
77
/* Load both inputs first to avoid potential overwrite if rm == rd */
78
- neon_load_reg64(rm1, a->vm);
79
- neon_load_reg64(rm2, a->vm + 1);
80
+ read_neon_element64(rm1, a->vm, 0, MO_64);
81
+ read_neon_element64(rm2, a->vm, 1, MO_64);
82
83
shiftfn(rm1, rm1, constimm);
84
narrowfn(rd, cpu_env, rm1);
85
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
86
tcg_gen_shli_i64(tmp, tmp, a->shift);
87
tcg_gen_andi_i64(tmp, tmp, ~widen_mask);
88
}
89
- neon_store_reg64(tmp, a->vd);
90
+ write_neon_element64(tmp, a->vd, 0, MO_64);
91
92
widenfn(tmp, rm1);
93
tcg_temp_free_i32(rm1);
94
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
95
tcg_gen_shli_i64(tmp, tmp, a->shift);
96
tcg_gen_andi_i64(tmp, tmp, ~widen_mask);
97
}
98
- neon_store_reg64(tmp, a->vd + 1);
99
+ write_neon_element64(tmp, a->vd, 1, MO_64);
100
tcg_temp_free_i64(tmp);
101
return true;
102
}
103
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
104
rm_64 = tcg_temp_new_i64();
105
106
if (src1_wide) {
107
- neon_load_reg64(rn0_64, a->vn);
108
+ read_neon_element64(rn0_64, a->vn, 0, MO_64);
109
} else {
110
TCGv_i32 tmp = tcg_temp_new_i32();
111
read_neon_element32(tmp, a->vn, 0, MO_32);
112
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
113
* avoid incorrect results if a narrow input overlaps with the result.
114
*/
115
if (src1_wide) {
116
- neon_load_reg64(rn1_64, a->vn + 1);
117
+ read_neon_element64(rn1_64, a->vn, 1, MO_64);
118
} else {
119
TCGv_i32 tmp = tcg_temp_new_i32();
120
read_neon_element32(tmp, a->vn, 1, MO_32);
121
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
122
rm = tcg_temp_new_i32();
123
read_neon_element32(rm, a->vm, 1, MO_32);
124
125
- neon_store_reg64(rn0_64, a->vd);
126
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
127
128
widenfn(rm_64, rm);
129
tcg_temp_free_i32(rm);
130
opfn(rn1_64, rn1_64, rm_64);
131
- neon_store_reg64(rn1_64, a->vd + 1);
132
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
133
134
tcg_temp_free_i64(rn0_64);
135
tcg_temp_free_i64(rn1_64);
136
@@ -XXX,XX +XXX,XX @@ static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
137
rd0 = tcg_temp_new_i32();
138
rd1 = tcg_temp_new_i32();
139
140
- neon_load_reg64(rn_64, a->vn);
141
- neon_load_reg64(rm_64, a->vm);
142
+ read_neon_element64(rn_64, a->vn, 0, MO_64);
143
+ read_neon_element64(rm_64, a->vm, 0, MO_64);
144
145
opfn(rn_64, rn_64, rm_64);
146
147
narrowfn(rd0, rn_64);
148
149
- neon_load_reg64(rn_64, a->vn + 1);
150
- neon_load_reg64(rm_64, a->vm + 1);
151
+ read_neon_element64(rn_64, a->vn, 1, MO_64);
152
+ read_neon_element64(rm_64, a->vm, 1, MO_64);
153
154
opfn(rn_64, rn_64, rm_64);
155
156
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
157
/* Don't store results until after all loads: they might overlap */
158
if (accfn) {
159
tmp = tcg_temp_new_i64();
160
- neon_load_reg64(tmp, a->vd);
161
+ read_neon_element64(tmp, a->vd, 0, MO_64);
162
accfn(tmp, tmp, rd0);
163
- neon_store_reg64(tmp, a->vd);
164
- neon_load_reg64(tmp, a->vd + 1);
165
+ write_neon_element64(tmp, a->vd, 0, MO_64);
166
+ read_neon_element64(tmp, a->vd, 1, MO_64);
167
accfn(tmp, tmp, rd1);
168
- neon_store_reg64(tmp, a->vd + 1);
169
+ write_neon_element64(tmp, a->vd, 1, MO_64);
170
tcg_temp_free_i64(tmp);
171
} else {
172
- neon_store_reg64(rd0, a->vd);
173
- neon_store_reg64(rd1, a->vd + 1);
174
+ write_neon_element64(rd0, a->vd, 0, MO_64);
175
+ write_neon_element64(rd1, a->vd, 1, MO_64);
176
}
177
178
tcg_temp_free_i64(rd0);
179
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
180
181
if (accfn) {
182
TCGv_i64 t64 = tcg_temp_new_i64();
183
- neon_load_reg64(t64, a->vd);
184
+ read_neon_element64(t64, a->vd, 0, MO_64);
185
accfn(t64, t64, rn0_64);
186
- neon_store_reg64(t64, a->vd);
187
- neon_load_reg64(t64, a->vd + 1);
188
+ write_neon_element64(t64, a->vd, 0, MO_64);
189
+ read_neon_element64(t64, a->vd, 1, MO_64);
190
accfn(t64, t64, rn1_64);
191
- neon_store_reg64(t64, a->vd + 1);
192
+ write_neon_element64(t64, a->vd, 1, MO_64);
193
tcg_temp_free_i64(t64);
194
} else {
195
- neon_store_reg64(rn0_64, a->vd);
196
- neon_store_reg64(rn1_64, a->vd + 1);
197
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
198
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
199
}
200
tcg_temp_free_i64(rn0_64);
201
tcg_temp_free_i64(rn1_64);
202
@@ -XXX,XX +XXX,XX @@ static bool trans_VEXT(DisasContext *s, arg_VEXT *a)
203
right = tcg_temp_new_i64();
204
dest = tcg_temp_new_i64();
205
206
- neon_load_reg64(right, a->vn);
207
- neon_load_reg64(left, a->vm);
208
+ read_neon_element64(right, a->vn, 0, MO_64);
209
+ read_neon_element64(left, a->vm, 0, MO_64);
210
tcg_gen_extract2_i64(dest, right, left, a->imm * 8);
211
- neon_store_reg64(dest, a->vd);
212
+ write_neon_element64(dest, a->vd, 0, MO_64);
213
214
tcg_temp_free_i64(left);
215
tcg_temp_free_i64(right);
216
@@ -XXX,XX +XXX,XX @@ static bool trans_VEXT(DisasContext *s, arg_VEXT *a)
217
destright = tcg_temp_new_i64();
218
219
if (a->imm < 8) {
220
- neon_load_reg64(right, a->vn);
221
- neon_load_reg64(middle, a->vn + 1);
222
+ read_neon_element64(right, a->vn, 0, MO_64);
223
+ read_neon_element64(middle, a->vn, 1, MO_64);
224
tcg_gen_extract2_i64(destright, right, middle, a->imm * 8);
225
- neon_load_reg64(left, a->vm);
226
+ read_neon_element64(left, a->vm, 0, MO_64);
227
tcg_gen_extract2_i64(destleft, middle, left, a->imm * 8);
228
} else {
229
- neon_load_reg64(right, a->vn + 1);
230
- neon_load_reg64(middle, a->vm);
231
+ read_neon_element64(right, a->vn, 1, MO_64);
232
+ read_neon_element64(middle, a->vm, 0, MO_64);
233
tcg_gen_extract2_i64(destright, right, middle, (a->imm - 8) * 8);
234
- neon_load_reg64(left, a->vm + 1);
235
+ read_neon_element64(left, a->vm, 1, MO_64);
236
tcg_gen_extract2_i64(destleft, middle, left, (a->imm - 8) * 8);
237
}
238
239
- neon_store_reg64(destright, a->vd);
240
- neon_store_reg64(destleft, a->vd + 1);
241
+ write_neon_element64(destright, a->vd, 0, MO_64);
242
+ write_neon_element64(destleft, a->vd, 1, MO_64);
243
244
tcg_temp_free_i64(destright);
245
tcg_temp_free_i64(destleft);
246
@@ -XXX,XX +XXX,XX @@ static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
247
248
if (accfn) {
249
TCGv_i64 tmp64 = tcg_temp_new_i64();
250
- neon_load_reg64(tmp64, a->vd + pass);
251
+ read_neon_element64(tmp64, a->vd, pass, MO_64);
252
accfn(rd_64, tmp64, rd_64);
253
tcg_temp_free_i64(tmp64);
254
}
255
- neon_store_reg64(rd_64, a->vd + pass);
256
+ write_neon_element64(rd_64, a->vd, pass, MO_64);
257
tcg_temp_free_i64(rd_64);
258
}
259
return true;
260
@@ -XXX,XX +XXX,XX @@ static bool do_vmovn(DisasContext *s, arg_2misc *a,
261
rd0 = tcg_temp_new_i32();
262
rd1 = tcg_temp_new_i32();
263
264
- neon_load_reg64(rm, a->vm);
265
+ read_neon_element64(rm, a->vm, 0, MO_64);
266
narrowfn(rd0, cpu_env, rm);
267
- neon_load_reg64(rm, a->vm + 1);
268
+ read_neon_element64(rm, a->vm, 1, MO_64);
269
narrowfn(rd1, cpu_env, rm);
270
write_neon_element32(rd0, a->vd, 0, MO_32);
271
write_neon_element32(rd1, a->vd, 1, MO_32);
272
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
273
274
widenfn(rd, rm0);
275
tcg_gen_shli_i64(rd, rd, 8 << a->size);
276
- neon_store_reg64(rd, a->vd);
277
+ write_neon_element64(rd, a->vd, 0, MO_64);
278
widenfn(rd, rm1);
279
tcg_gen_shli_i64(rd, rd, 8 << a->size);
280
- neon_store_reg64(rd, a->vd + 1);
281
+ write_neon_element64(rd, a->vd, 1, MO_64);
282
283
tcg_temp_free_i64(rd);
284
tcg_temp_free_i32(rm0);
285
@@ -XXX,XX +XXX,XX @@ static bool trans_VSWP(DisasContext *s, arg_2misc *a)
286
rm = tcg_temp_new_i64();
287
rd = tcg_temp_new_i64();
288
for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
289
- neon_load_reg64(rm, a->vm + pass);
290
- neon_load_reg64(rd, a->vd + pass);
291
- neon_store_reg64(rm, a->vd + pass);
292
- neon_store_reg64(rd, a->vm + pass);
293
+ read_neon_element64(rm, a->vm, pass, MO_64);
294
+ read_neon_element64(rd, a->vd, pass, MO_64);
295
+ write_neon_element64(rm, a->vd, pass, MO_64);
296
+ write_neon_element64(rd, a->vm, pass, MO_64);
297
}
298
tcg_temp_free_i64(rm);
299
tcg_temp_free_i64(rd);
300
--
80
--
301
2.20.1
81
2.25.1
302
82
303
83
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The only uses of this function are for loading VFP
3
Pass down the width of the output address from translation.
4
single-precision values, and nothing to do with NEON.
4
For now this is still just PAMax, but a subsequent patch will
5
compute the correct value from TCR_ELx.{I}PS.
5
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201030022618.785675-8-richard.henderson@linaro.org
9
Message-id: 20220301215958.157011-6-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/translate.c | 4 +-
12
target/arm/helper.c | 21 ++++++++++-----------
12
target/arm/translate-vfp.c.inc | 184 ++++++++++++++++-----------------
13
1 file changed, 10 insertions(+), 11 deletions(-)
13
2 files changed, 94 insertions(+), 94 deletions(-)
14
14
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
17
--- a/target/arm/helper.c
18
+++ b/target/arm/translate.c
18
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg64(TCGv_i64 var, int reg)
19
@@ -XXX,XX +XXX,XX @@ do_fault:
20
tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
20
* false otherwise.
21
}
21
*/
22
22
static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
23
-static inline void neon_load_reg32(TCGv_i32 var, int reg)
23
- int inputsize, int stride)
24
+static inline void vfp_load_reg32(TCGv_i32 var, int reg)
24
+ int inputsize, int stride, int outputsize)
25
{
25
{
26
tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
26
const int grainsize = stride + 3;
27
}
27
int startsizecheck;
28
28
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
29
-static inline void neon_store_reg32(TCGv_i32 var, int reg)
30
+static inline void vfp_store_reg32(TCGv_i32 var, int reg)
31
{
32
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
33
}
34
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-vfp.c.inc
37
+++ b/target/arm/translate-vfp.c.inc
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
39
frn = tcg_temp_new_i32();
40
frm = tcg_temp_new_i32();
41
dest = tcg_temp_new_i32();
42
- neon_load_reg32(frn, rn);
43
- neon_load_reg32(frm, rm);
44
+ vfp_load_reg32(frn, rn);
45
+ vfp_load_reg32(frm, rm);
46
switch (a->cc) {
47
case 0: /* eq: Z */
48
tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
49
@@ -XXX,XX +XXX,XX @@ static bool trans_VSEL(DisasContext *s, arg_VSEL *a)
50
if (sz == 1) {
51
tcg_gen_andi_i32(dest, dest, 0xffff);
52
}
53
- neon_store_reg32(dest, rd);
54
+ vfp_store_reg32(dest, rd);
55
tcg_temp_free_i32(frn);
56
tcg_temp_free_i32(frm);
57
tcg_temp_free_i32(dest);
58
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
59
TCGv_i32 tcg_res;
60
tcg_op = tcg_temp_new_i32();
61
tcg_res = tcg_temp_new_i32();
62
- neon_load_reg32(tcg_op, rm);
63
+ vfp_load_reg32(tcg_op, rm);
64
if (sz == 1) {
65
gen_helper_rinth(tcg_res, tcg_op, fpst);
66
} else {
67
gen_helper_rints(tcg_res, tcg_op, fpst);
68
}
69
- neon_store_reg32(tcg_res, rd);
70
+ vfp_store_reg32(tcg_res, rd);
71
tcg_temp_free_i32(tcg_op);
72
tcg_temp_free_i32(tcg_res);
73
}
29
}
74
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
30
75
gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
31
if (is_aa64) {
76
}
32
- CPUARMState *env = &cpu->env;
77
tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
33
- unsigned int pamax = arm_pamax(cpu);
78
- neon_store_reg32(tcg_tmp, rd);
34
-
79
+ vfp_store_reg32(tcg_tmp, rd);
35
switch (stride) {
80
tcg_temp_free_i32(tcg_tmp);
36
case 13: /* 64KB Pages. */
81
tcg_temp_free_i64(tcg_res);
37
- if (level == 0 || (level == 1 && pamax <= 42)) {
82
tcg_temp_free_i64(tcg_double);
38
+ if (level == 0 || (level == 1 && outputsize <= 42)) {
83
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
39
return false;
84
TCGv_i32 tcg_single, tcg_res;
85
tcg_single = tcg_temp_new_i32();
86
tcg_res = tcg_temp_new_i32();
87
- neon_load_reg32(tcg_single, rm);
88
+ vfp_load_reg32(tcg_single, rm);
89
if (sz == 1) {
90
if (is_signed) {
91
gen_helper_vfp_toslh(tcg_res, tcg_single, tcg_shift, fpst);
92
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
93
gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
94
}
95
}
96
- neon_store_reg32(tcg_res, rd);
97
+ vfp_store_reg32(tcg_res, rd);
98
tcg_temp_free_i32(tcg_res);
99
tcg_temp_free_i32(tcg_single);
100
}
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_half(DisasContext *s, arg_VMOV_single *a)
102
if (a->l) {
103
/* VFP to general purpose register */
104
tmp = tcg_temp_new_i32();
105
- neon_load_reg32(tmp, a->vn);
106
+ vfp_load_reg32(tmp, a->vn);
107
tcg_gen_andi_i32(tmp, tmp, 0xffff);
108
store_reg(s, a->rt, tmp);
109
} else {
110
/* general purpose register to VFP */
111
tmp = load_reg(s, a->rt);
112
tcg_gen_andi_i32(tmp, tmp, 0xffff);
113
- neon_store_reg32(tmp, a->vn);
114
+ vfp_store_reg32(tmp, a->vn);
115
tcg_temp_free_i32(tmp);
116
}
117
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
119
if (a->l) {
120
/* VFP to general purpose register */
121
tmp = tcg_temp_new_i32();
122
- neon_load_reg32(tmp, a->vn);
123
+ vfp_load_reg32(tmp, a->vn);
124
if (a->rt == 15) {
125
/* Set the 4 flag bits in the CPSR. */
126
gen_set_nzcv(tmp);
127
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
128
} else {
129
/* general purpose register to VFP */
130
tmp = load_reg(s, a->rt);
131
- neon_store_reg32(tmp, a->vn);
132
+ vfp_store_reg32(tmp, a->vn);
133
tcg_temp_free_i32(tmp);
134
}
135
136
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
137
if (a->op) {
138
/* fpreg to gpreg */
139
tmp = tcg_temp_new_i32();
140
- neon_load_reg32(tmp, a->vm);
141
+ vfp_load_reg32(tmp, a->vm);
142
store_reg(s, a->rt, tmp);
143
tmp = tcg_temp_new_i32();
144
- neon_load_reg32(tmp, a->vm + 1);
145
+ vfp_load_reg32(tmp, a->vm + 1);
146
store_reg(s, a->rt2, tmp);
147
} else {
148
/* gpreg to fpreg */
149
tmp = load_reg(s, a->rt);
150
- neon_store_reg32(tmp, a->vm);
151
+ vfp_store_reg32(tmp, a->vm);
152
tcg_temp_free_i32(tmp);
153
tmp = load_reg(s, a->rt2);
154
- neon_store_reg32(tmp, a->vm + 1);
155
+ vfp_store_reg32(tmp, a->vm + 1);
156
tcg_temp_free_i32(tmp);
157
}
158
159
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
160
if (a->op) {
161
/* fpreg to gpreg */
162
tmp = tcg_temp_new_i32();
163
- neon_load_reg32(tmp, a->vm * 2);
164
+ vfp_load_reg32(tmp, a->vm * 2);
165
store_reg(s, a->rt, tmp);
166
tmp = tcg_temp_new_i32();
167
- neon_load_reg32(tmp, a->vm * 2 + 1);
168
+ vfp_load_reg32(tmp, a->vm * 2 + 1);
169
store_reg(s, a->rt2, tmp);
170
} else {
171
/* gpreg to fpreg */
172
tmp = load_reg(s, a->rt);
173
- neon_store_reg32(tmp, a->vm * 2);
174
+ vfp_store_reg32(tmp, a->vm * 2);
175
tcg_temp_free_i32(tmp);
176
tmp = load_reg(s, a->rt2);
177
- neon_store_reg32(tmp, a->vm * 2 + 1);
178
+ vfp_store_reg32(tmp, a->vm * 2 + 1);
179
tcg_temp_free_i32(tmp);
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_hp(DisasContext *s, arg_VLDR_VSTR_sp *a)
183
tmp = tcg_temp_new_i32();
184
if (a->l) {
185
gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
186
- neon_store_reg32(tmp, a->vd);
187
+ vfp_store_reg32(tmp, a->vd);
188
} else {
189
- neon_load_reg32(tmp, a->vd);
190
+ vfp_load_reg32(tmp, a->vd);
191
gen_aa32_st16(s, tmp, addr, get_mem_index(s));
192
}
193
tcg_temp_free_i32(tmp);
194
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
195
tmp = tcg_temp_new_i32();
196
if (a->l) {
197
gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
198
- neon_store_reg32(tmp, a->vd);
199
+ vfp_store_reg32(tmp, a->vd);
200
} else {
201
- neon_load_reg32(tmp, a->vd);
202
+ vfp_load_reg32(tmp, a->vd);
203
gen_aa32_st32(s, tmp, addr, get_mem_index(s));
204
}
205
tcg_temp_free_i32(tmp);
206
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
207
if (a->l) {
208
/* load */
209
gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
210
- neon_store_reg32(tmp, a->vd + i);
211
+ vfp_store_reg32(tmp, a->vd + i);
212
} else {
213
/* store */
214
- neon_load_reg32(tmp, a->vd + i);
215
+ vfp_load_reg32(tmp, a->vd + i);
216
gen_aa32_st32(s, tmp, addr, get_mem_index(s));
217
}
218
tcg_gen_addi_i32(addr, addr, offset);
219
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
220
fd = tcg_temp_new_i32();
221
fpst = fpstatus_ptr(FPST_FPCR);
222
223
- neon_load_reg32(f0, vn);
224
- neon_load_reg32(f1, vm);
225
+ vfp_load_reg32(f0, vn);
226
+ vfp_load_reg32(f1, vm);
227
228
for (;;) {
229
if (reads_vd) {
230
- neon_load_reg32(fd, vd);
231
+ vfp_load_reg32(fd, vd);
232
}
233
fn(fd, f0, f1, fpst);
234
- neon_store_reg32(fd, vd);
235
+ vfp_store_reg32(fd, vd);
236
237
if (veclen == 0) {
238
break;
239
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
240
veclen--;
241
vd = vfp_advance_sreg(vd, delta_d);
242
vn = vfp_advance_sreg(vn, delta_d);
243
- neon_load_reg32(f0, vn);
244
+ vfp_load_reg32(f0, vn);
245
if (delta_m) {
246
vm = vfp_advance_sreg(vm, delta_m);
247
- neon_load_reg32(f1, vm);
248
+ vfp_load_reg32(f1, vm);
249
}
250
}
251
252
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_3op_hp(DisasContext *s, VFPGen3OpSPFn *fn,
253
fd = tcg_temp_new_i32();
254
fpst = fpstatus_ptr(FPST_FPCR_F16);
255
256
- neon_load_reg32(f0, vn);
257
- neon_load_reg32(f1, vm);
258
+ vfp_load_reg32(f0, vn);
259
+ vfp_load_reg32(f1, vm);
260
261
if (reads_vd) {
262
- neon_load_reg32(fd, vd);
263
+ vfp_load_reg32(fd, vd);
264
}
265
fn(fd, f0, f1, fpst);
266
- neon_store_reg32(fd, vd);
267
+ vfp_store_reg32(fd, vd);
268
269
tcg_temp_free_i32(f0);
270
tcg_temp_free_i32(f1);
271
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
272
f0 = tcg_temp_new_i32();
273
fd = tcg_temp_new_i32();
274
275
- neon_load_reg32(f0, vm);
276
+ vfp_load_reg32(f0, vm);
277
278
for (;;) {
279
fn(fd, f0);
280
- neon_store_reg32(fd, vd);
281
+ vfp_store_reg32(fd, vd);
282
283
if (veclen == 0) {
284
break;
285
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
286
/* single source one-many */
287
while (veclen--) {
288
vd = vfp_advance_sreg(vd, delta_d);
289
- neon_store_reg32(fd, vd);
290
+ vfp_store_reg32(fd, vd);
291
}
40
}
292
break;
41
break;
42
case 11: /* 16KB Pages. */
43
- if (level == 0 || (level == 1 && pamax <= 40)) {
44
+ if (level == 0 || (level == 1 && outputsize <= 40)) {
45
return false;
46
}
47
break;
48
case 9: /* 4KB Pages. */
49
- if (level == 0 && pamax <= 42) {
50
+ if (level == 0 && outputsize <= 42) {
51
return false;
52
}
53
break;
54
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
293
}
55
}
294
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
56
295
veclen--;
57
/* Inputsize checks. */
296
vd = vfp_advance_sreg(vd, delta_d);
58
- if (inputsize > pamax &&
297
vm = vfp_advance_sreg(vm, delta_m);
59
- (arm_el_is_aa64(env, 1) || inputsize > 40)) {
298
- neon_load_reg32(f0, vm);
60
+ if (inputsize > outputsize &&
299
+ vfp_load_reg32(f0, vm);
61
+ (arm_el_is_aa64(&cpu->env, 1) || inputsize > 40)) {
62
/* This is CONSTRAINED UNPREDICTABLE and we choose to fault. */
63
return false;
64
}
65
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
66
target_ulong page_size;
67
uint32_t attrs;
68
int32_t stride;
69
- int addrsize, inputsize;
70
+ int addrsize, inputsize, outputsize;
71
TCR *tcr = regime_tcr(env, mmu_idx);
72
int ap, ns, xn, pxn;
73
uint32_t el = regime_el(env, mmu_idx);
74
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
75
76
addrsize = 64 - 8 * param.tbi;
77
inputsize = 64 - param.tsz;
78
+ outputsize = arm_pamax(cpu);
79
} else {
80
param = aa32_va_parameters(env, address, mmu_idx);
81
level = 1;
82
addrsize = (mmu_idx == ARMMMUIdx_Stage2 ? 40 : 32);
83
inputsize = addrsize - param.tsz;
84
+ outputsize = 40;
300
}
85
}
301
86
302
tcg_temp_free_i32(f0);
87
/*
303
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_hp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
88
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
304
}
89
305
90
/* Check that the starting level is valid. */
306
f0 = tcg_temp_new_i32();
91
ok = check_s2_mmu_setup(cpu, aarch64, startlevel,
307
- neon_load_reg32(f0, vm);
92
- inputsize, stride);
308
+ vfp_load_reg32(f0, vm);
93
+ inputsize, stride, outputsize);
309
fn(f0, f0);
94
if (!ok) {
310
- neon_store_reg32(f0, vd);
95
fault_type = ARMFault_Translation;
311
+ vfp_store_reg32(f0, vd);
96
goto do_fault;
312
tcg_temp_free_i32(f0);
313
314
return true;
315
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_hp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
316
vm = tcg_temp_new_i32();
317
vd = tcg_temp_new_i32();
318
319
- neon_load_reg32(vn, a->vn);
320
- neon_load_reg32(vm, a->vm);
321
+ vfp_load_reg32(vn, a->vn);
322
+ vfp_load_reg32(vm, a->vm);
323
if (neg_n) {
324
/* VFNMS, VFMS */
325
gen_helper_vfp_negh(vn, vn);
326
}
327
- neon_load_reg32(vd, a->vd);
328
+ vfp_load_reg32(vd, a->vd);
329
if (neg_d) {
330
/* VFNMA, VFNMS */
331
gen_helper_vfp_negh(vd, vd);
332
}
333
fpst = fpstatus_ptr(FPST_FPCR_F16);
334
gen_helper_vfp_muladdh(vd, vn, vm, vd, fpst);
335
- neon_store_reg32(vd, a->vd);
336
+ vfp_store_reg32(vd, a->vd);
337
338
tcg_temp_free_ptr(fpst);
339
tcg_temp_free_i32(vn);
340
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_sp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
341
vm = tcg_temp_new_i32();
342
vd = tcg_temp_new_i32();
343
344
- neon_load_reg32(vn, a->vn);
345
- neon_load_reg32(vm, a->vm);
346
+ vfp_load_reg32(vn, a->vn);
347
+ vfp_load_reg32(vm, a->vm);
348
if (neg_n) {
349
/* VFNMS, VFMS */
350
gen_helper_vfp_negs(vn, vn);
351
}
352
- neon_load_reg32(vd, a->vd);
353
+ vfp_load_reg32(vd, a->vd);
354
if (neg_d) {
355
/* VFNMA, VFNMS */
356
gen_helper_vfp_negs(vd, vd);
357
}
358
fpst = fpstatus_ptr(FPST_FPCR);
359
gen_helper_vfp_muladds(vd, vn, vm, vd, fpst);
360
- neon_store_reg32(vd, a->vd);
361
+ vfp_store_reg32(vd, a->vd);
362
363
tcg_temp_free_ptr(fpst);
364
tcg_temp_free_i32(vn);
365
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_hp(DisasContext *s, arg_VMOV_imm_sp *a)
366
}
367
368
fd = tcg_const_i32(vfp_expand_imm(MO_16, a->imm));
369
- neon_store_reg32(fd, a->vd);
370
+ vfp_store_reg32(fd, a->vd);
371
tcg_temp_free_i32(fd);
372
return true;
373
}
374
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_sp(DisasContext *s, arg_VMOV_imm_sp *a)
375
fd = tcg_const_i32(vfp_expand_imm(MO_32, a->imm));
376
377
for (;;) {
378
- neon_store_reg32(fd, vd);
379
+ vfp_store_reg32(fd, vd);
380
381
if (veclen == 0) {
382
break;
383
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_hp(DisasContext *s, arg_VCMP_sp *a)
384
vd = tcg_temp_new_i32();
385
vm = tcg_temp_new_i32();
386
387
- neon_load_reg32(vd, a->vd);
388
+ vfp_load_reg32(vd, a->vd);
389
if (a->z) {
390
tcg_gen_movi_i32(vm, 0);
391
} else {
392
- neon_load_reg32(vm, a->vm);
393
+ vfp_load_reg32(vm, a->vm);
394
}
395
396
if (a->e) {
397
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMP_sp(DisasContext *s, arg_VCMP_sp *a)
398
vd = tcg_temp_new_i32();
399
vm = tcg_temp_new_i32();
400
401
- neon_load_reg32(vd, a->vd);
402
+ vfp_load_reg32(vd, a->vd);
403
if (a->z) {
404
tcg_gen_movi_i32(vm, 0);
405
} else {
406
- neon_load_reg32(vm, a->vm);
407
+ vfp_load_reg32(vm, a->vm);
408
}
409
410
if (a->e) {
411
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f32_f16(DisasContext *s, arg_VCVT_f32_f16 *a)
412
/* The T bit tells us if we want the low or high 16 bits of Vm */
413
tcg_gen_ld16u_i32(tmp, cpu_env, vfp_f16_offset(a->vm, a->t));
414
gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp_mode);
415
- neon_store_reg32(tmp, a->vd);
416
+ vfp_store_reg32(tmp, a->vd);
417
tcg_temp_free_i32(ahp_mode);
418
tcg_temp_free_ptr(fpst);
419
tcg_temp_free_i32(tmp);
420
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f16_f32(DisasContext *s, arg_VCVT_f16_f32 *a)
421
ahp_mode = get_ahp_flag();
422
tmp = tcg_temp_new_i32();
423
424
- neon_load_reg32(tmp, a->vm);
425
+ vfp_load_reg32(tmp, a->vm);
426
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp_mode);
427
tcg_gen_st16_i32(tmp, cpu_env, vfp_f16_offset(a->vd, a->t));
428
tcg_temp_free_i32(ahp_mode);
429
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_hp(DisasContext *s, arg_VRINTR_sp *a)
430
}
431
432
tmp = tcg_temp_new_i32();
433
- neon_load_reg32(tmp, a->vm);
434
+ vfp_load_reg32(tmp, a->vm);
435
fpst = fpstatus_ptr(FPST_FPCR_F16);
436
gen_helper_rinth(tmp, tmp, fpst);
437
- neon_store_reg32(tmp, a->vd);
438
+ vfp_store_reg32(tmp, a->vd);
439
tcg_temp_free_ptr(fpst);
440
tcg_temp_free_i32(tmp);
441
return true;
442
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTR_sp(DisasContext *s, arg_VRINTR_sp *a)
443
}
444
445
tmp = tcg_temp_new_i32();
446
- neon_load_reg32(tmp, a->vm);
447
+ vfp_load_reg32(tmp, a->vm);
448
fpst = fpstatus_ptr(FPST_FPCR);
449
gen_helper_rints(tmp, tmp, fpst);
450
- neon_store_reg32(tmp, a->vd);
451
+ vfp_store_reg32(tmp, a->vd);
452
tcg_temp_free_ptr(fpst);
453
tcg_temp_free_i32(tmp);
454
return true;
455
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_hp(DisasContext *s, arg_VRINTZ_sp *a)
456
}
457
458
tmp = tcg_temp_new_i32();
459
- neon_load_reg32(tmp, a->vm);
460
+ vfp_load_reg32(tmp, a->vm);
461
fpst = fpstatus_ptr(FPST_FPCR_F16);
462
tcg_rmode = tcg_const_i32(float_round_to_zero);
463
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
464
gen_helper_rinth(tmp, tmp, fpst);
465
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
466
- neon_store_reg32(tmp, a->vd);
467
+ vfp_store_reg32(tmp, a->vd);
468
tcg_temp_free_ptr(fpst);
469
tcg_temp_free_i32(tcg_rmode);
470
tcg_temp_free_i32(tmp);
471
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTZ_sp(DisasContext *s, arg_VRINTZ_sp *a)
472
}
473
474
tmp = tcg_temp_new_i32();
475
- neon_load_reg32(tmp, a->vm);
476
+ vfp_load_reg32(tmp, a->vm);
477
fpst = fpstatus_ptr(FPST_FPCR);
478
tcg_rmode = tcg_const_i32(float_round_to_zero);
479
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
480
gen_helper_rints(tmp, tmp, fpst);
481
gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
482
- neon_store_reg32(tmp, a->vd);
483
+ vfp_store_reg32(tmp, a->vd);
484
tcg_temp_free_ptr(fpst);
485
tcg_temp_free_i32(tcg_rmode);
486
tcg_temp_free_i32(tmp);
487
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_hp(DisasContext *s, arg_VRINTX_sp *a)
488
}
489
490
tmp = tcg_temp_new_i32();
491
- neon_load_reg32(tmp, a->vm);
492
+ vfp_load_reg32(tmp, a->vm);
493
fpst = fpstatus_ptr(FPST_FPCR_F16);
494
gen_helper_rinth_exact(tmp, tmp, fpst);
495
- neon_store_reg32(tmp, a->vd);
496
+ vfp_store_reg32(tmp, a->vd);
497
tcg_temp_free_ptr(fpst);
498
tcg_temp_free_i32(tmp);
499
return true;
500
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX_sp(DisasContext *s, arg_VRINTX_sp *a)
501
}
502
503
tmp = tcg_temp_new_i32();
504
- neon_load_reg32(tmp, a->vm);
505
+ vfp_load_reg32(tmp, a->vm);
506
fpst = fpstatus_ptr(FPST_FPCR);
507
gen_helper_rints_exact(tmp, tmp, fpst);
508
- neon_store_reg32(tmp, a->vd);
509
+ vfp_store_reg32(tmp, a->vd);
510
tcg_temp_free_ptr(fpst);
511
tcg_temp_free_i32(tmp);
512
return true;
513
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
514
515
vm = tcg_temp_new_i32();
516
vd = tcg_temp_new_i64();
517
- neon_load_reg32(vm, a->vm);
518
+ vfp_load_reg32(vm, a->vm);
519
gen_helper_vfp_fcvtds(vd, vm, cpu_env);
520
neon_store_reg64(vd, a->vd);
521
tcg_temp_free_i32(vm);
522
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
523
vm = tcg_temp_new_i64();
524
neon_load_reg64(vm, a->vm);
525
gen_helper_vfp_fcvtsd(vd, vm, cpu_env);
526
- neon_store_reg32(vd, a->vd);
527
+ vfp_store_reg32(vd, a->vd);
528
tcg_temp_free_i32(vd);
529
tcg_temp_free_i64(vm);
530
return true;
531
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_hp(DisasContext *s, arg_VCVT_int_sp *a)
532
}
533
534
vm = tcg_temp_new_i32();
535
- neon_load_reg32(vm, a->vm);
536
+ vfp_load_reg32(vm, a->vm);
537
fpst = fpstatus_ptr(FPST_FPCR_F16);
538
if (a->s) {
539
/* i32 -> f16 */
540
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_hp(DisasContext *s, arg_VCVT_int_sp *a)
541
/* u32 -> f16 */
542
gen_helper_vfp_uitoh(vm, vm, fpst);
543
}
544
- neon_store_reg32(vm, a->vd);
545
+ vfp_store_reg32(vm, a->vd);
546
tcg_temp_free_i32(vm);
547
tcg_temp_free_ptr(fpst);
548
return true;
549
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
550
}
551
552
vm = tcg_temp_new_i32();
553
- neon_load_reg32(vm, a->vm);
554
+ vfp_load_reg32(vm, a->vm);
555
fpst = fpstatus_ptr(FPST_FPCR);
556
if (a->s) {
557
/* i32 -> f32 */
558
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
559
/* u32 -> f32 */
560
gen_helper_vfp_uitos(vm, vm, fpst);
561
}
562
- neon_store_reg32(vm, a->vd);
563
+ vfp_store_reg32(vm, a->vd);
564
tcg_temp_free_i32(vm);
565
tcg_temp_free_ptr(fpst);
566
return true;
567
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
568
569
vm = tcg_temp_new_i32();
570
vd = tcg_temp_new_i64();
571
- neon_load_reg32(vm, a->vm);
572
+ vfp_load_reg32(vm, a->vm);
573
fpst = fpstatus_ptr(FPST_FPCR);
574
if (a->s) {
575
/* i32 -> f64 */
576
@@ -XXX,XX +XXX,XX @@ static bool trans_VJCVT(DisasContext *s, arg_VJCVT *a)
577
vd = tcg_temp_new_i32();
578
neon_load_reg64(vm, a->vm);
579
gen_helper_vjcvt(vd, vm, cpu_env);
580
- neon_store_reg32(vd, a->vd);
581
+ vfp_store_reg32(vd, a->vd);
582
tcg_temp_free_i64(vm);
583
tcg_temp_free_i32(vd);
584
return true;
585
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
586
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
587
588
vd = tcg_temp_new_i32();
589
- neon_load_reg32(vd, a->vd);
590
+ vfp_load_reg32(vd, a->vd);
591
592
fpst = fpstatus_ptr(FPST_FPCR_F16);
593
shift = tcg_const_i32(frac_bits);
594
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
595
g_assert_not_reached();
596
}
597
598
- neon_store_reg32(vd, a->vd);
599
+ vfp_store_reg32(vd, a->vd);
600
tcg_temp_free_i32(vd);
601
tcg_temp_free_i32(shift);
602
tcg_temp_free_ptr(fpst);
603
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
604
frac_bits = (a->opc & 1) ? (32 - a->imm) : (16 - a->imm);
605
606
vd = tcg_temp_new_i32();
607
- neon_load_reg32(vd, a->vd);
608
+ vfp_load_reg32(vd, a->vd);
609
610
fpst = fpstatus_ptr(FPST_FPCR);
611
shift = tcg_const_i32(frac_bits);
612
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
613
g_assert_not_reached();
614
}
615
616
- neon_store_reg32(vd, a->vd);
617
+ vfp_store_reg32(vd, a->vd);
618
tcg_temp_free_i32(vd);
619
tcg_temp_free_i32(shift);
620
tcg_temp_free_ptr(fpst);
621
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_hp_int(DisasContext *s, arg_VCVT_sp_int *a)
622
623
fpst = fpstatus_ptr(FPST_FPCR_F16);
624
vm = tcg_temp_new_i32();
625
- neon_load_reg32(vm, a->vm);
626
+ vfp_load_reg32(vm, a->vm);
627
628
if (a->s) {
629
if (a->rz) {
630
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_hp_int(DisasContext *s, arg_VCVT_sp_int *a)
631
gen_helper_vfp_touih(vm, vm, fpst);
632
}
633
}
634
- neon_store_reg32(vm, a->vd);
635
+ vfp_store_reg32(vm, a->vd);
636
tcg_temp_free_i32(vm);
637
tcg_temp_free_ptr(fpst);
638
return true;
639
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
640
641
fpst = fpstatus_ptr(FPST_FPCR);
642
vm = tcg_temp_new_i32();
643
- neon_load_reg32(vm, a->vm);
644
+ vfp_load_reg32(vm, a->vm);
645
646
if (a->s) {
647
if (a->rz) {
648
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
649
gen_helper_vfp_touis(vm, vm, fpst);
650
}
651
}
652
- neon_store_reg32(vm, a->vd);
653
+ vfp_store_reg32(vm, a->vd);
654
tcg_temp_free_i32(vm);
655
tcg_temp_free_ptr(fpst);
656
return true;
657
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
658
gen_helper_vfp_touid(vd, vm, fpst);
659
}
660
}
661
- neon_store_reg32(vd, a->vd);
662
+ vfp_store_reg32(vd, a->vd);
663
tcg_temp_free_i32(vd);
664
tcg_temp_free_i64(vm);
665
tcg_temp_free_ptr(fpst);
666
@@ -XXX,XX +XXX,XX @@ static bool trans_VINS(DisasContext *s, arg_VINS *a)
667
/* Insert low half of Vm into high half of Vd */
668
rm = tcg_temp_new_i32();
669
rd = tcg_temp_new_i32();
670
- neon_load_reg32(rm, a->vm);
671
- neon_load_reg32(rd, a->vd);
672
+ vfp_load_reg32(rm, a->vm);
673
+ vfp_load_reg32(rd, a->vd);
674
tcg_gen_deposit_i32(rd, rd, rm, 16, 16);
675
- neon_store_reg32(rd, a->vd);
676
+ vfp_store_reg32(rd, a->vd);
677
tcg_temp_free_i32(rm);
678
tcg_temp_free_i32(rd);
679
return true;
680
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOVX(DisasContext *s, arg_VINS *a)
681
682
/* Set Vd to high half of Vm */
683
rm = tcg_temp_new_i32();
684
- neon_load_reg32(rm, a->vm);
685
+ vfp_load_reg32(rm, a->vm);
686
tcg_gen_shri_i32(rm, rm, 16);
687
- neon_store_reg32(rm, a->vd);
688
+ vfp_store_reg32(rm, a->vd);
689
tcg_temp_free_i32(rm);
690
return true;
691
}
692
--
97
--
693
2.20.1
98
2.25.1
694
695
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use the BIT_ULL() macro to ensure we use 64-bit arithmetic.
3
The macro is a bit more readable than the inlined computation.
4
This fixes the following Coverity issue (OVERFLOW_BEFORE_WIDEN):
5
4
6
CID 1432363 (#1 of 1): Unintentional integer overflow:
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
overflow_before_widen:
7
Message-id: 20220301215958.157011-7-richard.henderson@linaro.org
9
Potentially overflowing expression 1 << scale with type int
10
(32 bits, signed) is evaluated using 32-bit arithmetic, and
11
then used in a context that expects an expression of type
12
hwaddr (64 bits, unsigned).
13
14
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Acked-by: Eric Auger <eric.auger@redhat.com>
16
Message-id: 20201030144617.1535064-1-philmd@redhat.com
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
9
---
20
hw/arm/smmuv3.c | 3 ++-
10
target/arm/helper.c | 4 ++--
21
1 file changed, 2 insertions(+), 1 deletion(-)
11
1 file changed, 2 insertions(+), 2 deletions(-)
22
12
23
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/smmuv3.c
15
--- a/target/arm/helper.c
26
+++ b/hw/arm/smmuv3.c
16
+++ b/target/arm/helper.c
27
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
28
*/
18
level = startlevel;
29
30
#include "qemu/osdep.h"
31
+#include "qemu/bitops.h"
32
#include "hw/irq.h"
33
#include "hw/sysbus.h"
34
#include "migration/vmstate.h"
35
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
36
scale = CMD_SCALE(cmd);
37
num = CMD_NUM(cmd);
38
ttl = CMD_TTL(cmd);
39
- num_pages = (num + 1) * (1 << (scale));
40
+ num_pages = (num + 1) * BIT_ULL(scale);
41
}
19
}
42
20
43
if (type == SMMU_CMD_TLBI_NH_VA) {
21
- indexmask_grainsize = (1ULL << (stride + 3)) - 1;
22
- indexmask = (1ULL << (inputsize - (stride * (4 - level)))) - 1;
23
+ indexmask_grainsize = MAKE_64BIT_MASK(0, stride + 3);
24
+ indexmask = MAKE_64BIT_MASK(0, inputsize - (stride * (4 - level)));
25
26
/* Now we can extract the actual base address from the TTBR */
27
descaddr = extract64(ttbr, 0, 48);
44
--
28
--
45
2.20.1
29
2.25.1
46
30
47
31
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
In both cases, we can sink the write-back and perform
3
This field controls the output (intermediate) physical address size
4
the accumulate into the normal destination temps.
4
of the translation process. V8 requires to raise an AddressSize
5
fault if the page tables are programmed incorrectly, such that any
6
intermediate descriptor address, or the final translated address,
7
is out of range.
5
8
9
Add a PS field to ARMVAParameters, and properly compute outputsize
10
in get_phys_addr_lpae. Test the descaddr as extracted from TTBR
11
and from page table entries.
12
13
Restrict descaddrmask so that we won't raise the fault for v7.
14
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201030022618.785675-11-richard.henderson@linaro.org
18
Message-id: 20220301215958.157011-8-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
20
---
11
target/arm/translate-neon.c.inc | 23 +++++++++--------------
21
target/arm/internals.h | 1 +
12
1 file changed, 9 insertions(+), 14 deletions(-)
22
target/arm/helper.c | 72 ++++++++++++++++++++++++++++++++----------
23
2 files changed, 57 insertions(+), 16 deletions(-)
13
24
14
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
25
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-neon.c.inc
27
--- a/target/arm/internals.h
17
+++ b/target/arm/translate-neon.c.inc
28
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
29
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
19
if (accfn) {
30
*/
20
tmp = tcg_temp_new_i64();
31
typedef struct ARMVAParameters {
21
read_neon_element64(tmp, a->vd, 0, MO_64);
32
unsigned tsz : 8;
22
- accfn(tmp, tmp, rd0);
33
+ unsigned ps : 3;
23
- write_neon_element64(tmp, a->vd, 0, MO_64);
34
unsigned select : 1;
24
+ accfn(rd0, tmp, rd0);
35
bool tbi : 1;
25
read_neon_element64(tmp, a->vd, 1, MO_64);
36
bool epd : 1;
26
- accfn(tmp, tmp, rd1);
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
27
- write_neon_element64(tmp, a->vd, 1, MO_64);
38
index XXXXXXX..XXXXXXX 100644
28
+ accfn(rd1, tmp, rd1);
39
--- a/target/arm/helper.c
29
tcg_temp_free_i64(tmp);
40
+++ b/target/arm/helper.c
30
- } else {
41
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
31
- write_neon_element64(rd0, a->vd, 0, MO_64);
42
}
32
- write_neon_element64(rd1, a->vd, 1, MO_64);
43
#endif /* !CONFIG_USER_ONLY */
44
45
+/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
46
+static const uint8_t pamax_map[] = {
47
+ [0] = 32,
48
+ [1] = 36,
49
+ [2] = 40,
50
+ [3] = 42,
51
+ [4] = 44,
52
+ [5] = 48,
53
+};
54
+
55
/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
56
unsigned int arm_pamax(ARMCPU *cpu)
57
{
58
- static const unsigned int pamax_map[] = {
59
- [0] = 32,
60
- [1] = 36,
61
- [2] = 40,
62
- [3] = 42,
63
- [4] = 44,
64
- [5] = 48,
65
- };
66
unsigned int parange =
67
FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
68
69
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
70
{
71
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
72
bool epd, hpd, using16k, using64k, tsz_oob;
73
- int select, tsz, tbi, max_tsz, min_tsz;
74
+ int select, tsz, tbi, max_tsz, min_tsz, ps;
75
76
if (!regime_has_2_ranges(mmu_idx)) {
77
select = 0;
78
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
79
hpd = extract32(tcr, 24, 1);
80
}
81
epd = false;
82
+ ps = extract32(tcr, 16, 3);
83
} else {
84
/*
85
* Bit 55 is always between the two regions, and is canonical for
86
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
87
epd = extract32(tcr, 23, 1);
88
hpd = extract64(tcr, 42, 1);
89
}
90
+ ps = extract64(tcr, 32, 3);
33
}
91
}
34
92
35
+ write_neon_element64(rd0, a->vd, 0, MO_64);
93
if (cpu_isar_feature(aa64_st, env_archcpu(env))) {
36
+ write_neon_element64(rd1, a->vd, 1, MO_64);
94
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
37
tcg_temp_free_i64(rd0);
95
38
tcg_temp_free_i64(rd1);
96
return (ARMVAParameters) {
39
97
.tsz = tsz,
40
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
98
+ .ps = ps,
41
if (accfn) {
99
.select = select,
42
TCGv_i64 t64 = tcg_temp_new_i64();
100
.tbi = tbi,
43
read_neon_element64(t64, a->vd, 0, MO_64);
101
.epd = epd,
44
- accfn(t64, t64, rn0_64);
102
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
45
- write_neon_element64(t64, a->vd, 0, MO_64);
103
46
+ accfn(rn0_64, t64, rn0_64);
104
/* TODO: This code does not support shareability levels. */
47
read_neon_element64(t64, a->vd, 1, MO_64);
105
if (aarch64) {
48
- accfn(t64, t64, rn1_64);
106
+ int ps;
49
- write_neon_element64(t64, a->vd, 1, MO_64);
50
+ accfn(rn1_64, t64, rn1_64);
51
tcg_temp_free_i64(t64);
52
- } else {
53
- write_neon_element64(rn0_64, a->vd, 0, MO_64);
54
- write_neon_element64(rn1_64, a->vd, 1, MO_64);
55
}
56
+
107
+
57
+ write_neon_element64(rn0_64, a->vd, 0, MO_64);
108
param = aa64_va_parameters(env, address, mmu_idx,
58
+ write_neon_element64(rn1_64, a->vd, 1, MO_64);
109
access_type != MMU_INST_FETCH);
59
tcg_temp_free_i64(rn0_64);
110
level = 0;
60
tcg_temp_free_i64(rn1_64);
111
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
61
return true;
112
113
addrsize = 64 - 8 * param.tbi;
114
inputsize = 64 - param.tsz;
115
- outputsize = arm_pamax(cpu);
116
+
117
+ /*
118
+ * Bound PS by PARANGE to find the effective output address size.
119
+ * ID_AA64MMFR0 is a read-only register so values outside of the
120
+ * supported mappings can be considered an implementation error.
121
+ */
122
+ ps = FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
123
+ ps = MIN(ps, param.ps);
124
+ assert(ps < ARRAY_SIZE(pamax_map));
125
+ outputsize = pamax_map[ps];
126
} else {
127
param = aa32_va_parameters(env, address, mmu_idx);
128
level = 1;
129
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
130
131
/* Now we can extract the actual base address from the TTBR */
132
descaddr = extract64(ttbr, 0, 48);
133
+
134
+ /*
135
+ * If the base address is out of range, raise AddressSizeFault.
136
+ * In the pseudocode, this is !IsZero(baseregister<47:outputsize>),
137
+ * but we've just cleared the bits above 47, so simplify the test.
138
+ */
139
+ if (descaddr >> outputsize) {
140
+ level = 0;
141
+ fault_type = ARMFault_AddressSize;
142
+ goto do_fault;
143
+ }
144
+
145
/*
146
* We rely on this masking to clear the RES0 bits at the bottom of the TTBR
147
* and also to mask out CnP (bit 0) which could validly be non-zero.
148
*/
149
descaddr &= ~indexmask;
150
151
- /* The address field in the descriptor goes up to bit 39 for ARMv7
152
- * but up to bit 47 for ARMv8, but we use the descaddrmask
153
- * up to bit 39 for AArch32, because we don't need other bits in that case
154
- * to construct next descriptor address (anyway they should be all zeroes).
155
+ /*
156
+ * For AArch32, the address field in the descriptor goes up to bit 39
157
+ * for both v7 and v8. However, for v8 the SBZ bits [47:40] must be 0
158
+ * or an AddressSize fault is raised. So for v8 we extract those SBZ
159
+ * bits as part of the address, which will be checked via outputsize.
160
+ * For AArch64, the address field always goes up to bit 47 (with extra
161
+ * bits for FEAT_LPA placed elsewhere). AArch64 implies v8.
162
*/
163
- descaddrmask = ((1ull << (aarch64 ? 48 : 40)) - 1) &
164
- ~indexmask_grainsize;
165
+ if (arm_feature(env, ARM_FEATURE_V8)) {
166
+ descaddrmask = MAKE_64BIT_MASK(0, 48);
167
+ } else {
168
+ descaddrmask = MAKE_64BIT_MASK(0, 40);
169
+ }
170
+ descaddrmask &= ~indexmask_grainsize;
171
172
/* Secure accesses start with the page table in secure memory and
173
* can be downgraded to non-secure at any step. Non-secure accesses
174
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
175
/* Invalid, or the Reserved level 3 encoding */
176
goto do_fault;
177
}
178
+
179
descaddr = descriptor & descaddrmask;
180
+ if (descaddr >> outputsize) {
181
+ fault_type = ARMFault_AddressSize;
182
+ goto do_fault;
183
+ }
184
185
if ((descriptor & 2) && (level < 3)) {
186
/* Table entry. The top five bits are attributes which may
62
--
187
--
63
2.20.1
188
2.25.1
64
189
65
190
diff view generated by jsdifflib
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Secure mode is not exempted from checking SCR_EL3.TLOR, and in the
3
The original A.a revision of the AArch64 ARM required that we
4
future HCR_EL2.TLOR when S-EL2 is enabled.
4
force-extend the addresses in these registers from 49 bits.
5
This language has been loosened via a combination of IMPLEMENTATION
6
DEFINED and CONSTRAINTED UNPREDICTABLE to allow consideration of
7
the entire aligned address.
5
8
6
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
9
This means that we do not have to consider whether or not FEAT_LVA
10
is enabled, and decide from which bit an address might need to be
11
extended.
12
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220301215958.157011-9-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
17
---
10
target/arm/helper.c | 19 +++++--------------
18
target/arm/helper.c | 32 ++++++++++++++++++++++++--------
11
1 file changed, 5 insertions(+), 14 deletions(-)
19
1 file changed, 24 insertions(+), 8 deletions(-)
12
20
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
23
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
24
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
25
@@ -XXX,XX +XXX,XX @@ static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
18
#endif
26
ARMCPU *cpu = env_archcpu(env);
19
27
int i = ri->crm;
20
/* Shared logic between LORID and the rest of the LOR* registers.
28
21
- * Secure state has already been delt with.
29
- /* Bits [63:49] are hardwired to the value of bit [48]; that is, the
22
+ * Secure state exclusion has already been dealt with.
30
- * register reads and behaves as if values written are sign extended.
23
*/
31
+ /*
24
-static CPAccessResult access_lor_ns(CPUARMState *env)
32
* Bits [1:0] are RES0.
25
+static CPAccessResult access_lor_ns(CPUARMState *env,
33
+ *
26
+ const ARMCPRegInfo *ri, bool isread)
34
+ * It is IMPLEMENTATION DEFINED whether [63:49] ([63:53] with FEAT_LVA)
27
{
35
+ * are hardwired to the value of bit [48] ([52] with FEAT_LVA), or if
28
int el = arm_current_el(env);
36
+ * they contain the value written. It is CONSTRAINED UNPREDICTABLE
29
37
+ * whether the RESS bits are ignored when comparing an address.
30
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_lor_ns(CPUARMState *env)
38
+ *
31
return CP_ACCESS_OK;
39
+ * Therefore we are allowed to compare the entire register, which lets
32
}
40
+ * us avoid considering whether or not FEAT_LVA is actually enabled.
33
41
*/
34
-static CPAccessResult access_lorid(CPUARMState *env, const ARMCPRegInfo *ri,
42
- value = sextract64(value, 0, 49) & ~3ULL;
35
- bool isread)
43
+ value &= ~3ULL;
36
-{
44
37
- if (arm_is_secure_below_el3(env)) {
45
raw_write(env, ri, value);
38
- /* Access ok in secure mode. */
46
hw_watchpoint_update(cpu, i);
39
- return CP_ACCESS_OK;
47
@@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update(ARMCPU *cpu, int n)
40
- }
48
case 0: /* unlinked address match */
41
- return access_lor_ns(env);
49
case 1: /* linked address match */
42
-}
50
{
43
-
51
- /* Bits [63:49] are hardwired to the value of bit [48]; that is,
44
static CPAccessResult access_lor_other(CPUARMState *env,
52
- * we behave as if the register was sign extended. Bits [1:0] are
45
const ARMCPRegInfo *ri, bool isread)
53
- * RES0. The BAS field is used to allow setting breakpoints on 16
46
{
54
- * bit wide instructions; it is CONSTRAINED UNPREDICTABLE whether
47
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_lor_other(CPUARMState *env,
55
+ /*
48
/* Access denied in secure mode. */
56
+ * Bits [1:0] are RES0.
49
return CP_ACCESS_TRAP;
57
+ *
50
}
58
+ * It is IMPLEMENTATION DEFINED whether bits [63:49]
51
- return access_lor_ns(env);
59
+ * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit
52
+ return access_lor_ns(env, ri, isread);
60
+ * of the VA field ([48] or [52] for FEAT_LVA), or whether the
53
}
61
+ * value is read as written. It is CONSTRAINED UNPREDICTABLE
54
62
+ * whether the RESS bits are ignored when comparing an address.
55
/*
63
+ * Therefore we are allowed to compare the entire register, which
56
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo lor_reginfo[] = {
64
+ * lets us avoid considering whether FEAT_LVA is actually enabled.
57
.type = ARM_CP_CONST, .resetvalue = 0 },
65
+ *
58
{ .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
66
+ * The BAS field is used to allow setting breakpoints on 16-bit
59
.opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
67
+ * wide instructions; it is CONSTRAINED UNPREDICTABLE whether
60
- .access = PL1_R, .accessfn = access_lorid,
68
* a bp will fire if the addresses covered by the bp and the addresses
61
+ .access = PL1_R, .accessfn = access_lor_ns,
69
* covered by the insn overlap but the insn doesn't start at the
62
.type = ARM_CP_CONST, .resetvalue = 0 },
70
* start of the bp address range. We choose to require the insn and
63
REGINFO_SENTINEL
71
@@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update(ARMCPU *cpu, int n)
64
};
72
* See also figure D2-3 in the v8 ARM ARM (DDI0487A.c).
73
*/
74
int bas = extract64(bcr, 5, 4);
75
- addr = sextract64(bvr, 0, 49) & ~3ULL;
76
+ addr = bvr & ~3ULL;
77
if (bas == 0) {
78
return;
79
}
65
--
80
--
66
2.20.1
81
2.25.1
67
68
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This will shortly have users outside of translate-neon.c.inc.
3
This feature is relatively small, as it applies only to
4
64k pages and thus requires no additional changes to the
5
table descriptor walking algorithm, only a change to the
6
minimum TSZ (which is the inverse of the maximum virtual
7
address space size).
4
8
9
Note that this feature widens VBAR_ELx, but we already
10
treat the register as being 64 bits wide.
11
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20201030022618.785675-3-richard.henderson@linaro.org
14
Message-id: 20220301215958.157011-10-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
16
---
10
target/arm/translate.c | 20 ++++++++++++++++++++
17
docs/system/arm/emulation.rst | 1 +
11
target/arm/translate-neon.c.inc | 19 -------------------
18
target/arm/cpu-param.h | 2 +-
12
2 files changed, 20 insertions(+), 19 deletions(-)
19
target/arm/cpu.h | 5 +++++
20
target/arm/cpu64.c | 1 +
21
target/arm/helper.c | 9 ++++++++-
22
5 files changed, 16 insertions(+), 2 deletions(-)
13
23
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
24
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
15
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
26
--- a/docs/system/arm/emulation.rst
17
+++ b/target/arm/translate.c
27
+++ b/docs/system/arm/emulation.rst
18
@@ -XXX,XX +XXX,XX @@ static long neon_full_reg_offset(unsigned reg)
28
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
19
return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
29
- FEAT_LRCPC (Load-acquire RCpc instructions)
30
- FEAT_LRCPC2 (Load-acquire RCpc instructions v2)
31
- FEAT_LSE (Large System Extensions)
32
+- FEAT_LVA (Large Virtual Address space)
33
- FEAT_MTE (Memory Tagging Extension)
34
- FEAT_MTE2 (Memory Tagging Extension)
35
- FEAT_MTE3 (MTE Asymmetric Fault Handling)
36
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/cpu-param.h
39
+++ b/target/arm/cpu-param.h
40
@@ -XXX,XX +XXX,XX @@
41
#ifdef TARGET_AARCH64
42
# define TARGET_LONG_BITS 64
43
# define TARGET_PHYS_ADDR_SPACE_BITS 48
44
-# define TARGET_VIRT_ADDR_SPACE_BITS 48
45
+# define TARGET_VIRT_ADDR_SPACE_BITS 52
46
#else
47
# define TARGET_LONG_BITS 32
48
# define TARGET_PHYS_ADDR_SPACE_BITS 40
49
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/cpu.h
52
+++ b/target/arm/cpu.h
53
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
54
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
20
}
55
}
21
56
22
+/*
57
+static inline bool isar_feature_aa64_lva(const ARMISARegisters *id)
23
+ * Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
24
+ * where 0 is the least significant end of the register.
25
+ */
26
+static long neon_element_offset(int reg, int element, MemOp size)
27
+{
58
+{
28
+ int element_size = 1 << size;
59
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0;
29
+ int ofs = element * element_size;
30
+#ifdef HOST_WORDS_BIGENDIAN
31
+ /*
32
+ * Calculate the offset assuming fully little-endian,
33
+ * then XOR to account for the order of the 8-byte units.
34
+ */
35
+ if (element_size < 8) {
36
+ ofs ^= 8 - element_size;
37
+ }
38
+#endif
39
+ return neon_full_reg_offset(reg) + ofs;
40
+}
60
+}
41
+
61
+
42
static inline long vfp_reg_offset(bool dp, unsigned reg)
62
static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
43
{
63
{
44
if (dp) {
64
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
45
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
65
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
46
index XXXXXXX..XXXXXXX 100644
66
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/translate-neon.c.inc
67
--- a/target/arm/cpu64.c
48
+++ b/target/arm/translate-neon.c.inc
68
+++ b/target/arm/cpu64.c
49
@@ -XXX,XX +XXX,XX @@ static inline int neon_3same_fp_size(DisasContext *s, int x)
69
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
50
#include "decode-neon-ls.c.inc"
70
t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
51
#include "decode-neon-shared.c.inc"
71
t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */
52
72
t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* TTST */
53
-/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
73
+ t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
54
- * where 0 is the least significant end of the register.
74
cpu->isar.id_aa64mmfr2 = t;
55
- */
75
56
-static inline long
76
t = cpu->isar.id_aa64zfr0;
57
-neon_element_offset(int reg, int element, MemOp size)
77
diff --git a/target/arm/helper.c b/target/arm/helper.c
58
-{
78
index XXXXXXX..XXXXXXX 100644
59
- int element_size = 1 << size;
79
--- a/target/arm/helper.c
60
- int ofs = element * element_size;
80
+++ b/target/arm/helper.c
61
-#ifdef HOST_WORDS_BIGENDIAN
81
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
62
- /* Calculate the offset assuming fully little-endian,
82
} else {
63
- * then XOR to account for the order of the 8-byte units.
83
max_tsz = 39;
64
- */
84
}
65
- if (element_size < 8) {
85
- min_tsz = 16; /* TODO: ARMv8.2-LVA */
66
- ofs ^= 8 - element_size;
86
+
67
- }
87
+ min_tsz = 16;
68
-#endif
88
+ if (using64k) {
69
- return neon_full_reg_offset(reg) + ofs;
89
+ if (cpu_isar_feature(aa64_lva, env_archcpu(env))) {
70
-}
90
+ min_tsz = 12;
71
-
91
+ }
72
static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
92
+ }
73
{
93
+ /* TODO: FEAT_LPA2 */
74
long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
94
95
if (tsz > max_tsz) {
96
tsz = max_tsz;
75
--
97
--
76
2.20.1
98
2.25.1
77
78
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We can use proper widening loads to extend 32-bit inputs,
3
This feature widens physical addresses (and intermediate physical
4
and skip the "widenfn" step.
4
addresses for 2-stage translation) from 48 to 52 bits, when using
5
64k pages. The only thing left at this point is to handle the
6
extra bits in the TTBR and in the table descriptors.
5
7
8
Note that PAR_EL1 and HPFAR_EL2 are nominally extended, but we don't
9
mask out the high bits when writing to those registers, so no changes
10
are required there.
11
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20201030022618.785675-12-richard.henderson@linaro.org
14
Message-id: 20220301215958.157011-11-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
16
---
11
target/arm/translate.c | 6 +++
17
docs/system/arm/emulation.rst | 1 +
12
target/arm/translate-neon.c.inc | 66 ++++++++++++++++++---------------
18
target/arm/cpu-param.h | 2 +-
13
2 files changed, 43 insertions(+), 29 deletions(-)
19
target/arm/cpu64.c | 2 +-
20
target/arm/helper.c | 19 ++++++++++++++++---
21
4 files changed, 19 insertions(+), 5 deletions(-)
14
22
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
23
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
16
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
25
--- a/docs/system/arm/emulation.rst
18
+++ b/target/arm/translate.c
26
+++ b/docs/system/arm/emulation.rst
19
@@ -XXX,XX +XXX,XX @@ static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
27
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
20
long off = neon_element_offset(reg, ele, memop);
28
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
21
29
- FEAT_JSCVT (JavaScript conversion instructions)
22
switch (memop) {
30
- FEAT_LOR (Limited ordering regions)
23
+ case MO_SL:
31
+- FEAT_LPA (Large Physical Address space)
24
+ tcg_gen_ld32s_i64(dest, cpu_env, off);
32
- FEAT_LRCPC (Load-acquire RCpc instructions)
25
+ break;
33
- FEAT_LRCPC2 (Load-acquire RCpc instructions v2)
26
+ case MO_UL:
34
- FEAT_LSE (Large System Extensions)
27
+ tcg_gen_ld32u_i64(dest, cpu_env, off);
35
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
28
+ break;
29
case MO_Q:
30
tcg_gen_ld_i64(dest, cpu_env, off);
31
break;
32
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
33
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-neon.c.inc
37
--- a/target/arm/cpu-param.h
35
+++ b/target/arm/translate-neon.c.inc
38
+++ b/target/arm/cpu-param.h
36
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1reg_imm *a)
39
@@ -XXX,XX +XXX,XX @@
37
static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
40
38
NeonGenWidenFn *widenfn,
41
#ifdef TARGET_AARCH64
39
NeonGenTwo64OpFn *opfn,
42
# define TARGET_LONG_BITS 64
40
- bool src1_wide)
43
-# define TARGET_PHYS_ADDR_SPACE_BITS 48
41
+ int src1_mop, int src2_mop)
44
+# define TARGET_PHYS_ADDR_SPACE_BITS 52
42
{
45
# define TARGET_VIRT_ADDR_SPACE_BITS 52
43
/* 3-regs different lengths, prewidening case (VADDL/VSUBL/VAADW/VSUBW) */
46
#else
44
TCGv_i64 rn0_64, rn1_64, rm_64;
47
# define TARGET_LONG_BITS 32
45
- TCGv_i32 rm;
48
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
46
49
index XXXXXXX..XXXXXXX 100644
47
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
50
--- a/target/arm/cpu64.c
48
return false;
51
+++ b/target/arm/cpu64.c
49
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
52
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
50
return false;
53
cpu->isar.id_aa64pfr1 = t;
51
}
54
52
55
t = cpu->isar.id_aa64mmfr0;
53
- if (!widenfn || !opfn) {
56
- t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 5); /* PARange: 48 bits */
54
+ if (!opfn) {
57
+ t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */
55
/* size == 3 case, which is an entirely different insn group */
58
cpu->isar.id_aa64mmfr0 = t;
56
return false;
59
57
}
60
t = cpu->isar.id_aa64mmfr1;
58
61
diff --git a/target/arm/helper.c b/target/arm/helper.c
59
- if ((a->vd & 1) || (src1_wide && (a->vn & 1))) {
62
index XXXXXXX..XXXXXXX 100644
60
+ if ((a->vd & 1) || (src1_mop == MO_Q && (a->vn & 1))) {
63
--- a/target/arm/helper.c
61
return false;
64
+++ b/target/arm/helper.c
62
}
65
@@ -XXX,XX +XXX,XX @@ static const uint8_t pamax_map[] = {
63
66
[3] = 42,
64
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
67
[4] = 44,
65
rn1_64 = tcg_temp_new_i64();
68
[5] = 48,
66
rm_64 = tcg_temp_new_i64();
69
+ [6] = 52,
67
70
};
68
- if (src1_wide) {
71
69
- read_neon_element64(rn0_64, a->vn, 0, MO_64);
72
/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
70
+ if (src1_mop >= 0) {
73
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
71
+ read_neon_element64(rn0_64, a->vn, 0, src1_mop);
74
descaddr = extract64(ttbr, 0, 48);
72
} else {
73
TCGv_i32 tmp = tcg_temp_new_i32();
74
read_neon_element32(tmp, a->vn, 0, MO_32);
75
widenfn(rn0_64, tmp);
76
tcg_temp_free_i32(tmp);
77
}
78
- rm = tcg_temp_new_i32();
79
- read_neon_element32(rm, a->vm, 0, MO_32);
80
+ if (src2_mop >= 0) {
81
+ read_neon_element64(rm_64, a->vm, 0, src2_mop);
82
+ } else {
83
+ TCGv_i32 tmp = tcg_temp_new_i32();
84
+ read_neon_element32(tmp, a->vm, 0, MO_32);
85
+ widenfn(rm_64, tmp);
86
+ tcg_temp_free_i32(tmp);
87
+ }
88
89
- widenfn(rm_64, rm);
90
- tcg_temp_free_i32(rm);
91
opfn(rn0_64, rn0_64, rm_64);
92
75
93
/*
76
/*
94
* Load second pass inputs before storing the first pass result, to
77
- * If the base address is out of range, raise AddressSizeFault.
95
* avoid incorrect results if a narrow input overlaps with the result.
78
+ * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [5:2] of TTBR.
79
+ *
80
+ * Otherwise, if the base address is out of range, raise AddressSizeFault.
81
* In the pseudocode, this is !IsZero(baseregister<47:outputsize>),
82
* but we've just cleared the bits above 47, so simplify the test.
96
*/
83
*/
97
- if (src1_wide) {
84
- if (descaddr >> outputsize) {
98
- read_neon_element64(rn1_64, a->vn, 1, MO_64);
85
+ if (outputsize > 48) {
99
+ if (src1_mop >= 0) {
86
+ descaddr |= extract64(ttbr, 2, 4) << 48;
100
+ read_neon_element64(rn1_64, a->vn, 1, src1_mop);
87
+ } else if (descaddr >> outputsize) {
101
} else {
88
level = 0;
102
TCGv_i32 tmp = tcg_temp_new_i32();
89
fault_type = ARMFault_AddressSize;
103
read_neon_element32(tmp, a->vn, 1, MO_32);
90
goto do_fault;
104
widenfn(rn1_64, tmp);
91
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
105
tcg_temp_free_i32(tmp);
92
}
106
}
93
107
- rm = tcg_temp_new_i32();
94
descaddr = descriptor & descaddrmask;
108
- read_neon_element32(rm, a->vm, 1, MO_32);
95
- if (descaddr >> outputsize) {
109
+ if (src2_mop >= 0) {
96
+
110
+ read_neon_element64(rm_64, a->vm, 1, src2_mop);
97
+ /*
111
+ } else {
98
+ * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12]
112
+ TCGv_i32 tmp = tcg_temp_new_i32();
99
+ * of descriptor. Otherwise, if descaddr is out of range, raise
113
+ read_neon_element32(tmp, a->vm, 1, MO_32);
100
+ * AddressSizeFault.
114
+ widenfn(rm_64, tmp);
101
+ */
115
+ tcg_temp_free_i32(tmp);
102
+ if (outputsize > 48) {
116
+ }
103
+ descaddr |= extract64(descriptor, 12, 4) << 48;
117
104
+ } else if (descaddr >> outputsize) {
118
write_neon_element64(rn0_64, a->vd, 0, MO_64);
105
fault_type = ARMFault_AddressSize;
119
106
goto do_fault;
120
- widenfn(rm_64, rm);
107
}
121
- tcg_temp_free_i32(rm);
122
opfn(rn1_64, rn1_64, rm_64);
123
write_neon_element64(rn1_64, a->vd, 1, MO_64);
124
125
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
126
return true;
127
}
128
129
-#define DO_PREWIDEN(INSN, S, EXT, OP, SRC1WIDE) \
130
+#define DO_PREWIDEN(INSN, S, OP, SRC1WIDE, SIGN) \
131
static bool trans_##INSN##_3d(DisasContext *s, arg_3diff *a) \
132
{ \
133
static NeonGenWidenFn * const widenfn[] = { \
134
gen_helper_neon_widen_##S##8, \
135
gen_helper_neon_widen_##S##16, \
136
- tcg_gen_##EXT##_i32_i64, \
137
- NULL, \
138
+ NULL, NULL, \
139
}; \
140
static NeonGenTwo64OpFn * const addfn[] = { \
141
gen_helper_neon_##OP##l_u16, \
142
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
143
tcg_gen_##OP##_i64, \
144
NULL, \
145
}; \
146
- return do_prewiden_3d(s, a, widenfn[a->size], \
147
- addfn[a->size], SRC1WIDE); \
148
+ int narrow_mop = a->size == MO_32 ? MO_32 | SIGN : -1; \
149
+ return do_prewiden_3d(s, a, widenfn[a->size], addfn[a->size], \
150
+ SRC1WIDE ? MO_Q : narrow_mop, \
151
+ narrow_mop); \
152
}
153
154
-DO_PREWIDEN(VADDL_S, s, ext, add, false)
155
-DO_PREWIDEN(VADDL_U, u, extu, add, false)
156
-DO_PREWIDEN(VSUBL_S, s, ext, sub, false)
157
-DO_PREWIDEN(VSUBL_U, u, extu, sub, false)
158
-DO_PREWIDEN(VADDW_S, s, ext, add, true)
159
-DO_PREWIDEN(VADDW_U, u, extu, add, true)
160
-DO_PREWIDEN(VSUBW_S, s, ext, sub, true)
161
-DO_PREWIDEN(VSUBW_U, u, extu, sub, true)
162
+DO_PREWIDEN(VADDL_S, s, add, false, MO_SIGN)
163
+DO_PREWIDEN(VADDL_U, u, add, false, 0)
164
+DO_PREWIDEN(VSUBL_S, s, sub, false, MO_SIGN)
165
+DO_PREWIDEN(VSUBL_U, u, sub, false, 0)
166
+DO_PREWIDEN(VADDW_S, s, add, true, MO_SIGN)
167
+DO_PREWIDEN(VADDW_U, u, add, true, 0)
168
+DO_PREWIDEN(VSUBW_S, s, sub, true, MO_SIGN)
169
+DO_PREWIDEN(VSUBW_U, u, sub, true, 0)
170
171
static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
172
NeonGenTwo64OpFn *opfn, NeonGenNarrowFn *narrowfn)
173
--
108
--
174
2.20.1
109
2.25.1
175
176
diff view generated by jsdifflib
1
The helper functions for performing the udot/sdot operations against
1
From: Richard Henderson <richard.henderson@linaro.org>
2
a scalar were not using an address-swizzling macro when converting
3
the index of the scalar element into a pointer into the vm array.
4
This had no effect on little-endian hosts but meant we generated
5
incorrect results on big-endian hosts.
6
2
7
For these insns, the index is indexing over group of 4 8-bit values,
3
With FEAT_LPA2, rather than introducing translation level 4,
8
so 32 bits per indexed entity, and H4() is therefore what we want.
4
we introduce level -1, below the current level 0. Extend
9
(For Neon the only possible input indexes are 0 and 1.)
5
arm_fi_to_lfsc to handle these faults.
10
6
7
Assert that this new translation level does not leak into
8
fault types for which it is not defined, which allows some
9
masking of fi->level to be removed.
10
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20220301215958.157011-12-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20201028191712.4910-3-peter.maydell@linaro.org
15
---
15
---
16
target/arm/vec_helper.c | 4 ++--
16
target/arm/internals.h | 35 +++++++++++++++++++++++++++++------
17
1 file changed, 2 insertions(+), 2 deletions(-)
17
1 file changed, 29 insertions(+), 6 deletions(-)
18
18
19
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/vec_helper.c
21
--- a/target/arm/internals.h
22
+++ b/target/arm/vec_helper.c
22
+++ b/target/arm/internals.h
23
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
23
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
24
intptr_t index = simd_data(desc);
24
case ARMFault_None:
25
uint32_t *d = vd;
25
return 0;
26
int8_t *n = vn;
26
case ARMFault_AddressSize:
27
- int8_t *m_indexed = (int8_t *)vm + index * 4;
27
- fsc = fi->level & 3;
28
+ int8_t *m_indexed = (int8_t *)vm + H4(index) * 4;
28
+ assert(fi->level >= -1 && fi->level <= 3);
29
29
+ if (fi->level < 0) {
30
/* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
30
+ fsc = 0b101001;
31
* Otherwise opr_sz is a multiple of 16.
31
+ } else {
32
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_udot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
32
+ fsc = fi->level;
33
intptr_t index = simd_data(desc);
33
+ }
34
uint32_t *d = vd;
34
break;
35
uint8_t *n = vn;
35
case ARMFault_AccessFlag:
36
- uint8_t *m_indexed = (uint8_t *)vm + index * 4;
36
- fsc = (fi->level & 3) | (0x2 << 2);
37
+ uint8_t *m_indexed = (uint8_t *)vm + H4(index) * 4;
37
+ assert(fi->level >= 0 && fi->level <= 3);
38
38
+ fsc = 0b001000 | fi->level;
39
/* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
39
break;
40
* Otherwise opr_sz is a multiple of 16.
40
case ARMFault_Permission:
41
- fsc = (fi->level & 3) | (0x3 << 2);
42
+ assert(fi->level >= 0 && fi->level <= 3);
43
+ fsc = 0b001100 | fi->level;
44
break;
45
case ARMFault_Translation:
46
- fsc = (fi->level & 3) | (0x1 << 2);
47
+ assert(fi->level >= -1 && fi->level <= 3);
48
+ if (fi->level < 0) {
49
+ fsc = 0b101011;
50
+ } else {
51
+ fsc = 0b000100 | fi->level;
52
+ }
53
break;
54
case ARMFault_SyncExternal:
55
fsc = 0x10 | (fi->ea << 12);
56
break;
57
case ARMFault_SyncExternalOnWalk:
58
- fsc = (fi->level & 3) | (0x5 << 2) | (fi->ea << 12);
59
+ assert(fi->level >= -1 && fi->level <= 3);
60
+ if (fi->level < 0) {
61
+ fsc = 0b010011;
62
+ } else {
63
+ fsc = 0b010100 | fi->level;
64
+ }
65
+ fsc |= fi->ea << 12;
66
break;
67
case ARMFault_SyncParity:
68
fsc = 0x18;
69
break;
70
case ARMFault_SyncParityOnWalk:
71
- fsc = (fi->level & 3) | (0x7 << 2);
72
+ assert(fi->level >= -1 && fi->level <= 3);
73
+ if (fi->level < 0) {
74
+ fsc = 0b011011;
75
+ } else {
76
+ fsc = 0b011100 | fi->level;
77
+ }
78
break;
79
case ARMFault_AsyncParity:
80
fsc = 0x19;
41
--
81
--
42
2.20.1
82
2.25.1
43
44
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This seems a bit more readable than using offsetof CPU_DoubleU.
3
Merge tlbi_aa64_range_get_length and tlbi_aa64_range_get_base,
4
returning a structure containing both results. Pass in the
5
ARMMMUIdx, rather than the digested two_ranges boolean.
4
6
7
This is in preparation for FEAT_LPA2, where the interpretation
8
of 'value' depends on the effective value of DS for the regime.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20201030022618.785675-5-richard.henderson@linaro.org
12
Message-id: 20220301215958.157011-13-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
14
---
10
target/arm/translate.c | 13 ++++---------
15
target/arm/helper.c | 58 +++++++++++++++++++--------------------------
11
1 file changed, 4 insertions(+), 9 deletions(-)
16
1 file changed, 24 insertions(+), 34 deletions(-)
12
17
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
20
--- a/target/arm/helper.c
16
+++ b/target/arm/translate.c
21
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static long neon_element_offset(int reg, int element, MemOp size)
22
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
18
return neon_full_reg_offset(reg) + ofs;
19
}
23
}
20
24
21
-static inline long vfp_reg_offset(bool dp, unsigned reg)
25
#ifdef TARGET_AARCH64
22
+/* Return the offset of a VFP Dreg (dp = true) or VFP Sreg (dp = false). */
26
-static uint64_t tlbi_aa64_range_get_length(CPUARMState *env,
23
+static long vfp_reg_offset(bool dp, unsigned reg)
27
- uint64_t value)
28
-{
29
- unsigned int page_shift;
30
- unsigned int page_size_granule;
31
- uint64_t num;
32
- uint64_t scale;
33
- uint64_t exponent;
34
+typedef struct {
35
+ uint64_t base;
36
uint64_t length;
37
+} TLBIRange;
38
+
39
+static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
40
+ uint64_t value)
41
+{
42
+ unsigned int page_size_granule, page_shift, num, scale, exponent;
43
+ TLBIRange ret = { };
44
45
- num = extract64(value, 39, 5);
46
- scale = extract64(value, 44, 2);
47
page_size_granule = extract64(value, 46, 2);
48
49
if (page_size_granule == 0) {
50
qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
51
page_size_granule);
52
- return 0;
53
+ return ret;
54
}
55
56
page_shift = (page_size_granule - 1) * 2 + 12;
57
-
58
+ num = extract64(value, 39, 5);
59
+ scale = extract64(value, 44, 2);
60
exponent = (5 * scale) + 1;
61
- length = (num + 1) << (exponent + page_shift);
62
63
- return length;
64
-}
65
+ ret.length = (num + 1) << (exponent + page_shift);
66
67
-static uint64_t tlbi_aa64_range_get_base(CPUARMState *env, uint64_t value,
68
- bool two_ranges)
69
-{
70
- /* TODO: ARMv8.7 FEAT_LPA2 */
71
- uint64_t pageaddr;
72
-
73
- if (two_ranges) {
74
- pageaddr = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
75
+ if (regime_has_2_ranges(mmuidx)) {
76
+ ret.base = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
77
} else {
78
- pageaddr = extract64(value, 0, 37) << TARGET_PAGE_BITS;
79
+ ret.base = extract64(value, 0, 37) << TARGET_PAGE_BITS;
80
}
81
82
- return pageaddr;
83
+ return ret;
84
}
85
86
static void do_rvae_write(CPUARMState *env, uint64_t value,
87
int idxmap, bool synced)
24
{
88
{
25
if (dp) {
89
ARMMMUIdx one_idx = ARM_MMU_IDX_A | ctz32(idxmap);
26
- return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
90
- bool two_ranges = regime_has_2_ranges(one_idx);
27
+ return neon_element_offset(reg, 0, MO_64);
91
- uint64_t baseaddr, length;
92
+ TLBIRange range;
93
int bits;
94
95
- baseaddr = tlbi_aa64_range_get_base(env, value, two_ranges);
96
- length = tlbi_aa64_range_get_length(env, value);
97
- bits = tlbbits_for_regime(env, one_idx, baseaddr);
98
+ range = tlbi_aa64_get_range(env, one_idx, value);
99
+ bits = tlbbits_for_regime(env, one_idx, range.base);
100
101
if (synced) {
102
tlb_flush_range_by_mmuidx_all_cpus_synced(env_cpu(env),
103
- baseaddr,
104
- length,
105
+ range.base,
106
+ range.length,
107
idxmap,
108
bits);
28
} else {
109
} else {
29
- long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
110
- tlb_flush_range_by_mmuidx(env_cpu(env), baseaddr,
30
- if (reg & 1) {
111
- length, idxmap, bits);
31
- ofs += offsetof(CPU_DoubleU, l.upper);
112
+ tlb_flush_range_by_mmuidx(env_cpu(env), range.base,
32
- } else {
113
+ range.length, idxmap, bits);
33
- ofs += offsetof(CPU_DoubleU, l.lower);
34
- }
35
- return ofs;
36
+ return neon_element_offset(reg >> 1, reg & 1, MO_32);
37
}
114
}
38
}
115
}
39
116
40
--
117
--
41
2.20.1
118
2.25.1
42
43
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Model these off the aa64 read/write_vec_element functions.
3
The shift of the BaseADDR field depends on the translation
4
Use it within translate-neon.c.inc. The new functions do
4
granule in use.
5
not allocate or free temps, so this rearranges the calling
6
code a bit.
7
5
6
Fixes: 84940ed8255 ("target/arm: Add support for FEAT_TLBIRANGE")
7
Reported-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20201030022618.785675-6-richard.henderson@linaro.org
10
Message-id: 20220301215958.157011-14-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
target/arm/translate.c | 26 ++++
13
target/arm/helper.c | 5 +++--
14
target/arm/translate-neon.c.inc | 256 ++++++++++++++++++++------------
14
1 file changed, 3 insertions(+), 2 deletions(-)
15
2 files changed, 183 insertions(+), 99 deletions(-)
16
15
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate.c
18
--- a/target/arm/helper.c
20
+++ b/target/arm/translate.c
19
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg32(TCGv_i32 var, int reg)
20
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
22
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
21
ret.length = (num + 1) << (exponent + page_shift);
23
}
22
24
23
if (regime_has_2_ranges(mmuidx)) {
25
+static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp size)
24
- ret.base = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
26
+{
25
+ ret.base = sextract64(value, 0, 37);
27
+ long off = neon_element_offset(reg, ele, size);
26
} else {
28
+
27
- ret.base = extract64(value, 0, 37) << TARGET_PAGE_BITS;
29
+ switch (size) {
28
+ ret.base = extract64(value, 0, 37);
30
+ case MO_32:
31
+ tcg_gen_ld_i32(dest, cpu_env, off);
32
+ break;
33
+ default:
34
+ g_assert_not_reached();
35
+ }
36
+}
37
+
38
+static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp size)
39
+{
40
+ long off = neon_element_offset(reg, ele, size);
41
+
42
+ switch (size) {
43
+ case MO_32:
44
+ tcg_gen_st_i32(src, cpu_env, off);
45
+ break;
46
+ default:
47
+ g_assert_not_reached();
48
+ }
49
+}
50
+
51
static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
52
{
53
TCGv_ptr ret = tcg_temp_new_ptr();
54
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/translate-neon.c.inc
57
+++ b/target/arm/translate-neon.c.inc
58
@@ -XXX,XX +XXX,XX @@ static bool do_3same_pair(DisasContext *s, arg_3same *a, NeonGenTwoOpFn *fn)
59
* early. Since Q is 0 there are always just two passes, so instead
60
* of a complicated loop over each pass we just unroll.
61
*/
62
- tmp = neon_load_reg(a->vn, 0);
63
- tmp2 = neon_load_reg(a->vn, 1);
64
+ tmp = tcg_temp_new_i32();
65
+ tmp2 = tcg_temp_new_i32();
66
+ tmp3 = tcg_temp_new_i32();
67
+
68
+ read_neon_element32(tmp, a->vn, 0, MO_32);
69
+ read_neon_element32(tmp2, a->vn, 1, MO_32);
70
fn(tmp, tmp, tmp2);
71
- tcg_temp_free_i32(tmp2);
72
73
- tmp3 = neon_load_reg(a->vm, 0);
74
- tmp2 = neon_load_reg(a->vm, 1);
75
+ read_neon_element32(tmp3, a->vm, 0, MO_32);
76
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
77
fn(tmp3, tmp3, tmp2);
78
- tcg_temp_free_i32(tmp2);
79
80
- neon_store_reg(a->vd, 0, tmp);
81
- neon_store_reg(a->vd, 1, tmp3);
82
+ write_neon_element32(tmp, a->vd, 0, MO_32);
83
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
84
+
85
+ tcg_temp_free_i32(tmp);
86
+ tcg_temp_free_i32(tmp2);
87
+ tcg_temp_free_i32(tmp3);
88
return true;
89
}
90
91
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a,
92
* 2-reg-and-shift operations, size < 3 case, where the
93
* helper needs to be passed cpu_env.
94
*/
95
- TCGv_i32 constimm;
96
+ TCGv_i32 constimm, tmp;
97
int pass;
98
99
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
100
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_env_32(DisasContext *s, arg_2reg_shift *a,
101
* by immediate using the variable shift operations.
102
*/
103
constimm = tcg_const_i32(dup_const(a->size, a->shift));
104
+ tmp = tcg_temp_new_i32();
105
106
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
107
- TCGv_i32 tmp = neon_load_reg(a->vm, pass);
108
+ read_neon_element32(tmp, a->vm, pass, MO_32);
109
fn(tmp, cpu_env, tmp, constimm);
110
- neon_store_reg(a->vd, pass, tmp);
111
+ write_neon_element32(tmp, a->vd, pass, MO_32);
112
}
29
}
113
+ tcg_temp_free_i32(tmp);
30
+ ret.base <<= page_shift;
114
tcg_temp_free_i32(constimm);
31
115
return true;
32
return ret;
116
}
117
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_64(DisasContext *s, arg_2reg_shift *a,
118
constimm = tcg_const_i64(-a->shift);
119
rm1 = tcg_temp_new_i64();
120
rm2 = tcg_temp_new_i64();
121
+ rd = tcg_temp_new_i32();
122
123
/* Load both inputs first to avoid potential overwrite if rm == rd */
124
neon_load_reg64(rm1, a->vm);
125
neon_load_reg64(rm2, a->vm + 1);
126
127
shiftfn(rm1, rm1, constimm);
128
- rd = tcg_temp_new_i32();
129
narrowfn(rd, cpu_env, rm1);
130
- neon_store_reg(a->vd, 0, rd);
131
+ write_neon_element32(rd, a->vd, 0, MO_32);
132
133
shiftfn(rm2, rm2, constimm);
134
- rd = tcg_temp_new_i32();
135
narrowfn(rd, cpu_env, rm2);
136
- neon_store_reg(a->vd, 1, rd);
137
+ write_neon_element32(rd, a->vd, 1, MO_32);
138
139
+ tcg_temp_free_i32(rd);
140
tcg_temp_free_i64(rm1);
141
tcg_temp_free_i64(rm2);
142
tcg_temp_free_i64(constimm);
143
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
144
constimm = tcg_const_i32(imm);
145
146
/* Load all inputs first to avoid potential overwrite */
147
- rm1 = neon_load_reg(a->vm, 0);
148
- rm2 = neon_load_reg(a->vm, 1);
149
- rm3 = neon_load_reg(a->vm + 1, 0);
150
- rm4 = neon_load_reg(a->vm + 1, 1);
151
+ rm1 = tcg_temp_new_i32();
152
+ rm2 = tcg_temp_new_i32();
153
+ rm3 = tcg_temp_new_i32();
154
+ rm4 = tcg_temp_new_i32();
155
+ read_neon_element32(rm1, a->vm, 0, MO_32);
156
+ read_neon_element32(rm2, a->vm, 1, MO_32);
157
+ read_neon_element32(rm3, a->vm, 2, MO_32);
158
+ read_neon_element32(rm4, a->vm, 3, MO_32);
159
rtmp = tcg_temp_new_i64();
160
161
shiftfn(rm1, rm1, constimm);
162
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
163
tcg_temp_free_i32(rm2);
164
165
narrowfn(rm1, cpu_env, rtmp);
166
- neon_store_reg(a->vd, 0, rm1);
167
+ write_neon_element32(rm1, a->vd, 0, MO_32);
168
+ tcg_temp_free_i32(rm1);
169
170
shiftfn(rm3, rm3, constimm);
171
shiftfn(rm4, rm4, constimm);
172
@@ -XXX,XX +XXX,XX @@ static bool do_2shift_narrow_32(DisasContext *s, arg_2reg_shift *a,
173
174
narrowfn(rm3, cpu_env, rtmp);
175
tcg_temp_free_i64(rtmp);
176
- neon_store_reg(a->vd, 1, rm3);
177
+ write_neon_element32(rm3, a->vd, 1, MO_32);
178
+ tcg_temp_free_i32(rm3);
179
return true;
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static bool do_vshll_2sh(DisasContext *s, arg_2reg_shift *a,
183
widen_mask = dup_const(a->size + 1, widen_mask);
184
}
185
186
- rm0 = neon_load_reg(a->vm, 0);
187
- rm1 = neon_load_reg(a->vm, 1);
188
+ rm0 = tcg_temp_new_i32();
189
+ rm1 = tcg_temp_new_i32();
190
+ read_neon_element32(rm0, a->vm, 0, MO_32);
191
+ read_neon_element32(rm1, a->vm, 1, MO_32);
192
tmp = tcg_temp_new_i64();
193
194
widenfn(tmp, rm0);
195
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
196
if (src1_wide) {
197
neon_load_reg64(rn0_64, a->vn);
198
} else {
199
- TCGv_i32 tmp = neon_load_reg(a->vn, 0);
200
+ TCGv_i32 tmp = tcg_temp_new_i32();
201
+ read_neon_element32(tmp, a->vn, 0, MO_32);
202
widenfn(rn0_64, tmp);
203
tcg_temp_free_i32(tmp);
204
}
205
- rm = neon_load_reg(a->vm, 0);
206
+ rm = tcg_temp_new_i32();
207
+ read_neon_element32(rm, a->vm, 0, MO_32);
208
209
widenfn(rm_64, rm);
210
tcg_temp_free_i32(rm);
211
@@ -XXX,XX +XXX,XX @@ static bool do_prewiden_3d(DisasContext *s, arg_3diff *a,
212
if (src1_wide) {
213
neon_load_reg64(rn1_64, a->vn + 1);
214
} else {
215
- TCGv_i32 tmp = neon_load_reg(a->vn, 1);
216
+ TCGv_i32 tmp = tcg_temp_new_i32();
217
+ read_neon_element32(tmp, a->vn, 1, MO_32);
218
widenfn(rn1_64, tmp);
219
tcg_temp_free_i32(tmp);
220
}
221
- rm = neon_load_reg(a->vm, 1);
222
+ rm = tcg_temp_new_i32();
223
+ read_neon_element32(rm, a->vm, 1, MO_32);
224
225
neon_store_reg64(rn0_64, a->vd);
226
227
@@ -XXX,XX +XXX,XX @@ static bool do_narrow_3d(DisasContext *s, arg_3diff *a,
228
229
narrowfn(rd1, rn_64);
230
231
- neon_store_reg(a->vd, 0, rd0);
232
- neon_store_reg(a->vd, 1, rd1);
233
+ write_neon_element32(rd0, a->vd, 0, MO_32);
234
+ write_neon_element32(rd1, a->vd, 1, MO_32);
235
236
+ tcg_temp_free_i32(rd0);
237
+ tcg_temp_free_i32(rd1);
238
tcg_temp_free_i64(rn_64);
239
tcg_temp_free_i64(rm_64);
240
241
@@ -XXX,XX +XXX,XX @@ static bool do_long_3d(DisasContext *s, arg_3diff *a,
242
rd0 = tcg_temp_new_i64();
243
rd1 = tcg_temp_new_i64();
244
245
- rn = neon_load_reg(a->vn, 0);
246
- rm = neon_load_reg(a->vm, 0);
247
+ rn = tcg_temp_new_i32();
248
+ rm = tcg_temp_new_i32();
249
+ read_neon_element32(rn, a->vn, 0, MO_32);
250
+ read_neon_element32(rm, a->vm, 0, MO_32);
251
opfn(rd0, rn, rm);
252
- tcg_temp_free_i32(rn);
253
- tcg_temp_free_i32(rm);
254
255
- rn = neon_load_reg(a->vn, 1);
256
- rm = neon_load_reg(a->vm, 1);
257
+ read_neon_element32(rn, a->vn, 1, MO_32);
258
+ read_neon_element32(rm, a->vm, 1, MO_32);
259
opfn(rd1, rn, rm);
260
tcg_temp_free_i32(rn);
261
tcg_temp_free_i32(rm);
262
@@ -XXX,XX +XXX,XX @@ static void gen_neon_dup_high16(TCGv_i32 var)
263
264
static inline TCGv_i32 neon_get_scalar(int size, int reg)
265
{
266
- TCGv_i32 tmp;
267
- if (size == 1) {
268
- tmp = neon_load_reg(reg & 7, reg >> 4);
269
+ TCGv_i32 tmp = tcg_temp_new_i32();
270
+ if (size == MO_16) {
271
+ read_neon_element32(tmp, reg & 7, reg >> 4, MO_32);
272
if (reg & 8) {
273
gen_neon_dup_high16(tmp);
274
} else {
275
gen_neon_dup_low16(tmp);
276
}
277
} else {
278
- tmp = neon_load_reg(reg & 15, reg >> 4);
279
+ read_neon_element32(tmp, reg & 15, reg >> 4, MO_32);
280
}
281
return tmp;
282
}
283
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar(DisasContext *s, arg_2scalar *a,
284
* perform an accumulation operation of that result into the
285
* destination.
286
*/
287
- TCGv_i32 scalar;
288
+ TCGv_i32 scalar, tmp;
289
int pass;
290
291
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
292
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar(DisasContext *s, arg_2scalar *a,
293
}
294
295
scalar = neon_get_scalar(a->size, a->vm);
296
+ tmp = tcg_temp_new_i32();
297
298
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
299
- TCGv_i32 tmp = neon_load_reg(a->vn, pass);
300
+ read_neon_element32(tmp, a->vn, pass, MO_32);
301
opfn(tmp, tmp, scalar);
302
if (accfn) {
303
- TCGv_i32 rd = neon_load_reg(a->vd, pass);
304
+ TCGv_i32 rd = tcg_temp_new_i32();
305
+ read_neon_element32(rd, a->vd, pass, MO_32);
306
accfn(tmp, rd, tmp);
307
tcg_temp_free_i32(rd);
308
}
309
- neon_store_reg(a->vd, pass, tmp);
310
+ write_neon_element32(tmp, a->vd, pass, MO_32);
311
}
312
+ tcg_temp_free_i32(tmp);
313
tcg_temp_free_i32(scalar);
314
return true;
315
}
316
@@ -XXX,XX +XXX,XX @@ static bool do_vqrdmlah_2sc(DisasContext *s, arg_2scalar *a,
317
* performs a kind of fused op-then-accumulate using a helper
318
* function that takes all of rd, rn and the scalar at once.
319
*/
320
- TCGv_i32 scalar;
321
+ TCGv_i32 scalar, rn, rd;
322
int pass;
323
324
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
325
@@ -XXX,XX +XXX,XX @@ static bool do_vqrdmlah_2sc(DisasContext *s, arg_2scalar *a,
326
}
327
328
scalar = neon_get_scalar(a->size, a->vm);
329
+ rn = tcg_temp_new_i32();
330
+ rd = tcg_temp_new_i32();
331
332
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
333
- TCGv_i32 rn = neon_load_reg(a->vn, pass);
334
- TCGv_i32 rd = neon_load_reg(a->vd, pass);
335
+ read_neon_element32(rn, a->vn, pass, MO_32);
336
+ read_neon_element32(rd, a->vd, pass, MO_32);
337
opfn(rd, cpu_env, rn, scalar, rd);
338
- tcg_temp_free_i32(rn);
339
- neon_store_reg(a->vd, pass, rd);
340
+ write_neon_element32(rd, a->vd, pass, MO_32);
341
}
342
+ tcg_temp_free_i32(rn);
343
+ tcg_temp_free_i32(rd);
344
tcg_temp_free_i32(scalar);
345
346
return true;
347
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_long(DisasContext *s, arg_2scalar *a,
348
scalar = neon_get_scalar(a->size, a->vm);
349
350
/* Load all inputs before writing any outputs, in case of overlap */
351
- rn = neon_load_reg(a->vn, 0);
352
+ rn = tcg_temp_new_i32();
353
+ read_neon_element32(rn, a->vn, 0, MO_32);
354
rn0_64 = tcg_temp_new_i64();
355
opfn(rn0_64, rn, scalar);
356
- tcg_temp_free_i32(rn);
357
358
- rn = neon_load_reg(a->vn, 1);
359
+ read_neon_element32(rn, a->vn, 1, MO_32);
360
rn1_64 = tcg_temp_new_i64();
361
opfn(rn1_64, rn, scalar);
362
tcg_temp_free_i32(rn);
363
@@ -XXX,XX +XXX,XX @@ static bool trans_VTBL(DisasContext *s, arg_VTBL *a)
364
return false;
365
}
366
n <<= 3;
367
+ tmp = tcg_temp_new_i32();
368
if (a->op) {
369
- tmp = neon_load_reg(a->vd, 0);
370
+ read_neon_element32(tmp, a->vd, 0, MO_32);
371
} else {
372
- tmp = tcg_temp_new_i32();
373
tcg_gen_movi_i32(tmp, 0);
374
}
375
- tmp2 = neon_load_reg(a->vm, 0);
376
+ tmp2 = tcg_temp_new_i32();
377
+ read_neon_element32(tmp2, a->vm, 0, MO_32);
378
ptr1 = vfp_reg_ptr(true, a->vn);
379
tmp4 = tcg_const_i32(n);
380
gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp4);
381
- tcg_temp_free_i32(tmp);
382
+
383
if (a->op) {
384
- tmp = neon_load_reg(a->vd, 1);
385
+ read_neon_element32(tmp, a->vd, 1, MO_32);
386
} else {
387
- tmp = tcg_temp_new_i32();
388
tcg_gen_movi_i32(tmp, 0);
389
}
390
- tmp3 = neon_load_reg(a->vm, 1);
391
+ tmp3 = tcg_temp_new_i32();
392
+ read_neon_element32(tmp3, a->vm, 1, MO_32);
393
gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp4);
394
+ tcg_temp_free_i32(tmp);
395
tcg_temp_free_i32(tmp4);
396
tcg_temp_free_ptr(ptr1);
397
- neon_store_reg(a->vd, 0, tmp2);
398
- neon_store_reg(a->vd, 1, tmp3);
399
- tcg_temp_free_i32(tmp);
400
+
401
+ write_neon_element32(tmp2, a->vd, 0, MO_32);
402
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
403
+ tcg_temp_free_i32(tmp2);
404
+ tcg_temp_free_i32(tmp3);
405
return true;
406
}
407
408
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
409
static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
410
{
411
int pass, half;
412
+ TCGv_i32 tmp[2];
413
414
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
415
return false;
416
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
417
return true;
418
}
419
420
- for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
421
- TCGv_i32 tmp[2];
422
+ tmp[0] = tcg_temp_new_i32();
423
+ tmp[1] = tcg_temp_new_i32();
424
425
+ for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
426
for (half = 0; half < 2; half++) {
427
- tmp[half] = neon_load_reg(a->vm, pass * 2 + half);
428
+ read_neon_element32(tmp[half], a->vm, pass * 2 + half, MO_32);
429
switch (a->size) {
430
case 0:
431
tcg_gen_bswap32_i32(tmp[half], tmp[half]);
432
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
433
g_assert_not_reached();
434
}
435
}
436
- neon_store_reg(a->vd, pass * 2, tmp[1]);
437
- neon_store_reg(a->vd, pass * 2 + 1, tmp[0]);
438
+ write_neon_element32(tmp[1], a->vd, pass * 2, MO_32);
439
+ write_neon_element32(tmp[0], a->vd, pass * 2 + 1, MO_32);
440
}
441
+
442
+ tcg_temp_free_i32(tmp[0]);
443
+ tcg_temp_free_i32(tmp[1]);
444
return true;
445
}
446
447
@@ -XXX,XX +XXX,XX @@ static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
448
rm0_64 = tcg_temp_new_i64();
449
rm1_64 = tcg_temp_new_i64();
450
rd_64 = tcg_temp_new_i64();
451
- tmp = neon_load_reg(a->vm, pass * 2);
452
+
453
+ tmp = tcg_temp_new_i32();
454
+ read_neon_element32(tmp, a->vm, pass * 2, MO_32);
455
widenfn(rm0_64, tmp);
456
- tcg_temp_free_i32(tmp);
457
- tmp = neon_load_reg(a->vm, pass * 2 + 1);
458
+ read_neon_element32(tmp, a->vm, pass * 2 + 1, MO_32);
459
widenfn(rm1_64, tmp);
460
tcg_temp_free_i32(tmp);
461
+
462
opfn(rd_64, rm0_64, rm1_64);
463
tcg_temp_free_i64(rm0_64);
464
tcg_temp_free_i64(rm1_64);
465
@@ -XXX,XX +XXX,XX @@ static bool do_vmovn(DisasContext *s, arg_2misc *a,
466
narrowfn(rd0, cpu_env, rm);
467
neon_load_reg64(rm, a->vm + 1);
468
narrowfn(rd1, cpu_env, rm);
469
- neon_store_reg(a->vd, 0, rd0);
470
- neon_store_reg(a->vd, 1, rd1);
471
+ write_neon_element32(rd0, a->vd, 0, MO_32);
472
+ write_neon_element32(rd1, a->vd, 1, MO_32);
473
+ tcg_temp_free_i32(rd0);
474
+ tcg_temp_free_i32(rd1);
475
tcg_temp_free_i64(rm);
476
return true;
477
}
478
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
479
}
480
481
rd = tcg_temp_new_i64();
482
+ rm0 = tcg_temp_new_i32();
483
+ rm1 = tcg_temp_new_i32();
484
485
- rm0 = neon_load_reg(a->vm, 0);
486
- rm1 = neon_load_reg(a->vm, 1);
487
+ read_neon_element32(rm0, a->vm, 0, MO_32);
488
+ read_neon_element32(rm1, a->vm, 1, MO_32);
489
490
widenfn(rd, rm0);
491
tcg_gen_shli_i64(rd, rd, 8 << a->size);
492
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F16_F32(DisasContext *s, arg_2misc *a)
493
494
fpst = fpstatus_ptr(FPST_STD);
495
ahp = get_ahp_flag();
496
- tmp = neon_load_reg(a->vm, 0);
497
+ tmp = tcg_temp_new_i32();
498
+ read_neon_element32(tmp, a->vm, 0, MO_32);
499
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
500
- tmp2 = neon_load_reg(a->vm, 1);
501
+ tmp2 = tcg_temp_new_i32();
502
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
503
gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
504
tcg_gen_shli_i32(tmp2, tmp2, 16);
505
tcg_gen_or_i32(tmp2, tmp2, tmp);
506
- tcg_temp_free_i32(tmp);
507
- tmp = neon_load_reg(a->vm, 2);
508
+ read_neon_element32(tmp, a->vm, 2, MO_32);
509
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
510
- tmp3 = neon_load_reg(a->vm, 3);
511
- neon_store_reg(a->vd, 0, tmp2);
512
+ tmp3 = tcg_temp_new_i32();
513
+ read_neon_element32(tmp3, a->vm, 3, MO_32);
514
+ write_neon_element32(tmp2, a->vd, 0, MO_32);
515
+ tcg_temp_free_i32(tmp2);
516
gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
517
tcg_gen_shli_i32(tmp3, tmp3, 16);
518
tcg_gen_or_i32(tmp3, tmp3, tmp);
519
- neon_store_reg(a->vd, 1, tmp3);
520
+ write_neon_element32(tmp3, a->vd, 1, MO_32);
521
+ tcg_temp_free_i32(tmp3);
522
tcg_temp_free_i32(tmp);
523
tcg_temp_free_i32(ahp);
524
tcg_temp_free_ptr(fpst);
525
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
526
fpst = fpstatus_ptr(FPST_STD);
527
ahp = get_ahp_flag();
528
tmp3 = tcg_temp_new_i32();
529
- tmp = neon_load_reg(a->vm, 0);
530
- tmp2 = neon_load_reg(a->vm, 1);
531
+ tmp2 = tcg_temp_new_i32();
532
+ tmp = tcg_temp_new_i32();
533
+ read_neon_element32(tmp, a->vm, 0, MO_32);
534
+ read_neon_element32(tmp2, a->vm, 1, MO_32);
535
tcg_gen_ext16u_i32(tmp3, tmp);
536
gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
537
- neon_store_reg(a->vd, 0, tmp3);
538
+ write_neon_element32(tmp3, a->vd, 0, MO_32);
539
tcg_gen_shri_i32(tmp, tmp, 16);
540
gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
541
- neon_store_reg(a->vd, 1, tmp);
542
- tmp3 = tcg_temp_new_i32();
543
+ write_neon_element32(tmp, a->vd, 1, MO_32);
544
+ tcg_temp_free_i32(tmp);
545
tcg_gen_ext16u_i32(tmp3, tmp2);
546
gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
547
- neon_store_reg(a->vd, 2, tmp3);
548
+ write_neon_element32(tmp3, a->vd, 2, MO_32);
549
+ tcg_temp_free_i32(tmp3);
550
tcg_gen_shri_i32(tmp2, tmp2, 16);
551
gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
552
- neon_store_reg(a->vd, 3, tmp2);
553
+ write_neon_element32(tmp2, a->vd, 3, MO_32);
554
+ tcg_temp_free_i32(tmp2);
555
tcg_temp_free_i32(ahp);
556
tcg_temp_free_ptr(fpst);
557
558
@@ -XXX,XX +XXX,XX @@ DO_2M_CRYPTO(SHA256SU0, aa32_sha2, 2)
559
560
static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
561
{
562
+ TCGv_i32 tmp;
563
int pass;
564
565
/* Handle a 2-reg-misc operation by iterating 32 bits at a time */
566
@@ -XXX,XX +XXX,XX @@ static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
567
return true;
568
}
569
570
+ tmp = tcg_temp_new_i32();
571
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
572
- TCGv_i32 tmp = neon_load_reg(a->vm, pass);
573
+ read_neon_element32(tmp, a->vm, pass, MO_32);
574
fn(tmp, tmp);
575
- neon_store_reg(a->vd, pass, tmp);
576
+ write_neon_element32(tmp, a->vd, pass, MO_32);
577
}
578
+ tcg_temp_free_i32(tmp);
579
580
return true;
581
}
582
@@ -XXX,XX +XXX,XX @@ static bool trans_VTRN(DisasContext *s, arg_2misc *a)
583
return true;
584
}
585
586
- if (a->size == 2) {
587
+ tmp = tcg_temp_new_i32();
588
+ tmp2 = tcg_temp_new_i32();
589
+ if (a->size == MO_32) {
590
for (pass = 0; pass < (a->q ? 4 : 2); pass += 2) {
591
- tmp = neon_load_reg(a->vm, pass);
592
- tmp2 = neon_load_reg(a->vd, pass + 1);
593
- neon_store_reg(a->vm, pass, tmp2);
594
- neon_store_reg(a->vd, pass + 1, tmp);
595
+ read_neon_element32(tmp, a->vm, pass, MO_32);
596
+ read_neon_element32(tmp2, a->vd, pass + 1, MO_32);
597
+ write_neon_element32(tmp2, a->vm, pass, MO_32);
598
+ write_neon_element32(tmp, a->vd, pass + 1, MO_32);
599
}
600
} else {
601
for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
602
- tmp = neon_load_reg(a->vm, pass);
603
- tmp2 = neon_load_reg(a->vd, pass);
604
- if (a->size == 0) {
605
+ read_neon_element32(tmp, a->vm, pass, MO_32);
606
+ read_neon_element32(tmp2, a->vd, pass, MO_32);
607
+ if (a->size == MO_8) {
608
gen_neon_trn_u8(tmp, tmp2);
609
} else {
610
gen_neon_trn_u16(tmp, tmp2);
611
}
612
- neon_store_reg(a->vm, pass, tmp2);
613
- neon_store_reg(a->vd, pass, tmp);
614
+ write_neon_element32(tmp2, a->vm, pass, MO_32);
615
+ write_neon_element32(tmp, a->vd, pass, MO_32);
616
}
617
}
618
+ tcg_temp_free_i32(tmp);
619
+ tcg_temp_free_i32(tmp2);
620
return true;
621
}
33
}
622
--
34
--
623
2.20.1
35
2.25.1
624
625
diff view generated by jsdifflib
1
From: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
HCR should be applied when NS is set, not when it is cleared.
3
For FEAT_LPA2, we will need other ARMVAParameters, which themselves
4
depend on the translation granule in use. We might as well validate
5
that the given TG matches; the architecture "does not require that
6
the instruction invalidates any entries" if this is not true.
4
7
5
Signed-off-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220301215958.157011-15-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
12
---
9
target/arm/helper.c | 5 ++---
13
target/arm/helper.c | 10 +++++++---
10
1 file changed, 2 insertions(+), 3 deletions(-)
14
1 file changed, 7 insertions(+), 3 deletions(-)
11
15
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
18
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
19
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static void tlbimvaa_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
20
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
17
21
uint64_t value)
18
/*
19
* Non-IS variants of TLB operations are upgraded to
20
- * IS versions if we are at NS EL1 and HCR_EL2.FB is set to
21
+ * IS versions if we are at EL1 and HCR_EL2.FB is effectively set to
22
* force broadcast of these operations.
23
*/
24
static bool tlb_force_broadcast(CPUARMState *env)
25
{
22
{
26
- return (env->cp15.hcr_el2 & HCR_FB) &&
23
unsigned int page_size_granule, page_shift, num, scale, exponent;
27
- arm_current_el(env) == 1 && arm_is_secure_below_el3(env);
24
+ /* Extract one bit to represent the va selector in use. */
28
+ return arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_FB);
25
+ uint64_t select = sextract64(value, 36, 1);
29
}
26
+ ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true);
30
27
TLBIRange ret = { };
31
static void tlbiall_write(CPUARMState *env, const ARMCPRegInfo *ri,
28
29
page_size_granule = extract64(value, 46, 2);
30
31
- if (page_size_granule == 0) {
32
- qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
33
+ /* The granule encoded in value must match the granule in use. */
34
+ if (page_size_granule != (param.using64k ? 3 : param.using16k ? 2 : 1)) {
35
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n",
36
page_size_granule);
37
return ret;
38
}
39
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
40
41
ret.length = (num + 1) << (exponent + page_shift);
42
43
- if (regime_has_2_ranges(mmuidx)) {
44
+ if (param.select) {
45
ret.base = sextract64(value, 0, 37);
46
} else {
47
ret.base = extract64(value, 0, 37);
32
--
48
--
33
2.20.1
49
2.25.1
34
35
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
These are the only users of neon_reg_offset, so remove that.
3
We support 16k pages, but do not advertize that in ID_AA64MMFR0.
4
5
The value 0 in the TGRAN*_2 fields indicates that stage2 lookups defer
6
to the same support as stage1 lookups. This setting is deprecated, so
7
indicate support for all stage2 page sizes directly.
4
8
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20201030022618.785675-4-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20220301215958.157011-16-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
13
---
10
target/arm/translate.c | 14 ++------------
14
target/arm/cpu64.c | 4 ++++
11
1 file changed, 2 insertions(+), 12 deletions(-)
15
1 file changed, 4 insertions(+)
12
16
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
19
--- a/target/arm/cpu64.c
16
+++ b/target/arm/translate.c
20
+++ b/target/arm/cpu64.c
17
@@ -XXX,XX +XXX,XX @@ static inline long vfp_reg_offset(bool dp, unsigned reg)
21
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
18
}
22
19
}
23
t = cpu->isar.id_aa64mmfr0;
20
24
t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */
21
-/* Return the offset of a 32-bit piece of a NEON register.
25
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 1); /* 16k pages supported */
22
- zero is the least significant end of the register. */
26
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 2); /* 16k stage2 supported */
23
-static inline long
27
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN64_2, 2); /* 64k stage2 supported */
24
-neon_reg_offset (int reg, int n)
28
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */
25
-{
29
cpu->isar.id_aa64mmfr0 = t;
26
- int sreg;
30
27
- sreg = reg * 2 + n;
31
t = cpu->isar.id_aa64mmfr1;
28
- return vfp_reg_offset(0, sreg);
29
-}
30
-
31
static TCGv_i32 neon_load_reg(int reg, int pass)
32
{
33
TCGv_i32 tmp = tcg_temp_new_i32();
34
- tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
35
+ tcg_gen_ld_i32(tmp, cpu_env, neon_element_offset(reg, pass, MO_32));
36
return tmp;
37
}
38
39
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
40
{
41
- tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
42
+ tcg_gen_st_i32(var, cpu_env, neon_element_offset(reg, pass, MO_32));
43
tcg_temp_free_i32(var);
44
}
45
46
--
32
--
47
2.20.1
33
2.25.1
48
49
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This function makes it clear that we're talking about the whole
3
This feature widens physical addresses (and intermediate physical
4
register, and not the 32-bit piece at index 0. This fixes a bug
4
addresses for 2-stage translation) from 48 to 52 bits, when using
5
when running on a big-endian host.
5
4k or 16k pages.
6
6
7
This introduces the DS bit to TCR_ELx, which is RES0 unless the
8
page size is enabled and supports LPA2, resulting in the effective
9
value of DS for a given table walk. The DS bit changes the format
10
of the page table descriptor slightly, moving the PS field out to
11
TCR so that all pages have the same sharability and repurposing
12
those bits of the page table descriptor for the highest bits of
13
the output address.
14
15
Do not yet enable FEAT_LPA2; we need extra plumbing to avoid
16
tickling an old kernel bug.
17
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
19
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20201030022618.785675-2-richard.henderson@linaro.org
20
Message-id: 20220301215958.157011-17-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
22
---
12
target/arm/translate.c | 8 ++++++
23
docs/system/arm/emulation.rst | 1 +
13
target/arm/translate-neon.c.inc | 44 ++++++++++++++++-----------------
24
target/arm/cpu.h | 22 ++++++++
14
target/arm/translate-vfp.c.inc | 2 +-
25
target/arm/internals.h | 2 +
15
3 files changed, 31 insertions(+), 23 deletions(-)
26
target/arm/helper.c | 102 +++++++++++++++++++++++++++++-----
16
27
4 files changed, 112 insertions(+), 15 deletions(-)
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
28
29
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
18
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate.c
31
--- a/docs/system/arm/emulation.rst
20
+++ b/target/arm/translate.c
32
+++ b/docs/system/arm/emulation.rst
21
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
33
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
22
unallocated_encoding(s);
34
- FEAT_JSCVT (JavaScript conversion instructions)
35
- FEAT_LOR (Limited ordering regions)
36
- FEAT_LPA (Large Physical Address space)
37
+- FEAT_LPA2 (Large Physical and virtual Address space v2)
38
- FEAT_LRCPC (Load-acquire RCpc instructions)
39
- FEAT_LRCPC2 (Load-acquire RCpc instructions v2)
40
- FEAT_LSE (Large System Extensions)
41
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/cpu.h
44
+++ b/target/arm/cpu.h
45
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_i8mm(const ARMISARegisters *id)
46
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, I8MM) != 0;
23
}
47
}
24
48
25
+/*
49
+static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
26
+ * Return the offset of a "full" NEON Dreg.
27
+ */
28
+static long neon_full_reg_offset(unsigned reg)
29
+{
50
+{
30
+ return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
51
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1;
31
+}
52
+}
32
+
53
+
33
static inline long vfp_reg_offset(bool dp, unsigned reg)
54
+static inline bool isar_feature_aa64_tgran4_2_lpa2(const ARMISARegisters *id)
55
+{
56
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
57
+ return t >= 3 || (t == 0 && isar_feature_aa64_tgran4_lpa2(id));
58
+}
59
+
60
+static inline bool isar_feature_aa64_tgran16_lpa2(const ARMISARegisters *id)
61
+{
62
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 2;
63
+}
64
+
65
+static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
66
+{
67
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
68
+ return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
69
+}
70
+
71
static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
34
{
72
{
35
if (dp) {
73
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
36
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
74
diff --git a/target/arm/internals.h b/target/arm/internals.h
37
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-neon.c.inc
76
--- a/target/arm/internals.h
39
+++ b/target/arm/translate-neon.c.inc
77
+++ b/target/arm/internals.h
40
@@ -XXX,XX +XXX,XX @@ neon_element_offset(int reg, int element, MemOp size)
78
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
41
ofs ^= 8 - element_size;
79
typedef struct ARMVAParameters {
42
}
80
unsigned tsz : 8;
43
#endif
81
unsigned ps : 3;
44
- return neon_reg_offset(reg, 0) + ofs;
82
+ unsigned sh : 2;
45
+ return neon_full_reg_offset(reg) + ofs;
83
unsigned select : 1;
84
bool tbi : 1;
85
bool epd : 1;
86
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
87
bool using16k : 1;
88
bool using64k : 1;
89
bool tsz_oob : 1; /* tsz has been clamped to legal range */
90
+ bool ds : 1;
91
} ARMVAParameters;
92
93
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
94
diff --git a/target/arm/helper.c b/target/arm/helper.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/target/arm/helper.c
97
+++ b/target/arm/helper.c
98
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
99
} else {
100
ret.base = extract64(value, 0, 37);
101
}
102
+ if (param.ds) {
103
+ /*
104
+ * With DS=1, BaseADDR is always shifted 16 so that it is able
105
+ * to address all 52 va bits. The input address is perforce
106
+ * aligned on a 64k boundary regardless of translation granule.
107
+ */
108
+ page_shift = 16;
109
+ }
110
ret.base <<= page_shift;
111
112
return ret;
113
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
114
const int grainsize = stride + 3;
115
int startsizecheck;
116
117
- /* Negative levels are never allowed. */
118
- if (level < 0) {
119
+ /*
120
+ * Negative levels are usually not allowed...
121
+ * Except for FEAT_LPA2, 4k page table, 52-bit address space, which
122
+ * begins with level -1. Note that previous feature tests will have
123
+ * eliminated this combination if it is not enabled.
124
+ */
125
+ if (level < (inputsize == 52 && stride == 9 ? -1 : 0)) {
126
return false;
127
}
128
129
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
130
ARMMMUIdx mmu_idx, bool data)
131
{
132
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
133
- bool epd, hpd, using16k, using64k, tsz_oob;
134
- int select, tsz, tbi, max_tsz, min_tsz, ps;
135
+ bool epd, hpd, using16k, using64k, tsz_oob, ds;
136
+ int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
137
+ ARMCPU *cpu = env_archcpu(env);
138
139
if (!regime_has_2_ranges(mmu_idx)) {
140
select = 0;
141
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
142
hpd = extract32(tcr, 24, 1);
143
}
144
epd = false;
145
+ sh = extract32(tcr, 12, 2);
146
ps = extract32(tcr, 16, 3);
147
+ ds = extract64(tcr, 32, 1);
148
} else {
149
/*
150
* Bit 55 is always between the two regions, and is canonical for
151
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
152
if (!select) {
153
tsz = extract32(tcr, 0, 6);
154
epd = extract32(tcr, 7, 1);
155
+ sh = extract32(tcr, 12, 2);
156
using64k = extract32(tcr, 14, 1);
157
using16k = extract32(tcr, 15, 1);
158
hpd = extract64(tcr, 41, 1);
159
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
160
using64k = tg == 3;
161
tsz = extract32(tcr, 16, 6);
162
epd = extract32(tcr, 23, 1);
163
+ sh = extract32(tcr, 28, 2);
164
hpd = extract64(tcr, 42, 1);
165
}
166
ps = extract64(tcr, 32, 3);
167
+ ds = extract64(tcr, 59, 1);
168
}
169
170
- if (cpu_isar_feature(aa64_st, env_archcpu(env))) {
171
+ if (cpu_isar_feature(aa64_st, cpu)) {
172
max_tsz = 48 - using64k;
173
} else {
174
max_tsz = 39;
175
}
176
177
+ /*
178
+ * DS is RES0 unless FEAT_LPA2 is supported for the given page size;
179
+ * adjust the effective value of DS, as documented.
180
+ */
181
min_tsz = 16;
182
if (using64k) {
183
- if (cpu_isar_feature(aa64_lva, env_archcpu(env))) {
184
+ if (cpu_isar_feature(aa64_lva, cpu)) {
185
+ min_tsz = 12;
186
+ }
187
+ ds = false;
188
+ } else if (ds) {
189
+ switch (mmu_idx) {
190
+ case ARMMMUIdx_Stage2:
191
+ case ARMMMUIdx_Stage2_S:
192
+ if (using16k) {
193
+ ds = cpu_isar_feature(aa64_tgran16_2_lpa2, cpu);
194
+ } else {
195
+ ds = cpu_isar_feature(aa64_tgran4_2_lpa2, cpu);
196
+ }
197
+ break;
198
+ default:
199
+ if (using16k) {
200
+ ds = cpu_isar_feature(aa64_tgran16_lpa2, cpu);
201
+ } else {
202
+ ds = cpu_isar_feature(aa64_tgran4_lpa2, cpu);
203
+ }
204
+ break;
205
+ }
206
+ if (ds) {
207
min_tsz = 12;
208
}
209
}
210
- /* TODO: FEAT_LPA2 */
211
212
if (tsz > max_tsz) {
213
tsz = max_tsz;
214
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
215
return (ARMVAParameters) {
216
.tsz = tsz,
217
.ps = ps,
218
+ .sh = sh,
219
.select = select,
220
.tbi = tbi,
221
.epd = epd,
222
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
223
.using16k = using16k,
224
.using64k = using64k,
225
.tsz_oob = tsz_oob,
226
+ .ds = ds,
227
};
46
}
228
}
47
229
48
static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
230
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
49
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
231
* VTCR_EL2.SL0 field (whose interpretation depends on the page size)
50
* We cannot write 16 bytes at once because the
232
*/
51
* destination is unaligned.
233
uint32_t sl0 = extract32(tcr->raw_tcr, 6, 2);
52
*/
234
+ uint32_t sl2 = extract64(tcr->raw_tcr, 33, 1);
53
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
235
uint32_t startlevel;
54
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(vd),
236
bool ok;
55
8, 8, tmp);
237
56
- tcg_gen_gvec_mov(0, neon_reg_offset(vd + 1, 0),
238
- if (!aarch64 || stride == 9) {
57
- neon_reg_offset(vd, 0), 8, 8);
239
+ /* SL2 is RES0 unless DS=1 & 4kb granule. */
58
+ tcg_gen_gvec_mov(0, neon_full_reg_offset(vd + 1),
240
+ if (param.ds && stride == 9 && sl2) {
59
+ neon_full_reg_offset(vd), 8, 8);
241
+ if (sl0 != 0) {
60
} else {
242
+ level = 0;
61
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
243
+ fault_type = ARMFault_Translation;
62
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(vd),
244
+ goto do_fault;
63
vec_size, vec_size, tmp);
245
+ }
64
}
246
+ startlevel = -1;
65
tcg_gen_addi_i32(addr, addr, 1 << size);
247
+ } else if (!aarch64 || stride == 9) {
66
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
248
/* AArch32 or 4KB pages */
67
static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
249
startlevel = 2 - sl0;
68
{
250
69
int vec_size = a->q ? 16 : 8;
251
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
70
- int rd_ofs = neon_reg_offset(a->vd, 0);
252
* for both v7 and v8. However, for v8 the SBZ bits [47:40] must be 0
71
- int rn_ofs = neon_reg_offset(a->vn, 0);
253
* or an AddressSize fault is raised. So for v8 we extract those SBZ
72
- int rm_ofs = neon_reg_offset(a->vm, 0);
254
* bits as part of the address, which will be checked via outputsize.
73
+ int rd_ofs = neon_full_reg_offset(a->vd);
255
- * For AArch64, the address field always goes up to bit 47 (with extra
74
+ int rn_ofs = neon_full_reg_offset(a->vn);
256
- * bits for FEAT_LPA placed elsewhere). AArch64 implies v8.
75
+ int rm_ofs = neon_full_reg_offset(a->vm);
257
+ * For AArch64, the address field goes up to bit 47, or 49 with FEAT_LPA2;
76
258
+ * the highest bits of a 52-bit output are placed elsewhere.
77
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
259
*/
78
return false;
260
- if (arm_feature(env, ARM_FEATURE_V8)) {
79
@@ -XXX,XX +XXX,XX @@ static bool do_vector_2sh(DisasContext *s, arg_2reg_shift *a, GVecGen2iFn *fn)
261
+ if (param.ds) {
80
{
262
+ descaddrmask = MAKE_64BIT_MASK(0, 50);
81
/* Handle a 2-reg-shift insn which can be vectorized. */
263
+ } else if (arm_feature(env, ARM_FEATURE_V8)) {
82
int vec_size = a->q ? 16 : 8;
264
descaddrmask = MAKE_64BIT_MASK(0, 48);
83
- int rd_ofs = neon_reg_offset(a->vd, 0);
265
} else {
84
- int rm_ofs = neon_reg_offset(a->vm, 0);
266
descaddrmask = MAKE_64BIT_MASK(0, 40);
85
+ int rd_ofs = neon_full_reg_offset(a->vd);
267
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
86
+ int rm_ofs = neon_full_reg_offset(a->vm);
268
87
269
/*
88
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
270
* For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12]
89
return false;
271
- * of descriptor. Otherwise, if descaddr is out of range, raise
90
@@ -XXX,XX +XXX,XX @@ static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a,
272
- * AddressSizeFault.
91
{
273
+ * of descriptor. For FEAT_LPA2 and effective DS, bits [51:50] of
92
/* FP operations in 2-reg-and-shift group */
274
+ * descaddr are in [9:8]. Otherwise, if descaddr is out of range,
93
int vec_size = a->q ? 16 : 8;
275
+ * raise AddressSizeFault.
94
- int rd_ofs = neon_reg_offset(a->vd, 0);
276
*/
95
- int rm_ofs = neon_reg_offset(a->vm, 0);
277
if (outputsize > 48) {
96
+ int rd_ofs = neon_full_reg_offset(a->vd);
278
- descaddr |= extract64(descriptor, 12, 4) << 48;
97
+ int rm_ofs = neon_full_reg_offset(a->vm);
279
+ if (param.ds) {
98
TCGv_ptr fpst;
280
+ descaddr |= extract64(descriptor, 8, 2) << 50;
99
281
+ } else {
100
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
282
+ descaddr |= extract64(descriptor, 12, 4) << 48;
101
@@ -XXX,XX +XXX,XX @@ static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
283
+ }
102
return true;
284
} else if (descaddr >> outputsize) {
103
}
285
fault_type = ARMFault_AddressSize;
104
286
goto do_fault;
105
- reg_ofs = neon_reg_offset(a->vd, 0);
287
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
106
+ reg_ofs = neon_full_reg_offset(a->vd);
288
assert(attrindx <= 7);
107
vec_size = a->q ? 16 : 8;
289
cacheattrs->attrs = extract64(mair, attrindx * 8, 8);
108
imm = asimd_imm_const(a->imm, a->cmode, a->op);
290
}
109
291
- cacheattrs->shareability = extract32(attrs, 6, 2);
110
@@ -XXX,XX +XXX,XX @@ static bool trans_VMULL_P_3d(DisasContext *s, arg_3diff *a)
292
+
111
return true;
293
+ /*
112
}
294
+ * For FEAT_LPA2 and effective DS, the SH field in the attributes
113
295
+ * was re-purposed for output address bits. The SH attribute in
114
- tcg_gen_gvec_3_ool(neon_reg_offset(a->vd, 0),
296
+ * that case comes from TCR_ELx, which we extracted earlier.
115
- neon_reg_offset(a->vn, 0),
297
+ */
116
- neon_reg_offset(a->vm, 0),
298
+ if (param.ds) {
117
+ tcg_gen_gvec_3_ool(neon_full_reg_offset(a->vd),
299
+ cacheattrs->shareability = param.sh;
118
+ neon_full_reg_offset(a->vn),
300
+ } else {
119
+ neon_full_reg_offset(a->vm),
301
+ cacheattrs->shareability = extract32(attrs, 6, 2);
120
16, 16, 0, fn_gvec);
302
+ }
121
return true;
303
122
}
304
*phys_ptr = descaddr;
123
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_fp_vec(DisasContext *s, arg_2scalar *a,
305
*page_size_ptr = page_size;
124
{
125
/* Two registers and a scalar, using gvec */
126
int vec_size = a->q ? 16 : 8;
127
- int rd_ofs = neon_reg_offset(a->vd, 0);
128
- int rn_ofs = neon_reg_offset(a->vn, 0);
129
+ int rd_ofs = neon_full_reg_offset(a->vd);
130
+ int rn_ofs = neon_full_reg_offset(a->vn);
131
int rm_ofs;
132
int idx;
133
TCGv_ptr fpstatus;
134
@@ -XXX,XX +XXX,XX @@ static bool do_2scalar_fp_vec(DisasContext *s, arg_2scalar *a,
135
/* a->vm is M:Vm, which encodes both register and index */
136
idx = extract32(a->vm, a->size + 2, 2);
137
a->vm = extract32(a->vm, 0, a->size + 2);
138
- rm_ofs = neon_reg_offset(a->vm, 0);
139
+ rm_ofs = neon_full_reg_offset(a->vm);
140
141
fpstatus = fpstatus_ptr(a->size == 1 ? FPST_STD_F16 : FPST_STD);
142
tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, fpstatus,
143
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
144
return true;
145
}
146
147
- tcg_gen_gvec_dup_mem(a->size, neon_reg_offset(a->vd, 0),
148
+ tcg_gen_gvec_dup_mem(a->size, neon_full_reg_offset(a->vd),
149
neon_element_offset(a->vm, a->index, a->size),
150
a->q ? 16 : 8, a->q ? 16 : 8);
151
return true;
152
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
153
static bool do_2misc_vec(DisasContext *s, arg_2misc *a, GVecGen2Fn *fn)
154
{
155
int vec_size = a->q ? 16 : 8;
156
- int rd_ofs = neon_reg_offset(a->vd, 0);
157
- int rm_ofs = neon_reg_offset(a->vm, 0);
158
+ int rd_ofs = neon_full_reg_offset(a->vd);
159
+ int rm_ofs = neon_full_reg_offset(a->vm);
160
161
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
162
return false;
163
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
164
index XXXXXXX..XXXXXXX 100644
165
--- a/target/arm/translate-vfp.c.inc
166
+++ b/target/arm/translate-vfp.c.inc
167
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
168
}
169
170
tmp = load_reg(s, a->rt);
171
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(a->vn, 0),
172
+ tcg_gen_gvec_dup_i32(size, neon_full_reg_offset(a->vn),
173
vec_size, vec_size, tmp);
174
tcg_temp_free_i32(tmp);
175
176
--
306
--
177
2.20.1
307
2.25.1
178
179
diff view generated by jsdifflib
1
In the neon_padd/pmax/pmin helpers for float16, a cut-and-paste error
1
When we're using KVM, the PSCI implementation is provided by the
2
meant we were using the H4() address swizzler macro rather than the
2
kernel, but QEMU has to tell the guest about it via the device tree.
3
H2() which is required for 2-byte data. This had no effect on
3
Currently we look at the KVM_CAP_ARM_PSCI_0_2 capability to determine
4
little-endian hosts but meant we put the result data into the
4
if the kernel is providing at least PSCI 0.2, but if the kernel
5
destination Dreg in the wrong order on big-endian hosts.
5
provides a newer version than that we will still only tell the guest
6
it has PSCI 0.2. (This is fairly harmless; it just means the guest
7
won't use newer parts of the PSCI API.)
8
9
The kernel exposes the specific PSCI version it is implementing via
10
the ONE_REG API; use this to report in the dtb that the PSCI
11
implementation is 1.0-compatible if appropriate. (The device tree
12
binding currently only distinguishes "pre-0.2", "0.2-compatible" and
13
"1.0-compatible".)
6
14
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Marc Zyngier <maz@kernel.org>
17
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Reviewed-by: Andrew Jones <drjones@redhat.com>
10
Message-id: 20201028191712.4910-2-peter.maydell@linaro.org
20
Message-id: 20220224134655.1207865-1-peter.maydell@linaro.org
11
---
21
---
12
target/arm/vec_helper.c | 8 ++++----
22
target/arm/kvm-consts.h | 1 +
13
1 file changed, 4 insertions(+), 4 deletions(-)
23
hw/arm/boot.c | 5 ++---
24
target/arm/kvm64.c | 12 ++++++++++++
25
3 files changed, 15 insertions(+), 3 deletions(-)
14
26
15
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
27
diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h
16
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/vec_helper.c
29
--- a/target/arm/kvm-consts.h
18
+++ b/target/arm/vec_helper.c
30
+++ b/target/arm/kvm-consts.h
19
@@ -XXX,XX +XXX,XX @@ DO_ABA(gvec_uaba_d, uint64_t)
31
@@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_1_0_FN_PSCI_FEATURES, PSCI_1_0_FN_PSCI_FEATURES);
20
r2 = float16_##OP(m[H2(0)], m[H2(1)], fpst); \
32
21
r3 = float16_##OP(m[H2(2)], m[H2(3)], fpst); \
33
#define QEMU_PSCI_VERSION_0_1 0x00001
22
\
34
#define QEMU_PSCI_VERSION_0_2 0x00002
23
- d[H4(0)] = r0; \
35
+#define QEMU_PSCI_VERSION_1_0 0x10000
24
- d[H4(1)] = r1; \
36
#define QEMU_PSCI_VERSION_1_1 0x10001
25
- d[H4(2)] = r2; \
37
26
- d[H4(3)] = r3; \
38
MISMATCH_CHECK(QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED, PSCI_0_2_TOS_MP);
27
+ d[H2(0)] = r0; \
39
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
28
+ d[H2(1)] = r1; \
40
index XXXXXXX..XXXXXXX 100644
29
+ d[H2(2)] = r2; \
41
--- a/hw/arm/boot.c
30
+ d[H2(3)] = r3; \
42
+++ b/hw/arm/boot.c
43
@@ -XXX,XX +XXX,XX @@ static void fdt_add_psci_node(void *fdt)
31
}
44
}
32
45
33
DO_NEON_PAIRWISE(neon_padd, add)
46
qemu_fdt_add_subnode(fdt, "/psci");
47
- if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2 ||
48
- armcpu->psci_version == QEMU_PSCI_VERSION_1_1) {
49
- if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2) {
50
+ if (armcpu->psci_version >= QEMU_PSCI_VERSION_0_2) {
51
+ if (armcpu->psci_version < QEMU_PSCI_VERSION_1_0) {
52
const char comp[] = "arm,psci-0.2\0arm,psci";
53
qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
54
} else {
55
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/kvm64.c
58
+++ b/target/arm/kvm64.c
59
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
60
uint64_t mpidr;
61
ARMCPU *cpu = ARM_CPU(cs);
62
CPUARMState *env = &cpu->env;
63
+ uint64_t psciver;
64
65
if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE ||
66
!object_dynamic_cast(OBJECT(cpu), TYPE_AARCH64_CPU)) {
67
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
68
}
69
}
70
71
+ /*
72
+ * KVM reports the exact PSCI version it is implementing via a
73
+ * special sysreg. If it is present, use its contents to determine
74
+ * what to report to the guest in the dtb (it is the PSCI version,
75
+ * in the same 15-bits major 16-bits minor format that PSCI_VERSION
76
+ * returns).
77
+ */
78
+ if (!kvm_get_one_reg(cs, KVM_REG_ARM_PSCI_VERSION, &psciver)) {
79
+ cpu->psci_version = psciver;
80
+ }
81
+
82
/*
83
* When KVM is in use, PSCI is emulated in-kernel and not by qemu.
84
* Currently KVM has its own idea about MPIDR assignment, so we
34
--
85
--
35
2.20.1
86
2.25.1
36
37
diff view generated by jsdifflib
1
From: AlexChen <alex.chen@huawei.com>
1
The updateUIInfo method makes Cocoa API calls. It also calls back
2
into QEMU functions like dpy_set_ui_info(). To do this safely, we
3
need to follow two rules:
4
* Cocoa API calls are made on the Cocoa UI thread
5
* When calling back into QEMU we must hold the iothread lock
2
6
3
In omap_lcd_interrupts(), the pointer omap_lcd is dereferinced before
7
Fix the places where we got this wrong, by taking the iothread lock
4
being check if it is valid, which may lead to NULL pointer dereference.
8
while executing updateUIInfo, and moving the call in cocoa_switch()
5
So move the assignment to surface after checking that the omap_lcd is valid
9
inside the dispatch_async block.
6
and move surface_bits_per_pixel(surface) to after the surface assignment.
7
10
8
Reported-by: Euler Robot <euler.robot@huawei.com>
11
Some of the Cocoa UI methods which call updateUIInfo are invoked as
9
Signed-off-by: AlexChen <alex.chen@huawei.com>
12
part of the initial application startup, while we're still doing the
10
Message-id: 5F9CDB8A.9000001@huawei.com
13
little cross-thread dance described in the comment just above
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
call_qemu_main(). This meant they were calling back into the QEMU UI
15
layer before we'd actually finished initializing our display and
16
registered the DisplayChangeListener, which isn't really valid. Once
17
updateUIInfo takes the iothread lock, we no longer get away with
18
this, because during this startup phase the iothread lock is held by
19
the QEMU main-loop thread which is waiting for us to finish our
20
display initialization. So we must suppress updateUIInfo until
21
applicationDidFinishLaunching allows the QEMU main-loop thread to
22
continue.
23
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
26
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
27
Message-id: 20220224101330.967429-2-peter.maydell@linaro.org
13
---
28
---
14
hw/display/omap_lcdc.c | 10 +++++++---
29
ui/cocoa.m | 25 ++++++++++++++++++++++---
15
1 file changed, 7 insertions(+), 3 deletions(-)
30
1 file changed, 22 insertions(+), 3 deletions(-)
16
31
17
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
32
diff --git a/ui/cocoa.m b/ui/cocoa.m
18
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/display/omap_lcdc.c
34
--- a/ui/cocoa.m
20
+++ b/hw/display/omap_lcdc.c
35
+++ b/ui/cocoa.m
21
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
36
@@ -XXX,XX +XXX,XX @@ QemuCocoaView *cocoaView;
22
static void omap_update_display(void *opaque)
37
}
38
}
39
40
-- (void) updateUIInfo
41
+- (void) updateUIInfoLocked
23
{
42
{
24
struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
43
+ /* Must be called with the iothread lock, i.e. via updateUIInfo */
25
- DisplaySurface *surface = qemu_console_surface(omap_lcd->con);
44
NSSize frameSize;
26
+ DisplaySurface *surface;
45
QemuUIInfo info;
27
draw_line_func draw_line;
46
28
int size, height, first, last;
47
@@ -XXX,XX +XXX,XX @@ QemuCocoaView *cocoaView;
29
int width, linesize, step, bpp, frame_offset;
48
dpy_set_ui_info(dcl.con, &info, TRUE);
30
hwaddr frame_base;
49
}
31
50
32
- if (!omap_lcd || omap_lcd->plm == 1 || !omap_lcd->enable ||
51
+- (void) updateUIInfo
33
- !surface_bits_per_pixel(surface)) {
52
+{
34
+ if (!omap_lcd || omap_lcd->plm == 1 || !omap_lcd->enable) {
53
+ if (!allow_events) {
54
+ /*
55
+ * Don't try to tell QEMU about UI information in the application
56
+ * startup phase -- we haven't yet registered dcl with the QEMU UI
57
+ * layer, and also trying to take the iothread lock would deadlock.
58
+ * When cocoa_display_init() does register the dcl, the UI layer
59
+ * will call cocoa_switch(), which will call updateUIInfo, so
60
+ * we don't lose any information here.
61
+ */
35
+ return;
62
+ return;
36
+ }
63
+ }
37
+
64
+
38
+ surface = qemu_console_surface(omap_lcd->con);
65
+ with_iothread_lock(^{
39
+ if (!surface_bits_per_pixel(surface)) {
66
+ [self updateUIInfoLocked];
40
return;
67
+ });
41
}
68
+}
42
69
+
70
- (void)viewDidMoveToWindow
71
{
72
[self updateUIInfo];
73
@@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl,
74
75
COCOA_DEBUG("qemu_cocoa: cocoa_switch\n");
76
77
- [cocoaView updateUIInfo];
78
-
79
// The DisplaySurface will be freed as soon as this callback returns.
80
// We take a reference to the underlying pixman image here so it does
81
// not disappear from under our feet; the switchSurface method will
82
@@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl,
83
pixman_image_ref(image);
84
85
dispatch_async(dispatch_get_main_queue(), ^{
86
+ [cocoaView updateUIInfo];
87
[cocoaView switchSurface:image];
88
});
89
[pool release];
43
--
90
--
44
2.20.1
91
2.25.1
45
46
diff view generated by jsdifflib
1
In gicv3_init_cpuif() we copy the ARMCPU gicv3_maintenance_interrupt
1
In commit 6e657e64cdc478 in 2013 we added some autorelease pools to
2
into the GICv3CPUState struct's maintenance_irq field. This will
2
deal with complaints from macOS when we made calls into Cocoa from
3
only work if the board happens to have already wired up the CPU
3
threads that didn't have automatically created autorelease pools.
4
maintenance IRQ before the GIC was realized. Unfortunately this is
4
Later on, macOS got stricter about forbidding cross-thread Cocoa
5
not the case for the 'virt' board, and so the value that gets copied
5
calls, and in commit 5588840ff77800e839d8 we restructured the code to
6
is NULL (since a qemu_irq is really a pointer to an IRQState struct
6
avoid them. This left the autorelease pool creation in several
7
under the hood). The effect is that the CPU interface code never
7
functions without any purpose; delete it.
8
actually raises the maintenance interrupt line.
9
8
10
Instead, since the GICv3CPUState has a pointer to the CPUState, make
9
We still need the pool in cocoa_refresh() for the clipboard related
11
the dereference at the point where we want to raise the interrupt, to
10
code which is called directly there.
12
avoid an implicit requirement on board code to wire things up in a
13
particular order.
14
11
15
Reported-by: Jose Martins <josemartins90@gmail.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20201009153904.28529-1-peter.maydell@linaro.org
13
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
18
Reviewed-by: Luc Michel <luc@lmichel.fr>
14
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
15
Message-id: 20220224101330.967429-3-peter.maydell@linaro.org
19
---
16
---
20
include/hw/intc/arm_gicv3_common.h | 1 -
17
ui/cocoa.m | 6 ------
21
hw/intc/arm_gicv3_cpuif.c | 5 ++---
18
1 file changed, 6 deletions(-)
22
2 files changed, 2 insertions(+), 4 deletions(-)
23
19
24
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
20
diff --git a/ui/cocoa.m b/ui/cocoa.m
25
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/intc/arm_gicv3_common.h
22
--- a/ui/cocoa.m
27
+++ b/include/hw/intc/arm_gicv3_common.h
23
+++ b/ui/cocoa.m
28
@@ -XXX,XX +XXX,XX @@ struct GICv3CPUState {
24
@@ -XXX,XX +XXX,XX @@ int main (int argc, char **argv) {
29
qemu_irq parent_fiq;
25
static void cocoa_update(DisplayChangeListener *dcl,
30
qemu_irq parent_virq;
26
int x, int y, int w, int h)
31
qemu_irq parent_vfiq;
27
{
32
- qemu_irq maintenance_irq;
28
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
33
29
-
34
/* Redistributor */
30
COCOA_DEBUG("qemu_cocoa: cocoa_update\n");
35
uint32_t level; /* Current IRQ level */
31
36
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
32
dispatch_async(dispatch_get_main_queue(), ^{
37
index XXXXXXX..XXXXXXX 100644
33
@@ -XXX,XX +XXX,XX @@ static void cocoa_update(DisplayChangeListener *dcl,
38
--- a/hw/intc/arm_gicv3_cpuif.c
34
}
39
+++ b/hw/intc/arm_gicv3_cpuif.c
35
[cocoaView setNeedsDisplayInRect:rect];
40
@@ -XXX,XX +XXX,XX @@ static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
36
});
41
int irqlevel = 0;
37
-
42
int fiqlevel = 0;
38
- [pool release];
43
int maintlevel = 0;
44
+ ARMCPU *cpu = ARM_CPU(cs->cpu);
45
46
idx = hppvi_index(cs);
47
trace_gicv3_cpuif_virt_update(gicv3_redist_affid(cs), idx);
48
@@ -XXX,XX +XXX,XX @@ static void gicv3_cpuif_virt_update(GICv3CPUState *cs)
49
50
qemu_set_irq(cs->parent_vfiq, fiqlevel);
51
qemu_set_irq(cs->parent_virq, irqlevel);
52
- qemu_set_irq(cs->maintenance_irq, maintlevel);
53
+ qemu_set_irq(cpu->gicv3_maintenance_interrupt, maintlevel);
54
}
39
}
55
40
56
static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
41
static void cocoa_switch(DisplayChangeListener *dcl,
57
@@ -XXX,XX +XXX,XX @@ void gicv3_init_cpuif(GICv3State *s)
42
DisplaySurface *surface)
58
&& cpu->gic_num_lrs) {
43
{
59
int j;
44
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
60
45
pixman_image_t *image = surface->image;
61
- cs->maintenance_irq = cpu->gicv3_maintenance_interrupt;
46
62
-
47
COCOA_DEBUG("qemu_cocoa: cocoa_switch\n");
63
cs->num_list_regs = cpu->gic_num_lrs;
48
@@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl,
64
cs->vpribits = cpu->gic_vpribits;
49
[cocoaView updateUIInfo];
65
cs->vprebits = cpu->gic_vprebits;
50
[cocoaView switchSurface:image];
51
});
52
- [pool release];
53
}
54
55
static void cocoa_refresh(DisplayChangeListener *dcl)
66
--
56
--
67
2.20.1
57
2.25.1
68
69
diff view generated by jsdifflib