1
Most of this is the Neon decodetree patches, followed by Edgar's versal cleanups.
1
The following changes since commit 64ada298b98a51eb2512607f6e6180cb330c47b1:
2
2
3
thanks
3
Merge remote-tracking branch 'remotes/legoater/tags/pull-ppc-20220302' into staging (2022-03-02 12:38:46 +0000)
4
-- PMM
5
6
7
The following changes since commit 2ef486e76d64436be90f7359a3071fb2a56ce835:
8
9
Merge remote-tracking branch 'remotes/marcel/tags/rdma-pull-request' into staging (2020-05-03 14:12:56 +0100)
10
4
11
are available in the Git repository at:
5
are available in the Git repository at:
12
6
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200504
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220302
14
8
15
for you to fetch changes up to 9aefc6cf9b73f66062d2f914a0136756e7a28211:
9
for you to fetch changes up to 268c11984e67867c22f53beb3c7f8b98900d66b2:
16
10
17
target/arm: Move gen_ function typedefs to translate.h (2020-05-04 12:59:26 +0100)
11
ui/cocoa.m: Remove unnecessary NSAutoreleasePools (2022-03-02 19:27:37 +0000)
18
12
19
----------------------------------------------------------------
13
----------------------------------------------------------------
20
target-arm queue:
14
target-arm queue:
21
* Start of conversion of Neon insns to decodetree
15
* mps3-an547: Add missing user ahb interfaces
22
* versal board: support SD and RTC
16
* hw/arm/mps2-tz.c: Update AN547 documentation URL
23
* Implement ARMv8.2-TTS2UXN
17
* hw/input/tsc210x: Don't abort on bad SPI word widths
24
* Make VQDMULL undefined when U=1
18
* hw/i2c: flatten pca954x mux device
25
* Some minor code cleanups
19
* target/arm: Support PSCI 1.1 and SMCCC 1.0
20
* target/arm: Fix early free of TCG temp in handle_simd_shift_fpint_conv()
21
* tests/qtest: add qtests for npcm7xx sdhci
22
* Implement FEAT_LVA
23
* Implement FEAT_LPA
24
* Implement FEAT_LPA2 (but do not enable it yet)
25
* Report KVM's actual PSCI version to guest in dtb
26
* ui/cocoa.m: Fix updateUIInfo threading issues
27
* ui/cocoa.m: Remove unnecessary NSAutoreleasePools
26
28
27
----------------------------------------------------------------
29
----------------------------------------------------------------
28
Edgar E. Iglesias (11):
30
Akihiko Odaki (1):
29
hw/arm: versal: Remove inclusion of arm_gicv3_common.h
31
target/arm: Support PSCI 1.1 and SMCCC 1.0
30
hw/arm: versal: Move misplaced comment
31
hw/arm: versal-virt: Fix typo xlnx-ve -> xlnx-versal
32
hw/arm: versal: Embed the UARTs into the SoC type
33
hw/arm: versal: Embed the GEMs into the SoC type
34
hw/arm: versal: Embed the ADMAs into the SoC type
35
hw/arm: versal: Embed the APUs into the SoC type
36
hw/arm: versal: Add support for SD
37
hw/arm: versal: Add support for the RTC
38
hw/arm: versal-virt: Add support for SD
39
hw/arm: versal-virt: Add support for the RTC
40
32
41
Fredrik Strupe (1):
33
Jimmy Brisson (1):
42
target/arm: Make VQDMULL undefined when U=1
34
mps3-an547: Add missing user ahb interfaces
43
35
44
Peter Maydell (25):
36
Patrick Venture (1):
45
target/arm: Don't use a TLB for ARMMMUIdx_Stage2
37
hw/i2c: flatten pca954x mux device
46
target/arm: Use enum constant in get_phys_addr_lpae() call
47
target/arm: Add new 's1_is_el0' argument to get_phys_addr_lpae()
48
target/arm: Implement ARMv8.2-TTS2UXN
49
target/arm: Use correct variable for setting 'max' cpu's ID_AA64DFR0
50
target/arm/translate-vfp.inc.c: Remove duplicate simd_r32 check
51
target/arm: Don't allow Thumb Neon insns without FEATURE_NEON
52
target/arm: Add stubs for AArch32 Neon decodetree
53
target/arm: Convert VCMLA (vector) to decodetree
54
target/arm: Convert VCADD (vector) to decodetree
55
target/arm: Convert V[US]DOT (vector) to decodetree
56
target/arm: Convert VFM[AS]L (vector) to decodetree
57
target/arm: Convert VCMLA (scalar) to decodetree
58
target/arm: Convert V[US]DOT (scalar) to decodetree
59
target/arm: Convert VFM[AS]L (scalar) to decodetree
60
target/arm: Convert Neon load/store multiple structures to decodetree
61
target/arm: Convert Neon 'load single structure to all lanes' to decodetree
62
target/arm: Convert Neon 'load/store single structure' to decodetree
63
target/arm: Convert Neon 3-reg-same VADD/VSUB to decodetree
64
target/arm: Convert Neon 3-reg-same logic ops to decodetree
65
target/arm: Convert Neon 3-reg-same VMAX/VMIN to decodetree
66
target/arm: Convert Neon 3-reg-same comparisons to decodetree
67
target/arm: Convert Neon 3-reg-same VQADD/VQSUB to decodetree
68
target/arm: Convert Neon 3-reg-same VMUL, VMLA, VMLS, VSHL to decodetree
69
target/arm: Move gen_ function typedefs to translate.h
70
38
71
Philippe Mathieu-Daudé (2):
39
Peter Maydell (5):
72
hw/arm/mps2-tz: Use TYPE_IOTKIT instead of hardcoded string
40
hw/arm/mps2-tz.c: Update AN547 documentation URL
73
target/arm: Use uint64_t for midr field in CPU state struct
41
hw/input/tsc210x: Don't abort on bad SPI word widths
42
target/arm: Report KVM's actual PSCI version to guest in dtb
43
ui/cocoa.m: Fix updateUIInfo threading issues
44
ui/cocoa.m: Remove unnecessary NSAutoreleasePools
74
45
75
include/hw/arm/xlnx-versal.h | 31 +-
46
Richard Henderson (16):
76
target/arm/cpu-param.h | 2 +-
47
hw/registerfields: Add FIELD_SEX<N> and FIELD_SDP<N>
77
target/arm/cpu.h | 38 ++-
48
target/arm: Set TCR_EL1.TSZ for user-only
78
target/arm/translate-a64.h | 9 -
49
target/arm: Fault on invalid TCR_ELx.TxSZ
79
target/arm/translate.h | 26 ++
50
target/arm: Move arm_pamax out of line
80
target/arm/neon-dp.decode | 86 +++++
51
target/arm: Pass outputsize down to check_s2_mmu_setup
81
target/arm/neon-ls.decode | 52 +++
52
target/arm: Use MAKE_64BIT_MASK to compute indexmask
82
target/arm/neon-shared.decode | 66 ++++
53
target/arm: Honor TCR_ELx.{I}PS
83
hw/arm/mps2-tz.c | 2 +-
54
target/arm: Prepare DBGBVR and DBGWVR for FEAT_LVA
84
hw/arm/xlnx-versal-virt.c | 74 ++++-
55
target/arm: Implement FEAT_LVA
85
hw/arm/xlnx-versal.c | 115 +++++--
56
target/arm: Implement FEAT_LPA
86
target/arm/cpu.c | 3 +-
57
target/arm: Extend arm_fi_to_lfsc to level -1
87
target/arm/cpu64.c | 8 +-
58
target/arm: Introduce tlbi_aa64_get_range
88
target/arm/helper.c | 183 ++++------
59
target/arm: Fix TLBIRange.base for 16k and 64k pages
89
target/arm/translate-a64.c | 17 -
60
target/arm: Validate tlbi TG matches translation granule in use
90
target/arm/translate-neon.inc.c | 714 +++++++++++++++++++++++++++++++++++++++
61
target/arm: Advertise all page sizes for -cpu max
91
target/arm/translate-vfp.inc.c | 6 -
62
target/arm: Implement FEAT_LPA2
92
target/arm/translate.c | 716 +++-------------------------------------
93
target/arm/Makefile.objs | 18 +
94
19 files changed, 1302 insertions(+), 864 deletions(-)
95
create mode 100644 target/arm/neon-dp.decode
96
create mode 100644 target/arm/neon-ls.decode
97
create mode 100644 target/arm/neon-shared.decode
98
create mode 100644 target/arm/translate-neon.inc.c
99
63
64
Shengtan Mao (1):
65
tests/qtest: add qtests for npcm7xx sdhci
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
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Jimmy Brisson <jimmy.brisson@linaro.org>
2
2
3
Embed the UARTs into the SoC type.
3
With these interfaces missing, TFM would delegate peripherals 0, 1,
4
2, 3 and 8, and qemu would ignore the delegation of interface 8, as
5
it thought interface 4 was eth & USB.
4
6
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
7
This patch corrects this behavior and allows TFM to delegate the
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
eth & USB peripheral to NS mode.
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
(The old QEMU behaviour was based on revision B of the AN547
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
11
appnote; revision C corrects this error in the documentation,
10
Message-id: 20200427181649.26851-5-edgar.iglesias@gmail.com
12
and this commit brings QEMU in to line with how the FPGA
13
image really behaves.)
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]
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
22
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
23
hw/arm/mps2-tz.c | 4 ++++
14
hw/arm/xlnx-versal.c | 12 ++++++------
24
1 file changed, 4 insertions(+)
15
2 files changed, 8 insertions(+), 7 deletions(-)
16
25
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
26
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
18
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
28
--- a/hw/arm/mps2-tz.c
20
+++ b/include/hw/arm/xlnx-versal.h
29
+++ b/hw/arm/mps2-tz.c
21
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
22
#include "hw/sysbus.h"
31
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
23
#include "hw/arm/boot.h"
32
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
24
#include "hw/intc/arm_gicv3.h"
33
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
25
+#include "hw/char/pl011.h"
34
+ { /* port 4 USER AHB interface 0 */ },
26
35
+ { /* port 5 USER AHB interface 1 */ },
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
36
+ { /* port 6 USER AHB interface 2 */ },
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
37
+ { /* port 7 USER AHB interface 3 */ },
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
38
{ "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 49 } },
30
MemoryRegion mr_ocm;
39
},
31
40
},
32
struct {
33
- SysBusDevice *uart[XLNX_VERSAL_NR_UARTS];
34
+ PL011State uart[XLNX_VERSAL_NR_UARTS];
35
SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
36
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
37
} iou;
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
41
+++ b/hw/arm/xlnx-versal.c
42
@@ -XXX,XX +XXX,XX @@
43
#include "kvm_arm.h"
44
#include "hw/misc/unimp.h"
45
#include "hw/arm/xlnx-versal.h"
46
-#include "hw/char/pl011.h"
47
48
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
49
#define GEM_REVISION 0x40070106
50
@@ -XXX,XX +XXX,XX @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
51
DeviceState *dev;
52
MemoryRegion *mr;
53
54
- dev = qdev_create(NULL, TYPE_PL011);
55
- s->lpd.iou.uart[i] = SYS_BUS_DEVICE(dev);
56
+ sysbus_init_child_obj(OBJECT(s), name,
57
+ &s->lpd.iou.uart[i], sizeof(s->lpd.iou.uart[i]),
58
+ TYPE_PL011);
59
+ dev = DEVICE(&s->lpd.iou.uart[i]);
60
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
61
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
62
qdev_init_nofail(dev);
63
64
- mr = sysbus_mmio_get_region(s->lpd.iou.uart[i], 0);
65
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
66
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
67
68
- sysbus_connect_irq(s->lpd.iou.uart[i], 0, pic[irqs[i]]);
69
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
70
g_free(name);
71
}
72
}
73
--
41
--
74
2.20.1
42
2.25.1
75
76
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The AN547 application note URL has changed: update our comment
2
accordingly. (Rev B is still downloadable from the old URL,
3
but there is a new Rev C of the document now.)
2
4
3
By using the TYPE_* definitions for devices, we can:
4
- quickly find where devices are used with 'git-grep'
5
- easily rename a device (one-line change).
6
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200428154650.21991-1-f4bug@amsat.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20220221094144.426191-1-peter.maydell@linaro.org
11
---
9
---
12
hw/arm/mps2-tz.c | 2 +-
10
hw/arm/mps2-tz.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 1 insertion(+), 1 deletion(-)
14
12
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2-tz.c
15
--- a/hw/arm/mps2-tz.c
18
+++ b/hw/arm/mps2-tz.c
16
+++ b/hw/arm/mps2-tz.c
19
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
17
@@ -XXX,XX +XXX,XX @@
20
exit(EXIT_FAILURE);
18
* Application Note AN524:
21
}
19
* https://developer.arm.com/documentation/dai0524/latest/
22
20
* Application Note AN547:
23
- sysbus_init_child_obj(OBJECT(machine), "iotkit", &mms->iotkit,
21
- * https://developer.arm.com/-/media/Arm%20Developer%20Community/PDF/DAI0547B_SSE300_PLUS_U55_FPGA_for_mps3.pdf
24
+ sysbus_init_child_obj(OBJECT(machine), TYPE_IOTKIT, &mms->iotkit,
22
+ * https://developer.arm.com/documentation/dai0547/latest/
25
sizeof(mms->iotkit), mmc->armsse_type);
23
*
26
iotkitdev = DEVICE(&mms->iotkit);
24
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
27
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
25
* (ARM ECM0601256) for the details of some of the device layout:
28
--
26
--
29
2.20.1
27
2.25.1
30
28
31
29
diff view generated by jsdifflib
1
Convert the Neon VMUL, VMLA, VMLS and VSHL insns in the
1
The tsc210x doesn't support anything other than 16-bit reads on the
2
3-reg-same grouping to decodetree.
2
SPI bus, but the guest can program the SPI controller to attempt
3
them anyway. If this happens, don't abort QEMU, just log this as
4
a guest error.
3
5
6
This fixes our machine_arm_n8x0.py:N8x0Machine.test_n800
7
acceptance test, which hits this assertion.
8
9
The reason we hit the assertion is because the guest kernel thinks
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.
23
24
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/736
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Message-id: 20200430181003.21682-20-peter.maydell@linaro.org
27
Message-id: 20220221140750.514557-1-peter.maydell@linaro.org
7
---
28
---
8
target/arm/neon-dp.decode | 9 +++++++
29
hw/input/tsc210x.c | 8 ++++++--
9
target/arm/translate-neon.inc.c | 44 +++++++++++++++++++++++++++++++++
30
1 file changed, 6 insertions(+), 2 deletions(-)
10
target/arm/translate.c | 28 +++------------------
11
3 files changed, 56 insertions(+), 25 deletions(-)
12
31
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
32
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
14
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
34
--- a/hw/input/tsc210x.c
16
+++ b/target/arm/neon-dp.decode
35
+++ b/hw/input/tsc210x.c
17
@@ -XXX,XX +XXX,XX @@ VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
36
@@ -XXX,XX +XXX,XX @@
18
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
37
#include "hw/hw.h"
19
VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
38
#include "audio/audio.h"
20
39
#include "qemu/timer.h"
21
+VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same
40
+#include "qemu/log.h"
22
+VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same
41
#include "sysemu/reset.h"
23
+
42
#include "ui/console.h"
24
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
43
#include "hw/arm/omap.h" /* For I2SCodec */
25
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
44
@@ -XXX,XX +XXX,XX @@ uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len)
26
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
45
TSC210xState *s = opaque;
27
@@ -XXX,XX +XXX,XX @@ VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
46
uint32_t ret = 0;
28
47
29
VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
48
- if (len != 16)
30
VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
49
- hw_error("%s: FIXME: bad SPI word width %i\n", __func__, len);
31
+
50
+ if (len != 16) {
32
+VMLA_3s 1111 001 0 0 . .. .... .... 1001 . . . 0 .... @3same
51
+ qemu_log_mask(LOG_GUEST_ERROR,
33
+VMLS_3s 1111 001 1 0 . .. .... .... 1001 . . . 0 .... @3same
52
+ "%s: bad SPI word width %i\n", __func__, len);
34
+
53
+ return 0;
35
+VMUL_3s 1111 001 0 0 . .. .... .... 1001 . . . 1 .... @3same
36
+VMUL_p_3s 1111 001 1 0 . .. .... .... 1001 . . . 1 .... @3same
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-neon.inc.c
40
+++ b/target/arm/translate-neon.inc.c
41
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
42
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
43
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
44
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
45
+DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
46
47
#define DO_3SAME_CMP(INSN, COND) \
48
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
49
@@ -XXX,XX +XXX,XX @@ DO_3SAME_GVEC4(VQADD_S, sqadd_op)
50
DO_3SAME_GVEC4(VQADD_U, uqadd_op)
51
DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
52
DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
53
+
54
+static void gen_VMUL_p_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
55
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
56
+{
57
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz,
58
+ 0, gen_helper_gvec_pmul_b);
59
+}
60
+
61
+static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
62
+{
63
+ if (a->size != 0) {
64
+ return false;
65
+ }
54
+ }
66
+ return do_3same(s, a, gen_VMUL_p_3s);
55
67
+}
56
/* TODO: sequential reads etc - how do we make sure the host doesn't
68
+
57
* unintentionally read out a conversion result from a register while
69
+#define DO_3SAME_GVEC3_NO_SZ_3(INSN, OPARRAY) \
70
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
71
+ uint32_t rn_ofs, uint32_t rm_ofs, \
72
+ uint32_t oprsz, uint32_t maxsz) \
73
+ { \
74
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
75
+ oprsz, maxsz, &OPARRAY[vece]); \
76
+ } \
77
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
78
+
79
+
80
+DO_3SAME_GVEC3_NO_SZ_3(VMLA, mla_op)
81
+DO_3SAME_GVEC3_NO_SZ_3(VMLS, mls_op)
82
+
83
+#define DO_3SAME_GVEC3_SHIFT(INSN, OPARRAY) \
84
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
85
+ uint32_t rn_ofs, uint32_t rm_ofs, \
86
+ uint32_t oprsz, uint32_t maxsz) \
87
+ { \
88
+ /* Note the operation is vshl vd,vm,vn */ \
89
+ tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, \
90
+ oprsz, maxsz, &OPARRAY[vece]); \
91
+ } \
92
+ DO_3SAME(INSN, gen_##INSN##_3s)
93
+
94
+DO_3SAME_GVEC3_SHIFT(VSHL_S, sshl_op)
95
+DO_3SAME_GVEC3_SHIFT(VSHL_U, ushl_op)
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
101
}
102
return 1;
103
104
- case NEON_3R_VMUL: /* VMUL */
105
- if (u) {
106
- /* Polynomial case allows only P8. */
107
- if (size != 0) {
108
- return 1;
109
- }
110
- tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
111
- 0, gen_helper_gvec_pmul_b);
112
- } else {
113
- tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
114
- vec_size, vec_size);
115
- }
116
- return 0;
117
-
118
- case NEON_3R_VML: /* VMLA, VMLS */
119
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
120
- u ? &mls_op[size] : &mla_op[size]);
121
- return 0;
122
-
123
- case NEON_3R_VSHL:
124
- /* Note the operation is vshl vd,vm,vn */
125
- tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
126
- u ? &ushl_op[size] : &sshl_op[size]);
127
- return 0;
128
-
129
case NEON_3R_VADD_VSUB:
130
case NEON_3R_LOGIC:
131
case NEON_3R_VMAX:
132
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
133
case NEON_3R_VCGE:
134
case NEON_3R_VQADD:
135
case NEON_3R_VQSUB:
136
+ case NEON_3R_VMUL:
137
+ case NEON_3R_VML:
138
+ case NEON_3R_VSHL:
139
/* Already handled by decodetree */
140
return 1;
141
}
142
--
58
--
143
2.20.1
59
2.25.1
144
60
145
61
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Patrick Venture <venture@google.com>
2
2
3
Add support for SD.
3
Previously this device created N subdevices which each owned an i2c bus.
4
Now this device simply owns the N i2c busses directly.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Tested: Verified devices behind mux are still accessible via qmp and i2c
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
from within an arm32 SoC.
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
8
Message-id: 20200427181649.26851-11-edgar.iglesias@gmail.com
9
Reviewed-by: Hao Wu <wuhaotsh@google.com>
10
Signed-off-by: Patrick Venture <venture@google.com>
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
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
15
---
11
hw/arm/xlnx-versal-virt.c | 46 +++++++++++++++++++++++++++++++++++++++
16
hw/i2c/i2c_mux_pca954x.c | 77 +++++++---------------------------------
12
1 file changed, 46 insertions(+)
17
1 file changed, 13 insertions(+), 64 deletions(-)
13
18
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
19
diff --git a/hw/i2c/i2c_mux_pca954x.c b/hw/i2c/i2c_mux_pca954x.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
21
--- a/hw/i2c/i2c_mux_pca954x.c
17
+++ b/hw/arm/xlnx-versal-virt.c
22
+++ b/hw/i2c/i2c_mux_pca954x.c
18
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
19
#include "hw/arm/sysbus-fdt.h"
24
#define PCA9548_CHANNEL_COUNT 8
20
#include "hw/arm/fdt.h"
25
#define PCA9546_CHANNEL_COUNT 4
21
#include "cpu.h"
26
22
+#include "hw/qdev-properties.h"
27
-/*
23
#include "hw/arm/xlnx-versal.h"
28
- * struct Pca954xChannel - The i2c mux device will have N of these states
24
29
- * that own the i2c channel bus.
25
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
30
- * @bus: The owned channel bus.
26
@@ -XXX,XX +XXX,XX @@ static void fdt_add_zdma_nodes(VersalVirt *s)
31
- * @enabled: Is this channel active?
32
- */
33
-typedef struct Pca954xChannel {
34
- SysBusDevice parent;
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
}
27
}
83
}
28
}
84
}
29
85
@@ -XXX,XX +XXX,XX @@ I2CBus *pca954x_i2c_get_bus(I2CSlave *mux, uint8_t channel)
30
+static void fdt_add_sd_nodes(VersalVirt *s)
86
Pca954xState *pca954x = PCA954X(mux);
31
+{
87
32
+ const char clocknames[] = "clk_xin\0clk_ahb";
88
g_assert(channel < pc->nchans);
33
+ const char compat[] = "arasan,sdhci-8.9a";
89
- return I2C_BUS(qdev_get_child_bus(DEVICE(&pca954x->channel[channel]),
34
+ int i;
90
- "i2c-bus"));
91
-}
92
-
93
-static void pca954x_channel_init(Object *obj)
94
-{
95
- Pca954xChannel *s = PCA954X_CHANNEL(obj);
96
- s->bus = i2c_init_bus(DEVICE(s), "i2c-bus");
97
-
98
- /* Start all channels as disabled. */
99
- s->enabled = false;
100
-}
101
-
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)
127
{
128
Pca954xState *s = PCA954X(obj);
129
Pca954xClass *c = PCA954X_GET_CLASS(obj);
130
int i;
131
132
- /* Only initialize the children we expect. */
133
+ /* SMBus modules. Cannot fail. */
134
for (i = 0; i < c->nchans; i++) {
135
- object_initialize_child(obj, "channel[*]", &s->channel[i],
136
- TYPE_PCA954X_CHANNEL);
137
+ g_autofree gchar *bus_name = g_strdup_printf("i2c.%d", i);
35
+
138
+
36
+ for (i = ARRAY_SIZE(s->soc.pmc.iou.sd) - 1; i >= 0; i--) {
139
+ /* start all channels as disabled. */
37
+ uint64_t addr = MM_PMC_SD0 + MM_PMC_SD0_SIZE * i;
140
+ s->enabled[i] = false;
38
+ char *name = g_strdup_printf("/sdhci@%" PRIx64, addr);
141
+ s->bus[i] = i2c_init_bus(DEVICE(s), bus_name);
39
+
40
+ qemu_fdt_add_subnode(s->fdt, name);
41
+
42
+ qemu_fdt_setprop_cells(s->fdt, name, "clocks",
43
+ s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
44
+ qemu_fdt_setprop(s->fdt, name, "clock-names",
45
+ clocknames, sizeof(clocknames));
46
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
47
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_SD0_IRQ_0 + i * 2,
48
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
49
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
50
+ 2, addr, 2, MM_PMC_SD0_SIZE);
51
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
52
+ g_free(name);
53
+ }
54
+}
55
+
56
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
57
{
58
Error *err = NULL;
59
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
60
}
142
}
61
}
143
}
62
144
63
+static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
145
@@ -XXX,XX +XXX,XX @@ static void pca954x_class_init(ObjectClass *klass, void *data)
64
+{
146
rc->phases.enter = pca954x_enter_reset;
65
+ BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
147
66
+ DeviceState *card;
148
dc->desc = "Pca954x i2c-mux";
67
+
149
- dc->realize = pca954x_realize;
68
+ card = qdev_create(qdev_get_child_bus(DEVICE(sd), "sd-bus"), TYPE_SD_CARD);
150
69
+ object_property_add_child(OBJECT(sd), "card[*]", OBJECT(card),
151
k->write_data = pca954x_write_data;
70
+ &error_fatal);
152
k->receive_byte = pca954x_read_byte;
71
+ qdev_prop_set_drive(card, "drive", blk, &error_fatal);
153
@@ -XXX,XX +XXX,XX @@ static const TypeInfo pca954x_info[] = {
72
+ object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
154
.parent = TYPE_PCA954X,
73
+}
155
.class_init = pca9548_class_init,
74
+
156
},
75
static void versal_virt_init(MachineState *machine)
157
- {
76
{
158
- .name = TYPE_PCA954X_CHANNEL,
77
VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
159
- .parent = TYPE_SYS_BUS_DEVICE,
78
int psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
160
- .class_init = pca954x_channel_class_init,
79
+ int i;
161
- .instance_size = sizeof(Pca954xChannel),
80
162
- .instance_init = pca954x_channel_init,
81
/*
163
- }
82
* If the user provides an Operating System to be loaded, we expect them
164
};
83
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
165
84
fdt_add_gic_nodes(s);
166
DEFINE_TYPES(pca954x_info)
85
fdt_add_timer_nodes(s);
86
fdt_add_zdma_nodes(s);
87
+ fdt_add_sd_nodes(s);
88
fdt_add_cpu_nodes(s, psci_conduit);
89
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
90
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
91
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
92
memory_region_add_subregion_overlap(get_system_memory(),
93
0, &s->soc.fpd.apu.mr, 0);
94
95
+ /* Plugin SD cards. */
96
+ for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
97
+ sd_plugin_card(&s->soc.pmc.iou.sd[i], drive_get_next(IF_SD));
98
+ }
99
+
100
s->binfo.ram_size = machine->ram_size;
101
s->binfo.loader_start = 0x0;
102
s->binfo.get_dtb = versal_virt_get_dtb;
103
--
167
--
104
2.20.1
168
2.25.1
105
169
106
170
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Akihiko Odaki <akihiko.odaki@gmail.com>
2
2
3
Add support for the RTC.
3
Support the latest PSCI on TCG and HVF. A 64-bit function called from
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.
4
7
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20220213035753.34577-1-akihiko.odaki@gmail.com
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20200427181649.26851-12-edgar.iglesias@gmail.com
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/xlnx-versal-virt.c | 22 ++++++++++++++++++++++
14
target/arm/kvm-consts.h | 13 +++++++++----
12
1 file changed, 22 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
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
22
diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h
15
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
24
--- a/target/arm/kvm-consts.h
17
+++ b/hw/arm/xlnx-versal-virt.c
25
+++ b/target/arm/kvm-consts.h
18
@@ -XXX,XX +XXX,XX @@ static void fdt_add_sd_nodes(VersalVirt *s)
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
61
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/boot.c
64
+++ b/hw/arm/boot.c
65
@@ -XXX,XX +XXX,XX @@ static void fdt_add_psci_node(void *fdt)
66
}
67
68
qemu_fdt_add_subnode(fdt, "/psci");
69
- if (armcpu->psci_version == 2) {
70
- const char comp[] = "arm,psci-0.2\0arm,psci";
71
- qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
72
+ if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2 ||
73
+ armcpu->psci_version == QEMU_PSCI_VERSION_1_1) {
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;
19
}
100
}
20
}
101
}
21
102
22
+static void fdt_add_rtc_node(VersalVirt *s)
103
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
23
+{
104
index XXXXXXX..XXXXXXX 100644
24
+ const char compat[] = "xlnx,zynqmp-rtc";
105
--- a/target/arm/hvf/hvf.c
25
+ const char interrupt_names[] = "alarm\0sec";
106
+++ b/target/arm/hvf/hvf.c
26
+ char *name = g_strdup_printf("/rtc@%x", MM_PMC_RTC);
107
@@ -XXX,XX +XXX,XX @@ static bool hvf_handle_psci_call(CPUState *cpu)
27
+
108
28
+ qemu_fdt_add_subnode(s->fdt, name);
109
switch (param[0]) {
29
+
110
case QEMU_PSCI_0_2_FN_PSCI_VERSION:
30
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
111
- ret = QEMU_PSCI_0_2_RET_VERSION_0_2;
31
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_ALARM_IRQ,
112
+ ret = QEMU_PSCI_VERSION_1_1;
32
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI,
113
break;
33
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_SECONDS_IRQ,
114
case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
34
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
115
ret = QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED; /* No trusted OS */
35
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
116
@@ -XXX,XX +XXX,XX @@ static bool hvf_handle_psci_call(CPUState *cpu)
36
+ interrupt_names, sizeof(interrupt_names));
117
case QEMU_PSCI_0_2_FN_MIGRATE:
37
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
118
ret = QEMU_PSCI_RET_NOT_SUPPORTED;
38
+ 2, MM_PMC_RTC, 2, MM_PMC_RTC_SIZE);
119
break;
39
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
120
+ case QEMU_PSCI_1_0_FN_PSCI_FEATURES:
40
+ g_free(name);
121
+ switch (param[1]) {
41
+}
122
+ case QEMU_PSCI_0_2_FN_PSCI_VERSION:
42
+
123
+ case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
43
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
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)
44
{
166
{
45
Error *err = NULL;
167
/*
46
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
168
* This function partially implements the logic for dispatching Power State
47
fdt_add_timer_nodes(s);
169
- * Coordination Interface (PSCI) calls (as described in ARM DEN 0022B.b),
48
fdt_add_zdma_nodes(s);
170
+ * Coordination Interface (PSCI) calls (as described in ARM DEN 0022D.b),
49
fdt_add_sd_nodes(s);
171
* to the extent required for bringing up and taking down secondary cores,
50
+ fdt_add_rtc_node(s);
172
* and for handling reset and poweroff requests.
51
fdt_add_cpu_nodes(s, psci_conduit);
173
* Additional information about the calling convention used is available in
52
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
174
@@ -XXX,XX +XXX,XX @@ void arm_handle_psci_call(ARMCPU *cpu)
53
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
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:
54
--
228
--
55
2.20.1
229
2.25.1
56
57
diff view generated by jsdifflib
1
We're going to want at least some of the NeonGen* typedefs
1
From: Wentao_Liang <Wentao_Liang_g@163.com>
2
for the refactored 32-bit Neon decoder, so move them all
3
to translate.h since it makes more sense to keep them in
4
one group.
5
2
3
handle_simd_shift_fpint_conv() was accidentally freeing the TCG
4
temporary tcg_fpstatus too early, before the last use of it. Move
5
the free down to where it belongs.
6
7
Signed-off-by: Wentao_Liang <Wentao_Liang_g@163.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
[PMM: cleaned up commit message]
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200430181003.21682-23-peter.maydell@linaro.org
9
---
11
---
10
target/arm/translate.h | 17 +++++++++++++++++
12
target/arm/translate-a64.c | 2 +-
11
target/arm/translate-a64.c | 17 -----------------
13
1 file changed, 1 insertion(+), 1 deletion(-)
12
2 files changed, 17 insertions(+), 17 deletions(-)
13
14
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
17
+++ b/target/arm/translate.h
18
@@ -XXX,XX +XXX,XX @@ typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
19
typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
20
uint32_t, uint32_t, uint32_t);
21
22
+/* Function prototype for gen_ functions for calling Neon helpers */
23
+typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
24
+typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
25
+typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
26
+typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
27
+typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
28
+typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
29
+typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
30
+typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
31
+typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
32
+typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
33
+typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
34
+typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
35
+typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
36
+typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
37
+typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
38
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
40
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
41
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-a64.c
17
--- a/target/arm/translate-a64.c
43
+++ b/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
44
@@ -XXX,XX +XXX,XX @@ typedef struct AArch64DecodeTable {
19
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
45
AArch64DecodeFn *disas_fn;
20
}
46
} AArch64DecodeTable;
21
}
47
22
48
-/* Function prototype for gen_ functions for calling Neon helpers */
23
- tcg_temp_free_ptr(tcg_fpstatus);
49
-typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
24
tcg_temp_free_i32(tcg_shift);
50
-typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
25
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
51
-typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
26
+ tcg_temp_free_ptr(tcg_fpstatus);
52
-typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
27
tcg_temp_free_i32(tcg_rmode);
53
-typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
28
}
54
-typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
29
55
-typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
56
-typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
57
-typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
58
-typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
59
-typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
60
-typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
61
-typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
62
-typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
63
-typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
64
-
65
/* initialize TCG globals. */
66
void a64_translate_init(void)
67
{
68
--
30
--
69
2.20.1
31
2.25.1
70
71
diff view generated by jsdifflib
1
Add the infrastructure for building and invoking a decodetree decoder
1
From: Shengtan Mao <stmao@google.com>
2
for the AArch32 Neon encodings. At the moment the new decoder covers
3
nothing, so we always fall back to the existing hand-written decode.
4
2
5
We follow the same pattern we did for the VFP decodetree conversion
3
Reviewed-by: Hao Wu <wuhaotsh@google.com>
6
(commit 78e138bc1f672c145ef6ace74617d and following): code that deals
4
Reviewed-by: Chris Rauer <crauer@google.com>
7
with Neon will be moving gradually out to translate-neon.vfp.inc,
5
Signed-off-by: Shengtan Mao <stmao@google.com>
8
which we #include into translate.c.
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
9
14
10
In order to share the decode files between A32 and T32, we
15
diff --git a/tests/qtest/npcm7xx_sdhci-test.c b/tests/qtest/npcm7xx_sdhci-test.c
11
split Neon into 3 parts:
12
* data-processing
13
* load-store
14
* 'shared' encodings
15
16
The first two groups of instructions have similar but not identical
17
A32 and T32 encodings, so we need to manually transform the T32
18
encoding into the A32 one before calling the decoder; the third group
19
covers the Neon instructions which are identical in A32 and T32.
20
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20200430181003.21682-4-peter.maydell@linaro.org
24
---
25
target/arm/neon-dp.decode | 29 ++++++++++++++++++++++++++
26
target/arm/neon-ls.decode | 29 ++++++++++++++++++++++++++
27
target/arm/neon-shared.decode | 27 +++++++++++++++++++++++++
28
target/arm/translate-neon.inc.c | 32 +++++++++++++++++++++++++++++
29
target/arm/translate.c | 36 +++++++++++++++++++++++++++++++--
30
target/arm/Makefile.objs | 18 +++++++++++++++++
31
6 files changed, 169 insertions(+), 2 deletions(-)
32
create mode 100644 target/arm/neon-dp.decode
33
create mode 100644 target/arm/neon-ls.decode
34
create mode 100644 target/arm/neon-shared.decode
35
create mode 100644 target/arm/translate-neon.inc.c
36
37
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
38
new file mode 100644
16
new file mode 100644
39
index XXXXXXX..XXXXXXX
17
index XXXXXXX..XXXXXXX
40
--- /dev/null
18
--- /dev/null
41
+++ b/target/arm/neon-dp.decode
19
+++ b/tests/qtest/npcm7xx_sdhci-test.c
42
@@ -XXX,XX +XXX,XX @@
43
+# AArch32 Neon data-processing instruction descriptions
44
+#
45
+# Copyright (c) 2020 Linaro, Ltd
46
+#
47
+# This library is free software; you can redistribute it and/or
48
+# modify it under the terms of the GNU Lesser General Public
49
+# License as published by the Free Software Foundation; either
50
+# version 2 of the License, or (at your option) any later version.
51
+#
52
+# This library is distributed in the hope that it will be useful,
53
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
54
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
55
+# Lesser General Public License for more details.
56
+#
57
+# You should have received a copy of the GNU Lesser General Public
58
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
59
+
60
+#
61
+# This file is processed by scripts/decodetree.py
62
+#
63
+
64
+# Encodings for Neon data processing instructions where the T32 encoding
65
+# is a simple transformation of the A32 encoding.
66
+# More specifically, this file covers instructions where the A32 encoding is
67
+# 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
68
+# and the T32 encoding is
69
+# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
70
+# This file works on the A32 encoding only; calling code for T32 has to
71
+# transform the insn into the A32 version first.
72
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
73
new file mode 100644
74
index XXXXXXX..XXXXXXX
75
--- /dev/null
76
+++ b/target/arm/neon-ls.decode
77
@@ -XXX,XX +XXX,XX @@
78
+# AArch32 Neon load/store instruction descriptions
79
+#
80
+# Copyright (c) 2020 Linaro, Ltd
81
+#
82
+# This library is free software; you can redistribute it and/or
83
+# modify it under the terms of the GNU Lesser General Public
84
+# License as published by the Free Software Foundation; either
85
+# version 2 of the License, or (at your option) any later version.
86
+#
87
+# This library is distributed in the hope that it will be useful,
88
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
89
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
90
+# Lesser General Public License for more details.
91
+#
92
+# You should have received a copy of the GNU Lesser General Public
93
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
94
+
95
+#
96
+# This file is processed by scripts/decodetree.py
97
+#
98
+
99
+# Encodings for Neon load/store instructions where the T32 encoding
100
+# is a simple transformation of the A32 encoding.
101
+# More specifically, this file covers instructions where the A32 encoding is
102
+# 0b1111_0100_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
103
+# and the T32 encoding is
104
+# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
105
+# This file works on the A32 encoding only; calling code for T32 has to
106
+# transform the insn into the A32 version first.
107
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
108
new file mode 100644
109
index XXXXXXX..XXXXXXX
110
--- /dev/null
111
+++ b/target/arm/neon-shared.decode
112
@@ -XXX,XX +XXX,XX @@
113
+# AArch32 Neon instruction descriptions
114
+#
115
+# Copyright (c) 2020 Linaro, Ltd
116
+#
117
+# This library is free software; you can redistribute it and/or
118
+# modify it under the terms of the GNU Lesser General Public
119
+# License as published by the Free Software Foundation; either
120
+# version 2 of the License, or (at your option) any later version.
121
+#
122
+# This library is distributed in the hope that it will be useful,
123
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
124
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
125
+# Lesser General Public License for more details.
126
+#
127
+# You should have received a copy of the GNU Lesser General Public
128
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
129
+
130
+#
131
+# This file is processed by scripts/decodetree.py
132
+#
133
+
134
+# Encodings for Neon instructions whose encoding is the same for
135
+# both A32 and T32.
136
+
137
+# More specifically, this covers:
138
+# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
139
+# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
140
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
141
new file mode 100644
142
index XXXXXXX..XXXXXXX
143
--- /dev/null
144
+++ b/target/arm/translate-neon.inc.c
145
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
146
+/*
21
+/*
147
+ * ARM translation: AArch32 Neon instructions
22
+ * QTests for NPCM7xx SD-3.0 / MMC-4.51 Host Controller
148
+ *
23
+ *
149
+ * Copyright (c) 2003 Fabrice Bellard
24
+ * Copyright (c) 2022 Google LLC
150
+ * Copyright (c) 2005-2007 CodeSourcery
151
+ * Copyright (c) 2007 OpenedHand, Ltd.
152
+ * Copyright (c) 2020 Linaro, Ltd.
153
+ *
25
+ *
154
+ * This library is free software; you can redistribute it and/or
26
+ * This program is free software; you can redistribute it and/or modify it
155
+ * modify it under the terms of the GNU Lesser General Public
27
+ * under the terms of the GNU General Public License as published by the
156
+ * License as published by the Free Software Foundation; either
28
+ * Free Software Foundation; either version 2 of the License, or
157
+ * version 2 of the License, or (at your option) any later version.
29
+ * (at your option) any later version.
158
+ *
30
+ *
159
+ * This library is distributed in the hope that it will be useful,
31
+ * This program is distributed in the hope that it will be useful, but WITHOUT
160
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
161
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
162
+ * Lesser General Public License for more details.
34
+ * for more details.
163
+ *
164
+ * You should have received a copy of the GNU Lesser General Public
165
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
166
+ */
35
+ */
167
+
36
+
168
+/*
37
+#include "qemu/osdep.h"
169
+ * This file is intended to be included from translate.c; it uses
38
+#include "hw/sd/npcm7xx_sdhci.h"
170
+ * some macros and definitions provided by that file.
39
+
171
+ * It might be possible to convert it to a standalone .c file eventually.
40
+#include "libqos/libqtest.h"
172
+ */
41
+#include "libqtest-single.h"
173
+
42
+#include "libqos/sdhci-cmd.h"
174
+/* Include the generated Neon decoder */
43
+
175
+#include "decode-neon-dp.inc.c"
44
+#define NPCM7XX_REG_SIZE 0x100
176
+#include "decode-neon-ls.inc.c"
45
+#define NPCM7XX_MMC_BA 0xF0842000
177
+#include "decode-neon-shared.inc.c"
46
+#define NPCM7XX_BLK_SIZE 512
178
diff --git a/target/arm/translate.c b/target/arm/translate.c
47
+#define NPCM7XX_TEST_IMAGE_SIZE (1 << 30)
179
index XXXXXXX..XXXXXXX 100644
48
+
180
--- a/target/arm/translate.c
49
+char *sd_path;
181
+++ b/target/arm/translate.c
50
+
182
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
51
+static QTestState *setup_sd_card(void)
183
52
+{
184
#define ARM_CP_RW_BIT (1 << 20)
53
+ QTestState *qts = qtest_initf(
185
54
+ "-machine kudo-bmc "
186
-/* Include the VFP decoder */
55
+ "-device sd-card,drive=drive0 "
187
+/* Include the VFP and Neon decoders */
56
+ "-drive id=drive0,if=none,file=%s,format=raw,auto-read-only=off",
188
#include "translate-vfp.inc.c"
57
+ sd_path);
189
+#include "translate-neon.inc.c"
58
+
190
59
+ qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_SWRST, SDHC_RESET_ALL);
191
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
60
+ qtest_writew(qts, NPCM7XX_MMC_BA + SDHC_CLKCON,
192
{
61
+ SDHC_CLOCK_SDCLK_EN | SDHC_CLOCK_INT_STABLE |
193
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
62
+ SDHC_CLOCK_INT_EN);
194
/* Unconditional instructions. */
63
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_APP_CMD);
195
/* TODO: Perhaps merge these into one decodetree output file. */
64
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x41200000, 0, (41 << 8));
196
if (disas_a32_uncond(s, insn) ||
65
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_ALL_SEND_CID);
197
- disas_vfp_uncond(s, insn)) {
66
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0, 0, SDHC_SEND_RELATIVE_ADDR);
198
+ disas_vfp_uncond(s, insn) ||
67
+ sdhci_cmd_regs(qts, NPCM7XX_MMC_BA, 0, 0, 0x45670000, 0,
199
+ disas_neon_dp(s, insn) ||
68
+ SDHC_SELECT_DESELECT_CARD);
200
+ disas_neon_ls(s, insn) ||
69
+
201
+ disas_neon_shared(s, insn)) {
70
+ return qts;
202
return;
71
+}
203
}
72
+
204
/* fall back to legacy decoder */
73
+static void write_sdread(QTestState *qts, const char *msg)
205
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
74
+{
206
ARCH(6T2);
75
+ int fd, ret;
207
}
76
+ size_t len = strlen(msg);
208
77
+ char *rmsg = g_malloc(len);
209
+ if ((insn & 0xef000000) == 0xef000000) {
78
+
210
+ /*
79
+ /* write message to sd */
211
+ * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
80
+ fd = open(sd_path, O_WRONLY);
212
+ * transform into
81
+ g_assert(fd >= 0);
213
+ * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
82
+ ret = write(fd, msg, len);
214
+ */
83
+ close(fd);
215
+ uint32_t a32_insn = (insn & 0xe2ffffff) |
84
+ g_assert(ret == len);
216
+ ((insn & (1 << 28)) >> 4) | (1 << 28);
85
+
217
+
86
+ /* read message using sdhci */
218
+ if (disas_neon_dp(s, a32_insn)) {
87
+ ret = sdhci_read_cmd(qts, NPCM7XX_MMC_BA, rmsg, len);
219
+ return;
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]);
183
+ }
184
+ addr += NPCM7XX_PRSTVALS_SIZE * 2;
185
+ break;
186
+ default:
187
+ g_assert_cmphex(qtest_readb(qts, addr), ==, 0);
188
+ addr += 1;
220
+ }
189
+ }
221
+ }
190
+ }
222
+
191
+
223
+ if ((insn & 0xff100000) == 0xf9000000) {
192
+ qtest_quit(qts);
224
+ /*
193
+}
225
+ * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
194
+
226
+ * transform into
195
+static void drive_destroy(void)
227
+ * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
196
+{
228
+ */
197
+ unlink(sd_path);
229
+ uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
198
+ g_free(sd_path);
230
+
199
+}
231
+ if (disas_neon_ls(s, a32_insn)) {
200
+
232
+ return;
201
+static void drive_create(void)
233
+ }
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);
234
+ }
211
+ }
235
+
212
+ g_assert(sd_path != NULL);
236
/*
213
+
237
* TODO: Perhaps merge these into one decodetree output file.
214
+ ret = ftruncate(fd, NPCM7XX_TEST_IMAGE_SIZE);
238
* Note disas_vfp is written for a32 with cond field in the
215
+ g_assert_cmpint(ret, ==, 0);
239
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
216
+ g_message("%s", sd_path);
240
*/
217
+ close(fd);
241
if (disas_t32(s, insn) ||
218
+}
242
disas_vfp_uncond(s, insn) ||
219
+
243
+ disas_neon_shared(s, insn) ||
220
+int main(int argc, char **argv)
244
((insn >> 28) == 0xe && disas_vfp(s, insn))) {
221
+{
245
return;
222
+ int ret;
246
}
223
+
247
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
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
248
index XXXXXXX..XXXXXXX 100644
237
index XXXXXXX..XXXXXXX 100644
249
--- a/target/arm/Makefile.objs
238
--- a/tests/qtest/meson.build
250
+++ b/target/arm/Makefile.objs
239
+++ b/tests/qtest/meson.build
251
@@ -XXX,XX +XXX,XX @@ target/arm/decode-sve.inc.c: $(SRC_PATH)/target/arm/sve.decode $(DECODETREE)
240
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
252
     $(PYTHON) $(DECODETREE) --decode disas_sve -o $@ $<,\
241
'npcm7xx_gpio-test',
253
     "GEN", $(TARGET_DIR)$@)
242
'npcm7xx_pwm-test',
254
243
'npcm7xx_rng-test',
255
+target/arm/decode-neon-shared.inc.c: $(SRC_PATH)/target/arm/neon-shared.decode $(DECODETREE)
244
+ 'npcm7xx_sdhci-test',
256
+    $(call quiet-command,\
245
'npcm7xx_smbus-test',
257
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_shared -o $@ $<,\
246
'npcm7xx_timer-test',
258
+     "GEN", $(TARGET_DIR)$@)
247
'npcm7xx_watchdog_timer-test'] + \
259
+
260
+target/arm/decode-neon-dp.inc.c: $(SRC_PATH)/target/arm/neon-dp.decode $(DECODETREE)
261
+    $(call quiet-command,\
262
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_dp -o $@ $<,\
263
+     "GEN", $(TARGET_DIR)$@)
264
+
265
+target/arm/decode-neon-ls.inc.c: $(SRC_PATH)/target/arm/neon-ls.decode $(DECODETREE)
266
+    $(call quiet-command,\
267
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_ls -o $@ $<,\
268
+     "GEN", $(TARGET_DIR)$@)
269
+
270
target/arm/decode-vfp.inc.c: $(SRC_PATH)/target/arm/vfp.decode $(DECODETREE)
271
    $(call quiet-command,\
272
     $(PYTHON) $(DECODETREE) --static-decode disas_vfp -o $@ $<,\
273
@@ -XXX,XX +XXX,XX @@ target/arm/decode-t16.inc.c: $(SRC_PATH)/target/arm/t16.decode $(DECODETREE)
274
     "GEN", $(TARGET_DIR)$@)
275
276
target/arm/translate-sve.o: target/arm/decode-sve.inc.c
277
+target/arm/translate.o: target/arm/decode-neon-shared.inc.c
278
+target/arm/translate.o: target/arm/decode-neon-dp.inc.c
279
+target/arm/translate.o: target/arm/decode-neon-ls.inc.c
280
target/arm/translate.o: target/arm/decode-vfp.inc.c
281
target/arm/translate.o: target/arm/decode-vfp-uncond.inc.c
282
target/arm/translate.o: target/arm/decode-a32.inc.c
283
--
248
--
284
2.20.1
249
2.25.1
285
286
diff view generated by jsdifflib
1
From: Fredrik Strupe <fredrik@strupe.net>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
According to Arm ARM, VQDMULL is only valid when U=0, while having
3
Add new macros to manipulate signed fields within the register.
4
U=1 is unallocated.
5
4
6
Signed-off-by: Fredrik Strupe <fredrik@strupe.net>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Fixes: 695272dcb976 ("target-arm: Handle UNDEF cases for Neon 3-regs-different-widths")
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@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>
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 | 2 +-
12
include/hw/registerfields.h | 48 ++++++++++++++++++++++++++++++++++++-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 47 insertions(+), 1 deletion(-)
13
14
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
17
--- a/include/hw/registerfields.h
17
+++ b/target/arm/translate.c
18
+++ b/include/hw/registerfields.h
18
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
19
@@ -XXX,XX +XXX,XX @@
19
{0, 0, 0, 0}, /* VMLSL */
20
extract64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
20
{0, 0, 0, 9}, /* VQDMLSL */
21
R_ ## reg ## _ ## field ## _LENGTH)
21
{0, 0, 0, 0}, /* Integer VMULL */
22
22
- {0, 0, 0, 1}, /* VQDMULL */
23
+#define FIELD_SEX8(storage, reg, field) \
23
+ {0, 0, 0, 9}, /* VQDMULL */
24
+ sextract8((storage), R_ ## reg ## _ ## field ## _SHIFT, \
24
{0, 0, 0, 0xa}, /* Polynomial VMULL */
25
+ R_ ## reg ## _ ## field ## _LENGTH)
25
{0, 0, 0, 7}, /* Reserved: always UNDEF */
26
+#define FIELD_SEX16(storage, reg, field) \
26
};
27
+ sextract16((storage), R_ ## reg ## _ ## field ## _SHIFT, \
28
+ R_ ## reg ## _ ## field ## _LENGTH)
29
+#define FIELD_SEX32(storage, reg, field) \
30
+ sextract32((storage), R_ ## reg ## _ ## field ## _SHIFT, \
31
+ R_ ## reg ## _ ## field ## _LENGTH)
32
+#define FIELD_SEX64(storage, reg, field) \
33
+ sextract64((storage), R_ ## reg ## _ ## field ## _SHIFT, \
34
+ R_ ## reg ## _ ## field ## _LENGTH)
35
+
36
/* Extract a field from an array of registers */
37
#define ARRAY_FIELD_EX32(regs, reg, field) \
38
FIELD_EX32((regs)[R_ ## reg], reg, field)
39
@@ -XXX,XX +XXX,XX @@
40
_d; })
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, \
27
--
81
--
28
2.20.1
82
2.25.1
29
83
30
84
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
MIDR_EL1 is a 64-bit system register with the top 32-bit being RES0.
3
Set this as the kernel would, to 48 bits, to keep the computation
4
Represent it in QEMU's ARMCPU struct with a uint64_t, not a
4
of the address space correct for PAuth.
5
uint32_t.
6
5
7
This fixes an error when compiling with -Werror=conversion
8
because we were manipulating the register value using a
9
local uint64_t variable:
10
11
target/arm/cpu64.c: In function ‘aarch64_max_initfn’:
12
target/arm/cpu64.c:628:21: error: conversion from ‘uint64_t’ {aka ‘long unsigned int’} to ‘uint32_t’ {aka ‘unsigned int’} may change value [-Werror=conversion]
13
628 | cpu->midr = t;
14
| ^
15
16
and future-proofs us against a possible future architecture
17
change using some of the top 32 bits.
18
19
Suggested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
20
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
23
Message-id: 20200428172634.29707-1-f4bug@amsat.org
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220301215958.157011-3-richard.henderson@linaro.org
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
10
---
27
target/arm/cpu.h | 2 +-
11
target/arm/cpu.c | 3 ++-
28
target/arm/cpu.c | 2 +-
12
1 file changed, 2 insertions(+), 1 deletion(-)
29
2 files changed, 2 insertions(+), 2 deletions(-)
30
13
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.h
34
+++ b/target/arm/cpu.h
35
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
36
uint64_t id_aa64dfr0;
37
uint64_t id_aa64dfr1;
38
} isar;
39
- uint32_t midr;
40
+ uint64_t midr;
41
uint32_t revidr;
42
uint32_t reset_fpsid;
43
uint32_t ctr;
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
45
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/cpu.c
16
--- a/target/arm/cpu.c
47
+++ b/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
48
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
18
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
49
static Property arm_cpu_properties[] = {
19
aarch64_sve_zcr_get_valid_len(cpu, cpu->sve_default_vq - 1);
50
DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
20
}
51
DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0),
21
/*
52
- DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0),
22
+ * Enable 48-bit address space (TODO: take reserved_va into account).
53
+ DEFINE_PROP_UINT64("midr", ARMCPU, midr, 0),
23
* Enable TBI0 but not TBI1.
54
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
24
* Note that this must match useronly_clean_ptr.
55
mp_affinity, ARM64_AFFINITY_INVALID),
25
*/
56
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
26
- env->cp15.tcr_el[1].raw_tcr = (1ULL << 37);
27
+ env->cp15.tcr_el[1].raw_tcr = 5 | (1ULL << 37);
28
29
/* Enable MTE */
30
if (cpu_isar_feature(aa64_mte, cpu)) {
57
--
31
--
58
2.20.1
32
2.25.1
59
60
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Embed the APUs into the SoC type.
3
Without FEAT_LVA, the behaviour of programming an invalid value
4
is IMPLEMENTATION DEFINED. With FEAT_LVA, programming an invalid
5
minimum value requires a Translation fault.
4
6
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
7
It is most self-consistent to choose to generate the fault always.
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
11
Message-id: 20220301215958.157011-4-richard.henderson@linaro.org
10
Message-id: 20200427181649.26851-8-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
include/hw/arm/xlnx-versal.h | 2 +-
14
target/arm/internals.h | 1 +
14
hw/arm/xlnx-versal-virt.c | 4 ++--
15
target/arm/helper.c | 32 ++++++++++++++++++++++++++++----
15
hw/arm/xlnx-versal.c | 19 +++++--------------
16
2 files changed, 29 insertions(+), 4 deletions(-)
16
3 files changed, 8 insertions(+), 17 deletions(-)
17
17
18
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
diff --git a/target/arm/internals.h b/target/arm/internals.h
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/xlnx-versal.h
20
--- a/target/arm/internals.h
21
+++ b/include/hw/arm/xlnx-versal.h
21
+++ b/target/arm/internals.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
22
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
23
struct {
23
bool hpd : 1;
24
struct {
24
bool using16k : 1;
25
MemoryRegion mr;
25
bool using64k : 1;
26
- ARMCPU *cpu[XLNX_VERSAL_NR_ACPUS];
26
+ bool tsz_oob : 1; /* tsz has been clamped to legal range */
27
+ ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
27
} ARMVAParameters;
28
GICv3State gic;
28
29
} apu;
29
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
30
} fpd;
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
32
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/xlnx-versal-virt.c
32
--- a/target/arm/helper.c
34
+++ b/hw/arm/xlnx-versal-virt.c
33
+++ b/target/arm/helper.c
35
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
34
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
36
s->binfo.get_dtb = versal_virt_get_dtb;
35
ARMMMUIdx mmu_idx, bool data)
37
s->binfo.modify_dtb = versal_virt_modify_dtb;
36
{
38
if (machine->kernel_filename) {
37
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
39
- arm_load_kernel(s->soc.fpd.apu.cpu[0], machine, &s->binfo);
38
- bool epd, hpd, using16k, using64k;
40
+ arm_load_kernel(&s->soc.fpd.apu.cpu[0], machine, &s->binfo);
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,
41
} else {
46
} else {
42
- AddressSpace *as = arm_boot_address_space(s->soc.fpd.apu.cpu[0],
47
max_tsz = 39;
43
+ AddressSpace *as = arm_boot_address_space(&s->soc.fpd.apu.cpu[0],
44
&s->binfo);
45
/* Some boot-loaders (e.g u-boot) don't like blobs at address 0 (NULL).
46
* Offset things by 4K. */
47
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/xlnx-versal.c
50
+++ b/hw/arm/xlnx-versal.c
51
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
52
53
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
54
Object *obj;
55
- char *name;
56
-
57
- obj = object_new(XLNX_VERSAL_ACPU_TYPE);
58
- if (!obj) {
59
- error_report("Unable to create apu.cpu[%d] of type %s",
60
- i, XLNX_VERSAL_ACPU_TYPE);
61
- exit(EXIT_FAILURE);
62
- }
63
-
64
- name = g_strdup_printf("apu-cpu[%d]", i);
65
- object_property_add_child(OBJECT(s), name, obj, &error_fatal);
66
- g_free(name);
67
68
+ object_initialize_child(OBJECT(s), "apu-cpu[*]",
69
+ &s->fpd.apu.cpu[i], sizeof(s->fpd.apu.cpu[i]),
70
+ XLNX_VERSAL_ACPU_TYPE, &error_abort, NULL);
71
+ obj = OBJECT(&s->fpd.apu.cpu[i]);
72
object_property_set_int(obj, s->cfg.psci_conduit,
73
"psci-conduit", &error_abort);
74
if (i) {
75
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
76
object_property_set_link(obj, OBJECT(&s->fpd.apu.mr), "memory",
77
&error_abort);
78
object_property_set_bool(obj, true, "realized", &error_fatal);
79
- s->fpd.apu.cpu[i] = ARM_CPU(obj);
80
}
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
};
81
}
71
}
82
72
83
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
73
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
84
}
74
param = aa64_va_parameters(env, address, mmu_idx,
85
75
access_type != MMU_INST_FETCH);
86
for (i = 0; i < nr_apu_cpus; i++) {
76
level = 0;
87
- DeviceState *cpudev = DEVICE(s->fpd.apu.cpu[i]);
77
+
88
+ DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]);
78
+ /*
89
int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
79
+ * If TxSZ is programmed to a value larger than the maximum,
90
qemu_irq maint_irq;
80
+ * or smaller than the effective minimum, it is IMPLEMENTATION
91
int ti;
81
+ * DEFINED whether we behave as if the field were programmed
82
+ * within bounds, or if a level 0 Translation fault is generated.
83
+ *
84
+ * With FEAT_LVA, fault on less than minimum becomes required,
85
+ * so our choice is to always raise the fault.
86
+ */
87
+ if (param.tsz_oob) {
88
+ fault_type = ARMFault_Translation;
89
+ goto do_fault;
90
+ }
91
+
92
addrsize = 64 - 8 * param.tbi;
93
inputsize = 64 - param.tsz;
94
} else {
92
--
95
--
93
2.20.1
96
2.25.1
94
95
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
hw/arm: versal: Add support for the RTC.
3
We will shortly share parts of this function with other portions
4
of address translation.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20220301215958.157011-5-richard.henderson@linaro.org
9
Message-id: 20200427181649.26851-10-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
include/hw/arm/xlnx-versal.h | 8 ++++++++
13
target/arm/internals.h | 19 +------------------
13
hw/arm/xlnx-versal.c | 21 +++++++++++++++++++++
14
target/arm/helper.c | 22 ++++++++++++++++++++++
14
2 files changed, 29 insertions(+)
15
2 files changed, 23 insertions(+), 18 deletions(-)
15
16
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
17
diff --git a/target/arm/internals.h b/target/arm/internals.h
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
19
--- a/target/arm/internals.h
19
+++ b/include/hw/arm/xlnx-versal.h
20
+++ b/target/arm/internals.h
20
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static inline void update_spsel(CPUARMState *env, uint32_t imm)
21
#include "hw/char/pl011.h"
22
* Returns the implementation defined bit-width of physical addresses.
22
#include "hw/dma/xlnx-zdma.h"
23
* The ARMv8 reference manuals refer to this as PAMax().
23
#include "hw/net/cadence_gem.h"
24
*/
24
+#include "hw/rtc/xlnx-zynqmp-rtc.h"
25
-static inline unsigned int arm_pamax(ARMCPU *cpu)
25
26
-{
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
27
- static const unsigned int pamax_map[] = {
27
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
28
- [0] = 32,
28
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
29
- [1] = 36,
29
struct {
30
- [2] = 40,
30
SDHCIState sd[XLNX_VERSAL_NR_SDS];
31
- [3] = 42,
31
} iou;
32
- [4] = 44,
32
+
33
- [5] = 48,
33
+ XlnxZynqMPRTC rtc;
34
- };
34
} pmc;
35
- unsigned int parange =
35
36
- FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
36
struct {
37
-
37
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
38
- /* id_aa64mmfr0 is a read-only register so values outside of the
38
#define VERSAL_GEM1_IRQ_0 58
39
- * supported mappings can be considered an implementation error. */
39
#define VERSAL_GEM1_WAKE_IRQ_0 59
40
- assert(parange < ARRAY_SIZE(pamax_map));
40
#define VERSAL_ADMA_IRQ_0 60
41
- return pamax_map[parange];
41
+#define VERSAL_RTC_APB_ERR_IRQ 121
42
-}
42
#define VERSAL_SD0_IRQ_0 126
43
+unsigned int arm_pamax(ARMCPU *cpu);
43
+#define VERSAL_RTC_ALARM_IRQ 142
44
44
+#define VERSAL_RTC_SECONDS_IRQ 143
45
/* Return true if extended addresses are enabled.
45
46
* This is always the case if our translation regime is 64 bit,
46
/* Architecturally reserved IRQs suitable for virtualization. */
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
47
#define VERSAL_RSVD_IRQ_FIRST 111
48
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
49
#define MM_PMC_SD0_SIZE 0x10000
50
#define MM_PMC_CRP 0xf1260000U
51
#define MM_PMC_CRP_SIZE 0x10000
52
+#define MM_PMC_RTC 0xf12a0000
53
+#define MM_PMC_RTC_SIZE 0x10000
54
#endif
55
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
56
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/xlnx-versal.c
49
--- a/target/arm/helper.c
58
+++ b/hw/arm/xlnx-versal.c
50
+++ b/target/arm/helper.c
59
@@ -XXX,XX +XXX,XX @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
51
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
60
}
61
}
52
}
62
53
#endif /* !CONFIG_USER_ONLY */
63
+static void versal_create_rtc(Versal *s, qemu_irq *pic)
54
55
+/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
56
+unsigned int arm_pamax(ARMCPU *cpu)
64
+{
57
+{
65
+ SysBusDevice *sbd;
58
+ static const unsigned int pamax_map[] = {
66
+ MemoryRegion *mr;
59
+ [0] = 32,
67
+
60
+ [1] = 36,
68
+ sysbus_init_child_obj(OBJECT(s), "rtc", &s->pmc.rtc, sizeof(s->pmc.rtc),
61
+ [2] = 40,
69
+ TYPE_XLNX_ZYNQMP_RTC);
62
+ [3] = 42,
70
+ sbd = SYS_BUS_DEVICE(&s->pmc.rtc);
63
+ [4] = 44,
71
+ qdev_init_nofail(DEVICE(sbd));
64
+ [5] = 48,
72
+
65
+ };
73
+ mr = sysbus_mmio_get_region(sbd, 0);
66
+ unsigned int parange =
74
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr);
67
+ FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
75
+
68
+
76
+ /*
69
+ /*
77
+ * TODO: Connect the ALARM and SECONDS interrupts once our RTC model
70
+ * id_aa64mmfr0 is a read-only register so values outside of the
78
+ * supports them.
71
+ * supported mappings can be considered an implementation error.
79
+ */
72
+ */
80
+ sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
73
+ assert(parange < ARRAY_SIZE(pamax_map));
74
+ return pamax_map[parange];
81
+}
75
+}
82
+
76
+
83
/* This takes the board allocated linear DDR memory and creates aliases
77
static int aa64_va_parameter_tbi(uint64_t tcr, ARMMMUIdx mmu_idx)
84
* for each split DDR range/aperture on the Versal address map.
78
{
85
*/
79
if (regime_has_2_ranges(mmu_idx)) {
86
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
87
versal_create_gems(s, pic);
88
versal_create_admas(s, pic);
89
versal_create_sds(s, pic);
90
+ versal_create_rtc(s, pic);
91
versal_map_ddr(s);
92
versal_unimp(s);
93
94
--
80
--
95
2.20.1
81
2.25.1
96
82
97
83
diff view generated by jsdifflib
1
For ARMv8.2-TTS2UXN, the stage 2 page table walk wants to know
1
From: Richard Henderson <richard.henderson@linaro.org>
2
whether the stage 1 access is for EL0 or not, because whether
3
exec permission is given can depend on whether this is an EL0
4
or EL1 access. Add a new argument to get_phys_addr_lpae() so
5
the call sites can pass this information in.
6
2
7
Since get_phys_addr_lpae() doesn't already have a doc comment,
3
Pass down the width of the output address from translation.
8
add one so we have a place to put the documentation of the
4
For now this is still just PAMax, but a subsequent patch will
9
semantics of the new s1_is_el0 argument.
5
compute the correct value from TCR_ELx.{I}PS.
10
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220301215958.157011-6-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200330210400.11724-4-peter.maydell@linaro.org
15
---
11
---
16
target/arm/helper.c | 29 ++++++++++++++++++++++++++++-
12
target/arm/helper.c | 21 ++++++++++-----------
17
1 file changed, 28 insertions(+), 1 deletion(-)
13
1 file changed, 10 insertions(+), 11 deletions(-)
18
14
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
17
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
18
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ do_fault:
24
20
* false otherwise.
25
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
21
*/
26
MMUAccessType access_type, ARMMMUIdx mmu_idx,
22
static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
27
+ bool s1_is_el0,
23
- int inputsize, int stride)
28
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
24
+ int inputsize, int stride, int outputsize)
29
target_ulong *page_size_ptr,
25
{
30
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
26
const int grainsize = stride + 3;
31
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
27
int startsizecheck;
28
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
29
}
30
31
if (is_aa64) {
32
- CPUARMState *env = &cpu->env;
33
- unsigned int pamax = arm_pamax(cpu);
34
-
35
switch (stride) {
36
case 13: /* 64KB Pages. */
37
- if (level == 0 || (level == 1 && pamax <= 42)) {
38
+ if (level == 0 || (level == 1 && outputsize <= 42)) {
39
return false;
40
}
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,
32
}
55
}
33
56
34
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
57
/* Inputsize checks. */
35
+ false,
58
- if (inputsize > pamax &&
36
&s2pa, &txattrs, &s2prot, &s2size, fi,
59
- (arm_el_is_aa64(env, 1) || inputsize > 40)) {
37
pcacheattrs);
60
+ if (inputsize > outputsize &&
38
if (ret) {
61
+ (arm_el_is_aa64(&cpu->env, 1) || inputsize > 40)) {
39
@@ -XXX,XX +XXX,XX @@ static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
62
/* This is CONSTRAINED UNPREDICTABLE and we choose to fault. */
40
};
63
return false;
41
}
64
}
42
65
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
43
+/**
66
target_ulong page_size;
44
+ * get_phys_addr_lpae: perform one stage of page table walk, LPAE format
67
uint32_t attrs;
45
+ *
68
int32_t stride;
46
+ * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
69
- int addrsize, inputsize;
47
+ * prot and page_size may not be filled in, and the populated fsr value provides
70
+ int addrsize, inputsize, outputsize;
48
+ * information on why the translation aborted, in the format of a long-format
71
TCR *tcr = regime_tcr(env, mmu_idx);
49
+ * DFSR/IFSR fault register, with the following caveats:
72
int ap, ns, xn, pxn;
50
+ * * the WnR bit is never set (the caller must do this).
73
uint32_t el = regime_el(env, mmu_idx);
51
+ *
74
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
52
+ * @env: CPUARMState
75
53
+ * @address: virtual address to get physical address for
76
addrsize = 64 - 8 * param.tbi;
54
+ * @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH
77
inputsize = 64 - param.tsz;
55
+ * @mmu_idx: MMU index indicating required translation regime
78
+ outputsize = arm_pamax(cpu);
56
+ * @s1_is_el0: if @mmu_idx is ARMMMUIdx_Stage2 (so this is a stage 2 page table
79
} else {
57
+ * walk), must be true if this is stage 2 of a stage 1+2 walk for an
80
param = aa32_va_parameters(env, address, mmu_idx);
58
+ * EL0 access). If @mmu_idx is anything else, @s1_is_el0 is ignored.
81
level = 1;
59
+ * @phys_ptr: set to the physical address corresponding to the virtual address
82
addrsize = (mmu_idx == ARMMMUIdx_Stage2 ? 40 : 32);
60
+ * @attrs: set to the memory transaction attributes to use
83
inputsize = addrsize - param.tsz;
61
+ * @prot: set to the permissions for the page containing phys_ptr
84
+ outputsize = 40;
62
+ * @page_size_ptr: set to the size of the page containing phys_ptr
63
+ * @fi: set to fault info if the translation fails
64
+ * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
65
+ */
66
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
67
MMUAccessType access_type, ARMMMUIdx mmu_idx,
68
+ bool s1_is_el0,
69
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
70
target_ulong *page_size_ptr,
71
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
72
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
73
74
/* S1 is done. Now do S2 translation. */
75
ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_Stage2,
76
+ mmu_idx == ARMMMUIdx_E10_0,
77
phys_ptr, attrs, &s2_prot,
78
page_size, fi,
79
cacheattrs != NULL ? &cacheattrs2 : NULL);
80
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
81
}
85
}
82
86
83
if (regime_using_lpae_format(env, mmu_idx)) {
87
/*
84
- return get_phys_addr_lpae(env, address, access_type, mmu_idx,
88
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
85
+ return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
89
86
phys_ptr, attrs, prot, page_size,
90
/* Check that the starting level is valid. */
87
fi, cacheattrs);
91
ok = check_s2_mmu_setup(cpu, aarch64, startlevel,
88
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
92
- inputsize, stride);
93
+ inputsize, stride, outputsize);
94
if (!ok) {
95
fault_type = ARMFault_Translation;
96
goto do_fault;
89
--
97
--
90
2.20.1
98
2.25.1
91
92
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Fix typo xlnx-ve -> xlnx-versal.
3
The macro is a bit more readable than the inlined computation.
4
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200427181649.26851-4-edgar.iglesias@gmail.com
7
Message-id: 20220301215958.157011-7-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
hw/arm/xlnx-versal-virt.c | 2 +-
10
target/arm/helper.c | 4 ++--
13
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 2 insertions(+), 2 deletions(-)
14
12
15
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal-virt.c
15
--- a/target/arm/helper.c
18
+++ b/hw/arm/xlnx-versal-virt.c
16
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
17
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
20
psci_conduit = QEMU_PSCI_CONDUIT_SMC;
18
level = startlevel;
21
}
19
}
22
20
23
- sysbus_init_child_obj(OBJECT(machine), "xlnx-ve", &s->soc,
21
- indexmask_grainsize = (1ULL << (stride + 3)) - 1;
24
+ sysbus_init_child_obj(OBJECT(machine), "xlnx-versal", &s->soc,
22
- indexmask = (1ULL << (inputsize - (stride * (4 - level)))) - 1;
25
sizeof(s->soc), TYPE_XLNX_VERSAL);
23
+ indexmask_grainsize = MAKE_64BIT_MASK(0, stride + 3);
26
object_property_set_link(OBJECT(&s->soc), OBJECT(machine->ram),
24
+ indexmask = MAKE_64BIT_MASK(0, inputsize - (stride * (4 - level)));
27
"ddr", &error_abort);
25
26
/* Now we can extract the actual base address from the TTBR */
27
descaddr = extract64(ttbr, 0, 48);
28
--
28
--
29
2.20.1
29
2.25.1
30
30
31
31
diff view generated by jsdifflib
1
Convert the Neon "load/store multiple structures" insns to decodetree.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This field controls the output (intermediate) physical address size
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.
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>
17
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20220301215958.157011-8-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-12-peter.maydell@linaro.org
6
---
20
---
7
target/arm/neon-ls.decode | 7 ++
21
target/arm/internals.h | 1 +
8
target/arm/translate-neon.inc.c | 124 ++++++++++++++++++++++++++++++++
22
target/arm/helper.c | 72 ++++++++++++++++++++++++++++++++----------
9
target/arm/translate.c | 91 +----------------------
23
2 files changed, 57 insertions(+), 16 deletions(-)
10
3 files changed, 133 insertions(+), 89 deletions(-)
11
24
12
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
25
diff --git a/target/arm/internals.h b/target/arm/internals.h
13
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-ls.decode
27
--- a/target/arm/internals.h
15
+++ b/target/arm/neon-ls.decode
28
+++ b/target/arm/internals.h
16
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
17
# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
30
*/
18
# This file works on the A32 encoding only; calling code for T32 has to
31
typedef struct ARMVAParameters {
19
# transform the insn into the A32 version first.
32
unsigned tsz : 8;
20
+
33
+ unsigned ps : 3;
21
+%vd_dp 22:1 12:4
34
unsigned select : 1;
22
+
35
bool tbi : 1;
23
+# Neon load/store multiple structures
36
bool epd : 1;
24
+
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
+VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
26
+ vd=%vd_dp
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
39
--- a/target/arm/helper.c
30
+++ b/target/arm/translate-neon.inc.c
40
+++ b/target/arm/helper.c
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
41
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
32
gen_helper_gvec_fmlal_idx_a32);
33
return true;
34
}
42
}
35
+
43
#endif /* !CONFIG_USER_ONLY */
36
+static struct {
44
37
+ int nregs;
45
+/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
38
+ int interleave;
46
+static const uint8_t pamax_map[] = {
39
+ int spacing;
47
+ [0] = 32,
40
+} const neon_ls_element_type[11] = {
48
+ [1] = 36,
41
+ {1, 4, 1},
49
+ [2] = 40,
42
+ {1, 4, 2},
50
+ [3] = 42,
43
+ {4, 1, 1},
51
+ [4] = 44,
44
+ {2, 2, 2},
52
+ [5] = 48,
45
+ {1, 3, 1},
46
+ {1, 3, 2},
47
+ {3, 1, 1},
48
+ {1, 1, 1},
49
+ {1, 2, 1},
50
+ {1, 2, 2},
51
+ {2, 1, 1}
52
+};
53
+};
53
+
54
+
54
+static void gen_neon_ldst_base_update(DisasContext *s, int rm, int rn,
55
/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
55
+ int stride)
56
unsigned int arm_pamax(ARMCPU *cpu)
56
+{
57
{
57
+ if (rm != 15) {
58
- static const unsigned int pamax_map[] = {
58
+ TCGv_i32 base;
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);
91
}
92
93
if (cpu_isar_feature(aa64_st, env_archcpu(env))) {
94
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
95
96
return (ARMVAParameters) {
97
.tsz = tsz,
98
+ .ps = ps,
99
.select = select,
100
.tbi = tbi,
101
.epd = epd,
102
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
103
104
/* TODO: This code does not support shareability levels. */
105
if (aarch64) {
106
+ int ps;
59
+
107
+
60
+ base = load_reg(s, rn);
108
param = aa64_va_parameters(env, address, mmu_idx,
61
+ if (rm == 13) {
109
access_type != MMU_INST_FETCH);
62
+ tcg_gen_addi_i32(base, base, stride);
110
level = 0;
63
+ } else {
111
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
64
+ TCGv_i32 index;
112
65
+ index = load_reg(s, rm);
113
addrsize = 64 - 8 * param.tbi;
66
+ tcg_gen_add_i32(base, base, index);
114
inputsize = 64 - param.tsz;
67
+ tcg_temp_free_i32(index);
115
- outputsize = arm_pamax(cpu);
68
+ }
69
+ store_reg(s, rn, base);
70
+ }
71
+}
72
+
116
+
73
+static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
117
+ /*
74
+{
118
+ * Bound PS by PARANGE to find the effective output address size.
75
+ /* Neon load/store multiple structures */
119
+ * ID_AA64MMFR0 is a read-only register so values outside of the
76
+ int nregs, interleave, spacing, reg, n;
120
+ * supported mappings can be considered an implementation error.
77
+ MemOp endian = s->be_data;
121
+ */
78
+ int mmu_idx = get_mem_index(s);
122
+ ps = FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
79
+ int size = a->size;
123
+ ps = MIN(ps, param.ps);
80
+ TCGv_i64 tmp64;
124
+ assert(ps < ARRAY_SIZE(pamax_map));
81
+ TCGv_i32 addr, tmp;
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);
82
+
133
+
83
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
134
+ /*
84
+ return false;
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;
85
+ }
143
+ }
86
+
144
+
87
+ /* UNDEF accesses to D16-D31 if they don't exist */
145
/*
88
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
146
* We rely on this masking to clear the RES0 bits at the bottom of the TTBR
89
+ return false;
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);
90
+ }
169
+ }
91
+ if (a->itype > 10) {
170
+ descaddrmask &= ~indexmask_grainsize;
92
+ return false;
171
93
+ }
172
/* Secure accesses start with the page table in secure memory and
94
+ /* Catch UNDEF cases for bad values of align field */
173
* can be downgraded to non-secure at any step. Non-secure accesses
95
+ switch (a->itype & 0xc) {
174
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
96
+ case 4:
175
/* Invalid, or the Reserved level 3 encoding */
97
+ if (a->align >= 2) {
176
goto do_fault;
98
+ return false;
177
}
178
+
179
descaddr = descriptor & descaddrmask;
180
+ if (descaddr >> outputsize) {
181
+ fault_type = ARMFault_AddressSize;
182
+ goto do_fault;
99
+ }
183
+ }
100
+ break;
184
101
+ case 8:
185
if ((descriptor & 2) && (level < 3)) {
102
+ if (a->align == 3) {
186
/* Table entry. The top five bits are attributes which may
103
+ return false;
104
+ }
105
+ break;
106
+ default:
107
+ break;
108
+ }
109
+ nregs = neon_ls_element_type[a->itype].nregs;
110
+ interleave = neon_ls_element_type[a->itype].interleave;
111
+ spacing = neon_ls_element_type[a->itype].spacing;
112
+ if (size == 3 && (interleave | spacing) != 1) {
113
+ return false;
114
+ }
115
+
116
+ if (!vfp_access_check(s)) {
117
+ return true;
118
+ }
119
+
120
+ /* For our purposes, bytes are always little-endian. */
121
+ if (size == 0) {
122
+ endian = MO_LE;
123
+ }
124
+ /*
125
+ * Consecutive little-endian elements from a single register
126
+ * can be promoted to a larger little-endian operation.
127
+ */
128
+ if (interleave == 1 && endian == MO_LE) {
129
+ size = 3;
130
+ }
131
+ tmp64 = tcg_temp_new_i64();
132
+ addr = tcg_temp_new_i32();
133
+ tmp = tcg_const_i32(1 << size);
134
+ load_reg_var(s, addr, a->rn);
135
+ for (reg = 0; reg < nregs; reg++) {
136
+ for (n = 0; n < 8 >> size; n++) {
137
+ int xs;
138
+ for (xs = 0; xs < interleave; xs++) {
139
+ int tt = a->vd + reg + spacing * xs;
140
+
141
+ if (a->l) {
142
+ gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
143
+ neon_store_element64(tt, n, size, tmp64);
144
+ } else {
145
+ neon_load_element64(tmp64, tt, n, size);
146
+ gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
147
+ }
148
+ tcg_gen_add_i32(addr, addr, tmp);
149
+ }
150
+ }
151
+ }
152
+ tcg_temp_free_i32(addr);
153
+ tcg_temp_free_i32(tmp);
154
+ tcg_temp_free_i64(tmp64);
155
+
156
+ gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
157
+ return true;
158
+}
159
diff --git a/target/arm/translate.c b/target/arm/translate.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/target/arm/translate.c
162
+++ b/target/arm/translate.c
163
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
164
}
165
166
167
-static struct {
168
- int nregs;
169
- int interleave;
170
- int spacing;
171
-} const neon_ls_element_type[11] = {
172
- {1, 4, 1},
173
- {1, 4, 2},
174
- {4, 1, 1},
175
- {2, 2, 2},
176
- {1, 3, 1},
177
- {1, 3, 2},
178
- {3, 1, 1},
179
- {1, 1, 1},
180
- {1, 2, 1},
181
- {1, 2, 2},
182
- {2, 1, 1}
183
-};
184
-
185
/* Translate a NEON load/store element instruction. Return nonzero if the
186
instruction is invalid. */
187
static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
188
{
189
int rd, rn, rm;
190
- int op;
191
int nregs;
192
- int interleave;
193
- int spacing;
194
int stride;
195
int size;
196
int reg;
197
int load;
198
- int n;
199
int vec_size;
200
- int mmu_idx;
201
- MemOp endian;
202
TCGv_i32 addr;
203
TCGv_i32 tmp;
204
- TCGv_i32 tmp2;
205
- TCGv_i64 tmp64;
206
207
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
208
return 1;
209
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
210
rn = (insn >> 16) & 0xf;
211
rm = insn & 0xf;
212
load = (insn & (1 << 21)) != 0;
213
- endian = s->be_data;
214
- mmu_idx = get_mem_index(s);
215
if ((insn & (1 << 23)) == 0) {
216
- /* Load store all elements. */
217
- op = (insn >> 8) & 0xf;
218
- size = (insn >> 6) & 3;
219
- if (op > 10)
220
- return 1;
221
- /* Catch UNDEF cases for bad values of align field */
222
- switch (op & 0xc) {
223
- case 4:
224
- if (((insn >> 5) & 1) == 1) {
225
- return 1;
226
- }
227
- break;
228
- case 8:
229
- if (((insn >> 4) & 3) == 3) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- break;
235
- }
236
- nregs = neon_ls_element_type[op].nregs;
237
- interleave = neon_ls_element_type[op].interleave;
238
- spacing = neon_ls_element_type[op].spacing;
239
- if (size == 3 && (interleave | spacing) != 1) {
240
- return 1;
241
- }
242
- /* For our purposes, bytes are always little-endian. */
243
- if (size == 0) {
244
- endian = MO_LE;
245
- }
246
- /* Consecutive little-endian elements from a single register
247
- * can be promoted to a larger little-endian operation.
248
- */
249
- if (interleave == 1 && endian == MO_LE) {
250
- size = 3;
251
- }
252
- tmp64 = tcg_temp_new_i64();
253
- addr = tcg_temp_new_i32();
254
- tmp2 = tcg_const_i32(1 << size);
255
- load_reg_var(s, addr, rn);
256
- for (reg = 0; reg < nregs; reg++) {
257
- for (n = 0; n < 8 >> size; n++) {
258
- int xs;
259
- for (xs = 0; xs < interleave; xs++) {
260
- int tt = rd + reg + spacing * xs;
261
-
262
- if (load) {
263
- gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
264
- neon_store_element64(tt, n, size, tmp64);
265
- } else {
266
- neon_load_element64(tmp64, tt, n, size);
267
- gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
268
- }
269
- tcg_gen_add_i32(addr, addr, tmp2);
270
- }
271
- }
272
- }
273
- tcg_temp_free_i32(addr);
274
- tcg_temp_free_i32(tmp2);
275
- tcg_temp_free_i64(tmp64);
276
- stride = nregs * interleave * 8;
277
+ /* Load store all elements -- handled already by decodetree */
278
+ return 1;
279
} else {
280
size = (insn >> 10) & 3;
281
if (size == 3) {
282
--
187
--
283
2.20.1
188
2.25.1
284
189
285
190
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Move misplaced comment.
3
The original A.a revision of the AArch64 ARM required that we
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.
4
8
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
This means that we do not have to consider whether or not FEAT_LVA
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
is enabled, and decide from which bit an address might need to be
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
extended.
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
12
9
Message-id: 20200427181649.26851-3-edgar.iglesias@gmail.com
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
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
17
---
12
hw/arm/xlnx-versal.c | 2 +-
18
target/arm/helper.c | 32 ++++++++++++++++++++++++--------
13
1 file changed, 1 insertion(+), 1 deletion(-)
19
1 file changed, 24 insertions(+), 8 deletions(-)
14
20
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
23
--- a/target/arm/helper.c
18
+++ b/hw/arm/xlnx-versal.c
24
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
25
@@ -XXX,XX +XXX,XX @@ static void dbgwvr_write(CPUARMState *env, const ARMCPRegInfo *ri,
20
26
ARMCPU *cpu = env_archcpu(env);
21
obj = object_new(XLNX_VERSAL_ACPU_TYPE);
27
int i = ri->crm;
22
if (!obj) {
28
23
- /* Secondary CPUs start in PSCI powered-down state */
29
- /* Bits [63:49] are hardwired to the value of bit [48]; that is, the
24
error_report("Unable to create apu.cpu[%d] of type %s",
30
- * register reads and behaves as if values written are sign extended.
25
i, XLNX_VERSAL_ACPU_TYPE);
31
+ /*
26
exit(EXIT_FAILURE);
32
* Bits [1:0] are RES0.
27
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
33
+ *
28
object_property_set_int(obj, s->cfg.psci_conduit,
34
+ * It is IMPLEMENTATION DEFINED whether [63:49] ([63:53] with FEAT_LVA)
29
"psci-conduit", &error_abort);
35
+ * are hardwired to the value of bit [48] ([52] with FEAT_LVA), or if
30
if (i) {
36
+ * they contain the value written. It is CONSTRAINED UNPREDICTABLE
31
+ /* Secondary CPUs start in PSCI powered-down state */
37
+ * whether the RESS bits are ignored when comparing an address.
32
object_property_set_bool(obj, true,
38
+ *
33
"start-powered-off", &error_abort);
39
+ * Therefore we are allowed to compare the entire register, which lets
40
+ * us avoid considering whether or not FEAT_LVA is actually enabled.
41
*/
42
- value = sextract64(value, 0, 49) & ~3ULL;
43
+ value &= ~3ULL;
44
45
raw_write(env, ri, value);
46
hw_watchpoint_update(cpu, i);
47
@@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update(ARMCPU *cpu, int n)
48
case 0: /* unlinked address match */
49
case 1: /* linked address match */
50
{
51
- /* Bits [63:49] are hardwired to the value of bit [48]; that is,
52
- * we behave as if the register was sign extended. Bits [1:0] are
53
- * RES0. The BAS field is used to allow setting breakpoints on 16
54
- * bit wide instructions; it is CONSTRAINED UNPREDICTABLE whether
55
+ /*
56
+ * Bits [1:0] are RES0.
57
+ *
58
+ * It is IMPLEMENTATION DEFINED whether bits [63:49]
59
+ * ([63:53] for FEAT_LVA) are hardwired to a copy of the sign bit
60
+ * of the VA field ([48] or [52] for FEAT_LVA), or whether the
61
+ * value is read as written. It is CONSTRAINED UNPREDICTABLE
62
+ * whether the RESS bits are ignored when comparing an address.
63
+ * Therefore we are allowed to compare the entire register, which
64
+ * lets us avoid considering whether FEAT_LVA is actually enabled.
65
+ *
66
+ * The BAS field is used to allow setting breakpoints on 16-bit
67
+ * wide instructions; it is CONSTRAINED UNPREDICTABLE whether
68
* a bp will fire if the addresses covered by the bp and the addresses
69
* covered by the insn overlap but the insn doesn't start at the
70
* start of the bp address range. We choose to require the insn and
71
@@ -XXX,XX +XXX,XX @@ void hw_breakpoint_update(ARMCPU *cpu, int n)
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;
34
}
79
}
35
--
80
--
36
2.20.1
81
2.25.1
37
38
diff view generated by jsdifflib
1
The ARMv8.2-TTS2UXN feature extends the XN field in stage 2
1
From: Richard Henderson <richard.henderson@linaro.org>
2
translation table descriptors from just bit [54] to bits [54:53],
3
allowing stage 2 to control execution permissions separately for EL0
4
and EL1. Implement the new semantics of the XN field and enable
5
the feature for our 'max' CPU.
6
2
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).
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>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20220301215958.157011-10-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200330210400.11724-5-peter.maydell@linaro.org
11
---
16
---
12
target/arm/cpu.h | 15 +++++++++++++++
17
docs/system/arm/emulation.rst | 1 +
13
target/arm/cpu.c | 1 +
18
target/arm/cpu-param.h | 2 +-
14
target/arm/cpu64.c | 2 ++
19
target/arm/cpu.h | 5 +++++
15
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++------
20
target/arm/cpu64.c | 1 +
16
4 files changed, 49 insertions(+), 6 deletions(-)
21
target/arm/helper.c | 9 ++++++++-
22
5 files changed, 16 insertions(+), 2 deletions(-)
17
23
24
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
25
index XXXXXXX..XXXXXXX 100644
26
--- a/docs/system/arm/emulation.rst
27
+++ b/docs/system/arm/emulation.rst
28
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
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
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
49
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
51
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
52
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
23
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
24
}
25
26
+static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
27
+{
28
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0;
29
+}
30
+
31
/*
32
* 64-bit feature tests via id registers.
33
*/
34
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
53
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
35
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
54
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
36
}
55
}
37
56
38
+static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
57
+static inline bool isar_feature_aa64_lva(const ARMISARegisters *id)
39
+{
58
+{
40
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
59
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0;
41
+}
60
+}
42
+
61
+
43
/*
62
static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
44
* Feature tests for "does this exist in either 32-bit or 64-bit?"
63
{
45
*/
64
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
46
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
47
return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
48
}
49
50
+static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
51
+{
52
+ return isar_feature_aa64_tts2uxn(id) || isar_feature_aa32_tts2uxn(id);
53
+}
54
+
55
/*
56
* Forward to the above feature tests given an ARMCPU pointer.
57
*/
58
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/cpu.c
61
+++ b/target/arm/cpu.c
62
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
63
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
64
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
65
t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
66
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
67
cpu->isar.id_mmfr4 = t;
68
}
69
#endif
70
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
65
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
71
index XXXXXXX..XXXXXXX 100644
66
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/cpu64.c
67
--- a/target/arm/cpu64.c
73
+++ b/target/arm/cpu64.c
68
+++ b/target/arm/cpu64.c
74
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
69
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
75
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
70
t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
76
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
71
t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1); /* TTCNP */
77
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */
72
t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1); /* TTST */
78
+ t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */
73
+ t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1); /* FEAT_LVA */
79
cpu->isar.id_aa64mmfr1 = t;
74
cpu->isar.id_aa64mmfr2 = t;
80
75
81
t = cpu->isar.id_aa64mmfr2;
76
t = cpu->isar.id_aa64zfr0;
82
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
83
u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
84
u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
85
u = FIELD_DP32(u, ID_MMFR4, CNP, 1); /* TTCNP */
86
+ u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
87
cpu->isar.id_mmfr4 = u;
88
89
u = cpu->isar.id_aa64dfr0;
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
77
diff --git a/target/arm/helper.c b/target/arm/helper.c
91
index XXXXXXX..XXXXXXX 100644
78
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/helper.c
79
--- a/target/arm/helper.c
93
+++ b/target/arm/helper.c
80
+++ b/target/arm/helper.c
94
@@ -XXX,XX +XXX,XX @@ simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
81
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
95
*
82
} else {
96
* @env: CPUARMState
83
max_tsz = 39;
97
* @s2ap: The 2-bit stage2 access permissions (S2AP)
98
- * @xn: XN (execute-never) bit
99
+ * @xn: XN (execute-never) bits
100
+ * @s1_is_el0: true if this is S2 of an S1+2 walk for EL0
101
*/
102
-static int get_S2prot(CPUARMState *env, int s2ap, int xn)
103
+static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
104
{
105
int prot = 0;
106
107
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn)
108
if (s2ap & 2) {
109
prot |= PAGE_WRITE;
110
}
84
}
111
- if (!xn) {
85
- min_tsz = 16; /* TODO: ARMv8.2-LVA */
112
- if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
113
+
86
+
114
+ if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
87
+ min_tsz = 16;
115
+ switch (xn) {
88
+ if (using64k) {
116
+ case 0:
89
+ if (cpu_isar_feature(aa64_lva, env_archcpu(env))) {
117
prot |= PAGE_EXEC;
90
+ min_tsz = 12;
118
+ break;
119
+ case 1:
120
+ if (s1_is_el0) {
121
+ prot |= PAGE_EXEC;
122
+ }
123
+ break;
124
+ case 2:
125
+ break;
126
+ case 3:
127
+ if (!s1_is_el0) {
128
+ prot |= PAGE_EXEC;
129
+ }
130
+ break;
131
+ default:
132
+ g_assert_not_reached();
133
+ }
91
+ }
134
+ } else {
92
+ }
135
+ if (!extract32(xn, 1, 1)) {
93
+ /* TODO: FEAT_LPA2 */
136
+ if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
94
137
+ prot |= PAGE_EXEC;
95
if (tsz > max_tsz) {
138
+ }
96
tsz = max_tsz;
139
}
140
}
141
return prot;
142
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
143
}
144
145
ap = extract32(attrs, 4, 2);
146
- xn = extract32(attrs, 12, 1);
147
148
if (mmu_idx == ARMMMUIdx_Stage2) {
149
ns = true;
150
- *prot = get_S2prot(env, ap, xn);
151
+ xn = extract32(attrs, 11, 2);
152
+ *prot = get_S2prot(env, ap, xn, s1_is_el0);
153
} else {
154
ns = extract32(attrs, 3, 1);
155
+ xn = extract32(attrs, 12, 1);
156
pxn = extract32(attrs, 11, 1);
157
*prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
158
}
159
--
97
--
160
2.20.1
98
2.25.1
161
162
diff view generated by jsdifflib
1
We define ARMMMUIdx_Stage2 as being an MMU index which uses a QEMU
1
From: Richard Henderson <richard.henderson@linaro.org>
2
TLB. However we never actually use the TLB -- all stage 2 lookups
3
are done by direct calls to get_phys_addr_lpae() followed by a
4
physical address load via address_space_ld*().
5
2
6
Remove Stage2 from the list of ARM MMU indexes which correspond to
3
This feature widens physical addresses (and intermediate physical
7
real core MMU indexes, and instead put it in the set of "NOTLB" ARM
4
addresses for 2-stage translation) from 48 to 52 bits, when using
8
MMU indexes.
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.
9
7
10
This allows us to drop NB_MMU_MODES to 11. It also means we can
8
Note that PAR_EL1 and HPFAR_EL2 are nominally extended, but we don't
11
safely add support for the ARMv8.3-TTS2UXN extension, which adds
9
mask out the high bits when writing to those registers, so no changes
12
permission bits to the stage 2 descriptors which define execute
10
are required there.
13
permission separatel for EL0 and EL1; supporting that while keeping
14
Stage2 in a QEMU TLB would require us to use separate TLBs for
15
"Stage2 for an EL0 access" and "Stage2 for an EL1 access", which is a
16
lot of extra complication given we aren't even using the QEMU TLB.
17
11
18
In the process of updating the comment on our MMU index use,
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
fix a couple of other minor errors:
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
20
* NS EL2 EL2&0 was missing from the list in the comment
14
Message-id: 20220301215958.157011-11-richard.henderson@linaro.org
21
* some text hadn't been updated from when we bumped NB_MMU_MODES
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
above 8
16
---
17
docs/system/arm/emulation.rst | 1 +
18
target/arm/cpu-param.h | 2 +-
19
target/arm/cpu64.c | 2 +-
20
target/arm/helper.c | 19 ++++++++++++++++---
21
4 files changed, 19 insertions(+), 5 deletions(-)
23
22
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
25
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
24
index XXXXXXX..XXXXXXX 100644
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
--- a/docs/system/arm/emulation.rst
27
Message-id: 20200330210400.11724-2-peter.maydell@linaro.org
26
+++ b/docs/system/arm/emulation.rst
28
---
27
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
29
target/arm/cpu-param.h | 2 +-
28
- FEAT_I8MM (AArch64 Int8 matrix multiplication instructions)
30
target/arm/cpu.h | 21 +++++---
29
- FEAT_JSCVT (JavaScript conversion instructions)
31
target/arm/helper.c | 112 ++++-------------------------------------
30
- FEAT_LOR (Limited ordering regions)
32
3 files changed, 27 insertions(+), 108 deletions(-)
31
+- FEAT_LPA (Large Physical Address space)
33
32
- FEAT_LRCPC (Load-acquire RCpc instructions)
33
- FEAT_LRCPC2 (Load-acquire RCpc instructions v2)
34
- FEAT_LSE (Large System Extensions)
34
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
35
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
35
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/cpu-param.h
37
--- a/target/arm/cpu-param.h
37
+++ b/target/arm/cpu-param.h
38
+++ b/target/arm/cpu-param.h
38
@@ -XXX,XX +XXX,XX @@
39
@@ -XXX,XX +XXX,XX @@
39
# define TARGET_PAGE_BITS_MIN 10
40
40
#endif
41
#ifdef TARGET_AARCH64
41
42
# define TARGET_LONG_BITS 64
42
-#define NB_MMU_MODES 12
43
-# define TARGET_PHYS_ADDR_SPACE_BITS 48
43
+#define NB_MMU_MODES 11
44
+# define TARGET_PHYS_ADDR_SPACE_BITS 52
44
45
# define TARGET_VIRT_ADDR_SPACE_BITS 52
45
#endif
46
#else
46
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
47
# define TARGET_LONG_BITS 32
48
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
47
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/cpu.h
50
--- a/target/arm/cpu64.c
49
+++ b/target/arm/cpu.h
51
+++ b/target/arm/cpu64.c
50
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
52
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
51
* handling via the TLB. The only way to do a stage 1 translation without
53
cpu->isar.id_aa64pfr1 = t;
52
* the immediate stage 2 translation is via the ATS or AT system insns,
54
53
* which can be slow-pathed and always do a page table walk.
55
t = cpu->isar.id_aa64mmfr0;
54
+ * The only use of stage 2 translations is either as part of an s1+2
56
- t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 5); /* PARange: 48 bits */
55
+ * lookup or when loading the descriptors during a stage 1 page table walk,
57
+ t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */
56
+ * and in both those cases we don't use the TLB.
58
cpu->isar.id_aa64mmfr0 = t;
57
* 4. we can also safely fold together the "32 bit EL3" and "64 bit EL3"
59
58
* translation regimes, because they map reasonably well to each other
60
t = cpu->isar.id_aa64mmfr1;
59
* and they can't both be active at the same time.
60
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
61
* NS EL1 EL1&0 stage 1+2 (aka NS PL1)
62
* NS EL1 EL1&0 stage 1+2 +PAN
63
* NS EL0 EL2&0
64
+ * NS EL2 EL2&0
65
* NS EL2 EL2&0 +PAN
66
* NS EL2 (aka NS PL2)
67
* S EL0 EL1&0 (aka S PL0)
68
* S EL1 EL1&0 (not used if EL3 is 32 bit)
69
* S EL1 EL1&0 +PAN
70
* S EL3 (aka S PL1)
71
- * NS EL1&0 stage 2
72
*
73
- * for a total of 12 different mmu_idx.
74
+ * for a total of 11 different mmu_idx.
75
*
76
* R profile CPUs have an MPU, but can use the same set of MMU indexes
77
* as A profile. They only need to distinguish NS EL0 and NS EL1 (and
78
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
79
* are not quite the same -- different CPU types (most notably M profile
80
* vs A/R profile) would like to use MMU indexes with different semantics,
81
* but since we don't ever need to use all of those in a single CPU we
82
- * can avoid setting NB_MMU_MODES to more than 8. The lower bits of
83
+ * can avoid having to set NB_MMU_MODES to "total number of A profile MMU
84
+ * modes + total number of M profile MMU modes". The lower bits of
85
* ARMMMUIdx are the core TLB mmu index, and the higher bits are always
86
* the same for any particular CPU.
87
* Variables of type ARMMUIdx are always full values, and the core
88
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
89
ARMMMUIdx_SE10_1_PAN = 9 | ARM_MMU_IDX_A,
90
ARMMMUIdx_SE3 = 10 | ARM_MMU_IDX_A,
91
92
- ARMMMUIdx_Stage2 = 11 | ARM_MMU_IDX_A,
93
-
94
/*
95
* These are not allocated TLBs and are used only for AT system
96
* instructions or for the first stage of an S12 page table walk.
97
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
98
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
99
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
100
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
101
+ /*
102
+ * Not allocated a TLB: used only for second stage of an S12 page
103
+ * table walk, or for descriptor loads during first stage of an S1
104
+ * page table walk. Note that if we ever want to have a TLB for this
105
+ * then various TLB flush insns which currently are no-ops or flush
106
+ * only stage 1 MMU indexes will need to change to flush stage 2.
107
+ */
108
+ ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
109
110
/*
111
* M-profile.
112
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
113
TO_CORE_BIT(SE10_1),
114
TO_CORE_BIT(SE10_1_PAN),
115
TO_CORE_BIT(SE3),
116
- TO_CORE_BIT(Stage2),
117
118
TO_CORE_BIT(MUser),
119
TO_CORE_BIT(MPriv),
120
diff --git a/target/arm/helper.c b/target/arm/helper.c
61
diff --git a/target/arm/helper.c b/target/arm/helper.c
121
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
122
--- a/target/arm/helper.c
63
--- a/target/arm/helper.c
123
+++ b/target/arm/helper.c
64
+++ b/target/arm/helper.c
124
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
65
@@ -XXX,XX +XXX,XX @@ static const uint8_t pamax_map[] = {
125
tlb_flush_by_mmuidx(cs,
66
[3] = 42,
126
ARMMMUIdxBit_E10_1 |
67
[4] = 44,
127
ARMMMUIdxBit_E10_1_PAN |
68
[5] = 48,
128
- ARMMMUIdxBit_E10_0 |
69
+ [6] = 52,
129
- ARMMMUIdxBit_Stage2);
70
};
130
+ ARMMMUIdxBit_E10_0);
71
131
}
72
/* The cpu-specific constant value of PAMax; also used by hw/arm/virt. */
132
73
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
133
static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
74
descaddr = extract64(ttbr, 0, 48);
134
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
75
135
tlb_flush_by_mmuidx_all_cpus_synced(cs,
76
/*
136
ARMMMUIdxBit_E10_1 |
77
- * If the base address is out of range, raise AddressSizeFault.
137
ARMMMUIdxBit_E10_1_PAN |
78
+ * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [5:2] of TTBR.
138
- ARMMMUIdxBit_E10_0 |
79
+ *
139
- ARMMMUIdxBit_Stage2);
80
+ * Otherwise, if the base address is out of range, raise AddressSizeFault.
140
+ ARMMMUIdxBit_E10_0);
81
* In the pseudocode, this is !IsZero(baseregister<47:outputsize>),
141
}
82
* but we've just cleared the bits above 47, so simplify the test.
142
83
*/
143
-static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
84
- if (descaddr >> outputsize) {
144
- uint64_t value)
85
+ if (outputsize > 48) {
145
-{
86
+ descaddr |= extract64(ttbr, 2, 4) << 48;
146
- /* Invalidate by IPA. This has to invalidate any structures that
87
+ } else if (descaddr >> outputsize) {
147
- * contain only stage 2 translation information, but does not need
88
level = 0;
148
- * to apply to structures that contain combined stage 1 and stage 2
89
fault_type = ARMFault_AddressSize;
149
- * translation information.
90
goto do_fault;
150
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
91
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
151
- */
92
}
152
- CPUState *cs = env_cpu(env);
93
153
- uint64_t pageaddr;
94
descaddr = descriptor & descaddrmask;
154
-
95
- if (descaddr >> outputsize) {
155
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
96
+
156
- return;
97
+ /*
157
- }
98
+ * For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12]
158
-
99
+ * of descriptor. Otherwise, if descaddr is out of range, raise
159
- pageaddr = sextract64(value << 12, 0, 40);
100
+ * AddressSizeFault.
160
-
101
+ */
161
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
102
+ if (outputsize > 48) {
162
-}
103
+ descaddr |= extract64(descriptor, 12, 4) << 48;
163
-
104
+ } else if (descaddr >> outputsize) {
164
-static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
105
fault_type = ARMFault_AddressSize;
165
- uint64_t value)
106
goto do_fault;
166
-{
107
}
167
- CPUState *cs = env_cpu(env);
168
- uint64_t pageaddr;
169
-
170
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
171
- return;
172
- }
173
-
174
- pageaddr = sextract64(value << 12, 0, 40);
175
-
176
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
177
- ARMMMUIdxBit_Stage2);
178
-}
179
180
static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
181
uint64_t value)
182
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
183
tlb_flush_by_mmuidx(cs,
184
ARMMMUIdxBit_E10_1 |
185
ARMMMUIdxBit_E10_1_PAN |
186
- ARMMMUIdxBit_E10_0 |
187
- ARMMMUIdxBit_Stage2);
188
+ ARMMMUIdxBit_E10_0);
189
raw_write(env, ri, value);
190
}
191
}
192
@@ -XXX,XX +XXX,XX @@ static int alle1_tlbmask(CPUARMState *env)
193
return ARMMMUIdxBit_SE10_1 |
194
ARMMMUIdxBit_SE10_1_PAN |
195
ARMMMUIdxBit_SE10_0;
196
- } else if (arm_feature(env, ARM_FEATURE_EL2)) {
197
- return ARMMMUIdxBit_E10_1 |
198
- ARMMMUIdxBit_E10_1_PAN |
199
- ARMMMUIdxBit_E10_0 |
200
- ARMMMUIdxBit_Stage2;
201
} else {
202
return ARMMMUIdxBit_E10_1 |
203
ARMMMUIdxBit_E10_1_PAN |
204
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
205
ARMMMUIdxBit_SE3);
206
}
207
208
-static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
209
- uint64_t value)
210
-{
211
- /* Invalidate by IPA. This has to invalidate any structures that
212
- * contain only stage 2 translation information, but does not need
213
- * to apply to structures that contain combined stage 1 and stage 2
214
- * translation information.
215
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
216
- */
217
- ARMCPU *cpu = env_archcpu(env);
218
- CPUState *cs = CPU(cpu);
219
- uint64_t pageaddr;
220
-
221
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
222
- return;
223
- }
224
-
225
- pageaddr = sextract64(value << 12, 0, 48);
226
-
227
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
228
-}
229
-
230
-static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
231
- uint64_t value)
232
-{
233
- CPUState *cs = env_cpu(env);
234
- uint64_t pageaddr;
235
-
236
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
237
- return;
238
- }
239
-
240
- pageaddr = sextract64(value << 12, 0, 48);
241
-
242
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
243
- ARMMMUIdxBit_Stage2);
244
-}
245
-
246
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
247
bool isread)
248
{
249
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
250
.writefn = tlbi_aa64_vae1_write },
251
{ .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
252
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
253
- .access = PL2_W, .type = ARM_CP_NO_RAW,
254
- .writefn = tlbi_aa64_ipas2e1is_write },
255
+ .access = PL2_W, .type = ARM_CP_NOP },
256
{ .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64,
257
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
258
- .access = PL2_W, .type = ARM_CP_NO_RAW,
259
- .writefn = tlbi_aa64_ipas2e1is_write },
260
+ .access = PL2_W, .type = ARM_CP_NOP },
261
{ .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
262
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
263
.access = PL2_W, .type = ARM_CP_NO_RAW,
264
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
265
.writefn = tlbi_aa64_alle1is_write },
266
{ .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64,
267
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
268
- .access = PL2_W, .type = ARM_CP_NO_RAW,
269
- .writefn = tlbi_aa64_ipas2e1_write },
270
+ .access = PL2_W, .type = ARM_CP_NOP },
271
{ .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64,
272
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
273
- .access = PL2_W, .type = ARM_CP_NO_RAW,
274
- .writefn = tlbi_aa64_ipas2e1_write },
275
+ .access = PL2_W, .type = ARM_CP_NOP },
276
{ .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64,
277
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
278
.access = PL2_W, .type = ARM_CP_NO_RAW,
279
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
280
.writefn = tlbimva_hyp_is_write },
281
{ .name = "TLBIIPAS2",
282
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
283
- .type = ARM_CP_NO_RAW, .access = PL2_W,
284
- .writefn = tlbiipas2_write },
285
+ .type = ARM_CP_NOP, .access = PL2_W },
286
{ .name = "TLBIIPAS2IS",
287
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
288
- .type = ARM_CP_NO_RAW, .access = PL2_W,
289
- .writefn = tlbiipas2_is_write },
290
+ .type = ARM_CP_NOP, .access = PL2_W },
291
{ .name = "TLBIIPAS2L",
292
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
293
- .type = ARM_CP_NO_RAW, .access = PL2_W,
294
- .writefn = tlbiipas2_write },
295
+ .type = ARM_CP_NOP, .access = PL2_W },
296
{ .name = "TLBIIPAS2LIS",
297
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
298
- .type = ARM_CP_NO_RAW, .access = PL2_W,
299
- .writefn = tlbiipas2_is_write },
300
+ .type = ARM_CP_NOP, .access = PL2_W },
301
/* 32 bit cache operations */
302
{ .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
303
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
304
--
108
--
305
2.20.1
109
2.25.1
306
307
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Remove inclusion of arm_gicv3_common.h, this already gets
3
With FEAT_LPA2, rather than introducing translation level 4,
4
included via xlnx-versal.h.
4
we introduce level -1, below the current level 0. Extend
5
arm_fi_to_lfsc to handle these faults.
5
6
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Assert that this new translation level does not leak into
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
fault types for which it is not defined, which allows some
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
masking of fi->level to be removed.
9
Message-id: 20200427181649.26851-2-edgar.iglesias@gmail.com
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
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
hw/arm/xlnx-versal.c | 1 -
16
target/arm/internals.h | 35 +++++++++++++++++++++++++++++------
13
1 file changed, 1 deletion(-)
17
1 file changed, 29 insertions(+), 6 deletions(-)
14
18
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
21
--- a/target/arm/internals.h
18
+++ b/hw/arm/xlnx-versal.c
22
+++ b/target/arm/internals.h
19
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
20
#include "hw/arm/boot.h"
24
case ARMFault_None:
21
#include "kvm_arm.h"
25
return 0;
22
#include "hw/misc/unimp.h"
26
case ARMFault_AddressSize:
23
-#include "hw/intc/arm_gicv3_common.h"
27
- fsc = fi->level & 3;
24
#include "hw/arm/xlnx-versal.h"
28
+ assert(fi->level >= -1 && fi->level <= 3);
25
#include "hw/char/pl011.h"
29
+ if (fi->level < 0) {
26
30
+ fsc = 0b101001;
31
+ } else {
32
+ fsc = fi->level;
33
+ }
34
break;
35
case ARMFault_AccessFlag:
36
- fsc = (fi->level & 3) | (0x2 << 2);
37
+ assert(fi->level >= 0 && fi->level <= 3);
38
+ fsc = 0b001000 | fi->level;
39
break;
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;
27
--
81
--
28
2.20.1
82
2.25.1
29
30
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add support for SD.
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
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
This is in preparation for FEAT_LPA2, where the interpretation
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
of 'value' depends on the effective value of DS for the regime.
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20200427181649.26851-9-edgar.iglesias@gmail.com
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20220301215958.157011-13-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
include/hw/arm/xlnx-versal.h | 12 ++++++++++++
15
target/arm/helper.c | 58 +++++++++++++++++++--------------------------
13
hw/arm/xlnx-versal.c | 31 +++++++++++++++++++++++++++++++
16
1 file changed, 24 insertions(+), 34 deletions(-)
14
2 files changed, 43 insertions(+)
15
17
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
20
--- a/target/arm/helper.c
19
+++ b/include/hw/arm/xlnx-versal.h
21
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
21
23
}
22
#include "hw/sysbus.h"
24
23
#include "hw/arm/boot.h"
25
#ifdef TARGET_AARCH64
24
+#include "hw/sd/sdhci.h"
26
-static uint64_t tlbi_aa64_range_get_length(CPUARMState *env,
25
#include "hw/intc/arm_gicv3.h"
27
- uint64_t value)
26
#include "hw/char/pl011.h"
28
-{
27
#include "hw/dma/xlnx-zdma.h"
29
- unsigned int page_shift;
28
@@ -XXX,XX +XXX,XX @@
30
- unsigned int page_size_granule;
29
#define XLNX_VERSAL_NR_UARTS 2
31
- uint64_t num;
30
#define XLNX_VERSAL_NR_GEMS 2
32
- uint64_t scale;
31
#define XLNX_VERSAL_NR_ADMAS 8
33
- uint64_t exponent;
32
+#define XLNX_VERSAL_NR_SDS 2
34
+typedef struct {
33
#define XLNX_VERSAL_NR_IRQS 192
35
+ uint64_t base;
34
36
uint64_t length;
35
typedef struct Versal {
37
+} TLBIRange;
36
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
37
} iou;
38
} lpd;
39
40
+ /* The Platform Management Controller subsystem. */
41
+ struct {
42
+ struct {
43
+ SDHCIState sd[XLNX_VERSAL_NR_SDS];
44
+ } iou;
45
+ } pmc;
46
+
38
+
47
struct {
39
+static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
48
MemoryRegion *mr_ddr;
40
+ uint64_t value)
49
uint32_t psci_conduit;
41
+{
50
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
42
+ unsigned int page_size_granule, page_shift, num, scale, exponent;
51
#define VERSAL_GEM1_IRQ_0 58
43
+ TLBIRange ret = { };
52
#define VERSAL_GEM1_WAKE_IRQ_0 59
44
53
#define VERSAL_ADMA_IRQ_0 60
45
- num = extract64(value, 39, 5);
54
+#define VERSAL_SD0_IRQ_0 126
46
- scale = extract64(value, 44, 2);
55
47
page_size_granule = extract64(value, 46, 2);
56
/* Architecturally reserved IRQs suitable for virtualization. */
48
57
#define VERSAL_RSVD_IRQ_FIRST 111
49
if (page_size_granule == 0) {
58
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
50
qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
59
#define MM_FPD_CRF 0xfd1a0000U
51
page_size_granule);
60
#define MM_FPD_CRF_SIZE 0x140000
52
- return 0;
61
53
+ return ret;
62
+#define MM_PMC_SD0 0xf1040000U
54
}
63
+#define MM_PMC_SD0_SIZE 0x10000
55
64
#define MM_PMC_CRP 0xf1260000U
56
page_shift = (page_size_granule - 1) * 2 + 12;
65
#define MM_PMC_CRP_SIZE 0x10000
57
-
66
#endif
58
+ num = extract64(value, 39, 5);
67
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
59
+ scale = extract64(value, 44, 2);
68
index XXXXXXX..XXXXXXX 100644
60
exponent = (5 * scale) + 1;
69
--- a/hw/arm/xlnx-versal.c
61
- length = (num + 1) << (exponent + page_shift);
70
+++ b/hw/arm/xlnx-versal.c
62
71
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
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)
88
{
89
ARMMMUIdx one_idx = ARM_MMU_IDX_A | ctz32(idxmap);
90
- bool two_ranges = regime_has_2_ranges(one_idx);
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);
109
} else {
110
- tlb_flush_range_by_mmuidx(env_cpu(env), baseaddr,
111
- length, idxmap, bits);
112
+ tlb_flush_range_by_mmuidx(env_cpu(env), range.base,
113
+ range.length, idxmap, bits);
72
}
114
}
73
}
115
}
74
116
75
+#define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */
76
+static void versal_create_sds(Versal *s, qemu_irq *pic)
77
+{
78
+ int i;
79
+
80
+ for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) {
81
+ DeviceState *dev;
82
+ MemoryRegion *mr;
83
+
84
+ sysbus_init_child_obj(OBJECT(s), "sd[*]",
85
+ &s->pmc.iou.sd[i], sizeof(s->pmc.iou.sd[i]),
86
+ TYPE_SYSBUS_SDHCI);
87
+ dev = DEVICE(&s->pmc.iou.sd[i]);
88
+
89
+ object_property_set_uint(OBJECT(dev),
90
+ 3, "sd-spec-version", &error_fatal);
91
+ object_property_set_uint(OBJECT(dev), SDHCI_CAPABILITIES, "capareg",
92
+ &error_fatal);
93
+ object_property_set_uint(OBJECT(dev), UHS_I, "uhs", &error_fatal);
94
+ qdev_init_nofail(dev);
95
+
96
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
97
+ memory_region_add_subregion(&s->mr_ps,
98
+ MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr);
99
+
100
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
101
+ pic[VERSAL_SD0_IRQ_0 + i * 2]);
102
+ }
103
+}
104
+
105
/* This takes the board allocated linear DDR memory and creates aliases
106
* for each split DDR range/aperture on the Versal address map.
107
*/
108
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
109
versal_create_uarts(s, pic);
110
versal_create_gems(s, pic);
111
versal_create_admas(s, pic);
112
+ versal_create_sds(s, pic);
113
versal_map_ddr(s);
114
versal_unimp(s);
115
116
--
117
--
117
2.20.1
118
2.25.1
118
119
diff view generated by jsdifflib
1
The access_type argument to get_phys_addr_lpae() is an MMUAccessType;
1
From: Richard Henderson <richard.henderson@linaro.org>
2
use the enum constant MMU_DATA_LOAD rather than a literal 0 when we
3
call it in S1_ptw_translate().
4
2
3
The shift of the BaseADDR field depends on the translation
4
granule in use.
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>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20220301215958.157011-14-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200330210400.11724-3-peter.maydell@linaro.org
9
---
12
---
10
target/arm/helper.c | 5 +++--
13
target/arm/helper.c | 5 +++--
11
1 file changed, 3 insertions(+), 2 deletions(-)
14
1 file changed, 3 insertions(+), 2 deletions(-)
12
15
13
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
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
18
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
19
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
20
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
18
pcacheattrs = &cacheattrs;
21
ret.length = (num + 1) << (exponent + page_shift);
19
}
22
20
23
if (regime_has_2_ranges(mmuidx)) {
21
- ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_Stage2, &s2pa,
24
- ret.base = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
22
- &txattrs, &s2prot, &s2size, fi, pcacheattrs);
25
+ ret.base = sextract64(value, 0, 37);
23
+ ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
26
} else {
24
+ &s2pa, &txattrs, &s2prot, &s2size, fi,
27
- ret.base = extract64(value, 0, 37) << TARGET_PAGE_BITS;
25
+ pcacheattrs);
28
+ ret.base = extract64(value, 0, 37);
26
if (ret) {
29
}
27
assert(fi->type != ARMFault_None);
30
+ ret.base <<= page_shift;
28
fi->s2addr = addr;
31
32
return ret;
33
}
29
--
34
--
30
2.20.1
35
2.25.1
31
32
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Embed the ADMAs into the SoC type.
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
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20220301215958.157011-15-richard.henderson@linaro.org
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-7-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
13
target/arm/helper.c | 10 +++++++---
14
hw/arm/xlnx-versal.c | 14 +++++++-------
14
1 file changed, 7 insertions(+), 3 deletions(-)
15
2 files changed, 9 insertions(+), 8 deletions(-)
16
15
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
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/include/hw/arm/xlnx-versal.h
18
--- a/target/arm/helper.c
20
+++ b/include/hw/arm/xlnx-versal.h
19
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static TLBIRange tlbi_aa64_get_range(CPUARMState *env, ARMMMUIdx mmuidx,
22
#include "hw/arm/boot.h"
21
uint64_t value)
23
#include "hw/intc/arm_gicv3.h"
22
{
24
#include "hw/char/pl011.h"
23
unsigned int page_size_granule, page_shift, num, scale, exponent;
25
+#include "hw/dma/xlnx-zdma.h"
24
+ /* Extract one bit to represent the va selector in use. */
26
#include "hw/net/cadence_gem.h"
25
+ uint64_t select = sextract64(value, 36, 1);
27
26
+ ARMVAParameters param = aa64_va_parameters(env, select, mmuidx, true);
28
#define TYPE_XLNX_VERSAL "xlnx-versal"
27
TLBIRange ret = { };
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
28
30
struct {
29
page_size_granule = extract64(value, 46, 2);
31
PL011State uart[XLNX_VERSAL_NR_UARTS];
30
32
CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
31
- if (page_size_granule == 0) {
33
- SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
32
- qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
34
+ XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
33
+ /* The granule encoded in value must match the granule in use. */
35
} iou;
34
+ if (page_size_granule != (param.using64k ? 3 : param.using16k ? 2 : 1)) {
36
} lpd;
35
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid tlbi page size granule %d\n",
37
36
page_size_granule);
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
37
return ret;
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
41
+++ b/hw/arm/xlnx-versal.c
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
43
DeviceState *dev;
44
MemoryRegion *mr;
45
46
- dev = qdev_create(NULL, "xlnx.zdma");
47
- s->lpd.iou.adma[i] = SYS_BUS_DEVICE(dev);
48
- object_property_set_int(OBJECT(s->lpd.iou.adma[i]), 128, "bus-width",
49
- &error_abort);
50
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
51
+ sysbus_init_child_obj(OBJECT(s), name,
52
+ &s->lpd.iou.adma[i], sizeof(s->lpd.iou.adma[i]),
53
+ TYPE_XLNX_ZDMA);
54
+ dev = DEVICE(&s->lpd.iou.adma[i]);
55
+ object_property_set_int(OBJECT(dev), 128, "bus-width", &error_abort);
56
qdev_init_nofail(dev);
57
58
- mr = sysbus_mmio_get_region(s->lpd.iou.adma[i], 0);
59
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
60
memory_region_add_subregion(&s->mr_ps,
61
MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr);
62
63
- sysbus_connect_irq(s->lpd.iou.adma[i], 0, pic[VERSAL_ADMA_IRQ_0 + i]);
64
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]);
65
g_free(name);
66
}
38
}
67
}
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);
68
--
48
--
69
2.20.1
49
2.25.1
70
71
diff view generated by jsdifflib
1
In aarch64_max_initfn() we update both 32-bit and 64-bit ID
1
From: Richard Henderson <richard.henderson@linaro.org>
2
registers. The intended pattern is that for 64-bit ID registers we
3
use FIELD_DP64 and the uint64_t 't' register, while 32-bit ID
4
registers use FIELD_DP32 and the uint32_t 'u' register. For
5
ID_AA64DFR0 we accidentally used 'u', meaning that the top 32 bits of
6
this 64-bit ID register would end up always zero. Luckily at the
7
moment that's what they should be anyway, so this bug has no visible
8
effects.
9
2
10
Use the right-sized variable.
3
We support 16k pages, but do not advertize that in ID_AA64MMFR0.
11
4
12
Fixes: 3bec78447a958d481991
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.
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20220301215958.157011-16-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20200423110915.10527-1-peter.maydell@linaro.org
17
---
13
---
18
target/arm/cpu64.c | 6 +++---
14
target/arm/cpu64.c | 4 ++++
19
1 file changed, 3 insertions(+), 3 deletions(-)
15
1 file changed, 4 insertions(+)
20
16
21
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
17
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
22
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu64.c
19
--- a/target/arm/cpu64.c
24
+++ b/target/arm/cpu64.c
20
+++ b/target/arm/cpu64.c
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
21
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
26
u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
22
27
cpu->isar.id_mmfr4 = u;
23
t = cpu->isar.id_aa64mmfr0;
28
24
t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6); /* FEAT_LPA: 52 bits */
29
- u = cpu->isar.id_aa64dfr0;
25
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 1); /* 16k pages supported */
30
- u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
26
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 2); /* 16k stage2 supported */
31
- cpu->isar.id_aa64dfr0 = u;
27
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN64_2, 2); /* 64k stage2 supported */
32
+ t = cpu->isar.id_aa64dfr0;
28
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */
33
+ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
29
cpu->isar.id_aa64mmfr0 = t;
34
+ cpu->isar.id_aa64dfr0 = t;
30
35
31
t = cpu->isar.id_aa64mmfr1;
36
u = cpu->isar.id_dfr0;
37
u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
38
--
32
--
39
2.20.1
33
2.25.1
40
41
diff view generated by jsdifflib
Deleted patch
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
1
3
Embed the GEMs into the SoC type.
4
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-6-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
14
hw/arm/xlnx-versal.c | 15 ++++++++-------
15
2 files changed, 10 insertions(+), 8 deletions(-)
16
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
20
+++ b/include/hw/arm/xlnx-versal.h
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/arm/boot.h"
23
#include "hw/intc/arm_gicv3.h"
24
#include "hw/char/pl011.h"
25
+#include "hw/net/cadence_gem.h"
26
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
30
31
struct {
32
PL011State uart[XLNX_VERSAL_NR_UARTS];
33
- SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
34
+ CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
35
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
36
} iou;
37
} lpd;
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
41
+++ b/hw/arm/xlnx-versal.c
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
43
DeviceState *dev;
44
MemoryRegion *mr;
45
46
- dev = qdev_create(NULL, "cadence_gem");
47
- s->lpd.iou.gem[i] = SYS_BUS_DEVICE(dev);
48
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
49
+ sysbus_init_child_obj(OBJECT(s), name,
50
+ &s->lpd.iou.gem[i], sizeof(s->lpd.iou.gem[i]),
51
+ TYPE_CADENCE_GEM);
52
+ dev = DEVICE(&s->lpd.iou.gem[i]);
53
if (nd->used) {
54
qemu_check_nic_model(nd, "cadence_gem");
55
qdev_set_nic_properties(dev, nd);
56
}
57
- object_property_set_int(OBJECT(s->lpd.iou.gem[i]),
58
+ object_property_set_int(OBJECT(dev),
59
2, "num-priority-queues",
60
&error_abort);
61
- object_property_set_link(OBJECT(s->lpd.iou.gem[i]),
62
+ object_property_set_link(OBJECT(dev),
63
OBJECT(&s->mr_ps), "dma",
64
&error_abort);
65
qdev_init_nofail(dev);
66
67
- mr = sysbus_mmio_get_region(s->lpd.iou.gem[i], 0);
68
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
69
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
70
71
- sysbus_connect_irq(s->lpd.iou.gem[i], 0, pic[irqs[i]]);
72
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
73
g_free(name);
74
}
75
}
76
--
77
2.20.1
78
79
diff view generated by jsdifflib
1
Somewhere along theline we accidentally added a duplicate
1
From: Richard Henderson <richard.henderson@linaro.org>
2
"using D16-D31 when they don't exist" check to do_vfm_dp()
2
3
(probably an artifact of a patchseries rebase). Remove it.
3
This feature widens physical addresses (and intermediate physical
4
4
addresses for 2-stage translation) from 48 to 52 bits, when using
5
4k or 16k pages.
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>
19
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20220301215958.157011-17-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200430181003.21682-2-peter.maydell@linaro.org
9
---
22
---
10
target/arm/translate-vfp.inc.c | 6 ------
23
docs/system/arm/emulation.rst | 1 +
11
1 file changed, 6 deletions(-)
24
target/arm/cpu.h | 22 ++++++++
12
25
target/arm/internals.h | 2 +
13
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
26
target/arm/helper.c | 102 +++++++++++++++++++++++++++++-----
27
4 files changed, 112 insertions(+), 15 deletions(-)
28
29
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
14
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-vfp.inc.c
31
--- a/docs/system/arm/emulation.rst
16
+++ b/target/arm/translate-vfp.inc.c
32
+++ b/docs/system/arm/emulation.rst
17
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
33
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
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;
47
}
48
49
+static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
50
+{
51
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1;
52
+}
53
+
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)
72
{
73
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
74
diff --git a/target/arm/internals.h b/target/arm/internals.h
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/internals.h
77
+++ b/target/arm/internals.h
78
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
79
typedef struct ARMVAParameters {
80
unsigned tsz : 8;
81
unsigned ps : 3;
82
+ unsigned sh : 2;
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)) {
18
return false;
126
return false;
19
}
127
}
20
128
21
- /* UNDEF accesses to D16-D31 if they don't exist. */
129
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
22
- if (!dc_isar_feature(aa32_simd_r32, s) &&
130
ARMMMUIdx mmu_idx, bool data)
23
- ((a->vd | a->vn | a->vm) & 0x10)) {
131
{
24
- return false;
132
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
25
- }
133
- bool epd, hpd, using16k, using64k, tsz_oob;
26
-
134
- int select, tsz, tbi, max_tsz, min_tsz, ps;
27
if (!vfp_access_check(s)) {
135
+ bool epd, hpd, using16k, using64k, tsz_oob, ds;
28
return true;
136
+ int select, tsz, tbi, max_tsz, min_tsz, ps, sh;
29
}
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
};
228
}
229
230
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
231
* VTCR_EL2.SL0 field (whose interpretation depends on the page size)
232
*/
233
uint32_t sl0 = extract32(tcr->raw_tcr, 6, 2);
234
+ uint32_t sl2 = extract64(tcr->raw_tcr, 33, 1);
235
uint32_t startlevel;
236
bool ok;
237
238
- if (!aarch64 || stride == 9) {
239
+ /* SL2 is RES0 unless DS=1 & 4kb granule. */
240
+ if (param.ds && stride == 9 && sl2) {
241
+ if (sl0 != 0) {
242
+ level = 0;
243
+ fault_type = ARMFault_Translation;
244
+ goto do_fault;
245
+ }
246
+ startlevel = -1;
247
+ } else if (!aarch64 || stride == 9) {
248
/* AArch32 or 4KB pages */
249
startlevel = 2 - sl0;
250
251
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
252
* for both v7 and v8. However, for v8 the SBZ bits [47:40] must be 0
253
* or an AddressSize fault is raised. So for v8 we extract those SBZ
254
* bits as part of the address, which will be checked via outputsize.
255
- * For AArch64, the address field always goes up to bit 47 (with extra
256
- * bits for FEAT_LPA placed elsewhere). AArch64 implies v8.
257
+ * For AArch64, the address field goes up to bit 47, or 49 with FEAT_LPA2;
258
+ * the highest bits of a 52-bit output are placed elsewhere.
259
*/
260
- if (arm_feature(env, ARM_FEATURE_V8)) {
261
+ if (param.ds) {
262
+ descaddrmask = MAKE_64BIT_MASK(0, 50);
263
+ } else if (arm_feature(env, ARM_FEATURE_V8)) {
264
descaddrmask = MAKE_64BIT_MASK(0, 48);
265
} else {
266
descaddrmask = MAKE_64BIT_MASK(0, 40);
267
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
268
269
/*
270
* For FEAT_LPA and PS=6, bits [51:48] of descaddr are in [15:12]
271
- * of descriptor. Otherwise, if descaddr is out of range, raise
272
- * AddressSizeFault.
273
+ * of descriptor. For FEAT_LPA2 and effective DS, bits [51:50] of
274
+ * descaddr are in [9:8]. Otherwise, if descaddr is out of range,
275
+ * raise AddressSizeFault.
276
*/
277
if (outputsize > 48) {
278
- descaddr |= extract64(descriptor, 12, 4) << 48;
279
+ if (param.ds) {
280
+ descaddr |= extract64(descriptor, 8, 2) << 50;
281
+ } else {
282
+ descaddr |= extract64(descriptor, 12, 4) << 48;
283
+ }
284
} else if (descaddr >> outputsize) {
285
fault_type = ARMFault_AddressSize;
286
goto do_fault;
287
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
288
assert(attrindx <= 7);
289
cacheattrs->attrs = extract64(mair, attrindx * 8, 8);
290
}
291
- cacheattrs->shareability = extract32(attrs, 6, 2);
292
+
293
+ /*
294
+ * For FEAT_LPA2 and effective DS, the SH field in the attributes
295
+ * was re-purposed for output address bits. The SH attribute in
296
+ * that case comes from TCR_ELx, which we extracted earlier.
297
+ */
298
+ if (param.ds) {
299
+ cacheattrs->shareability = param.sh;
300
+ } else {
301
+ cacheattrs->shareability = extract32(attrs, 6, 2);
302
+ }
303
304
*phys_ptr = descaddr;
305
*page_size_ptr = page_size;
30
--
306
--
31
2.20.1
307
2.25.1
32
33
diff view generated by jsdifflib
Deleted patch
1
We were accidentally permitting decode of Thumb Neon insns even if
2
the CPU didn't have the FEATURE_NEON bit set, because the feature
3
check was being done before the call to disas_neon_data_insn() and
4
disas_neon_ls_insn() in the Arm decoder but was omitted from the
5
Thumb decoder. Push the feature bit check down into the called
6
functions so it is done for both Arm and Thumb encodings.
7
1
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20200430181003.21682-3-peter.maydell@linaro.org
12
---
13
target/arm/translate.c | 16 ++++++++--------
14
1 file changed, 8 insertions(+), 8 deletions(-)
15
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
19
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
21
TCGv_i32 tmp2;
22
TCGv_i64 tmp64;
23
24
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
25
+ return 1;
26
+ }
27
+
28
/* FIXME: this access check should not take precedence over UNDEF
29
* for invalid encodings; we will generate incorrect syndrome information
30
* for attempts to execute invalid vfp/neon encodings with FP disabled.
31
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
32
TCGv_ptr ptr1, ptr2, ptr3;
33
TCGv_i64 tmp64;
34
35
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
36
+ return 1;
37
+ }
38
+
39
/* FIXME: this access check should not take precedence over UNDEF
40
* for invalid encodings; we will generate incorrect syndrome information
41
* for attempts to execute invalid vfp/neon encodings with FP disabled.
42
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
43
44
if (((insn >> 25) & 7) == 1) {
45
/* NEON Data processing. */
46
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
47
- goto illegal_op;
48
- }
49
-
50
if (disas_neon_data_insn(s, insn)) {
51
goto illegal_op;
52
}
53
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
54
}
55
if ((insn & 0x0f100000) == 0x04000000) {
56
/* NEON load/store. */
57
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
58
- goto illegal_op;
59
- }
60
-
61
if (disas_neon_ls_insn(s, insn)) {
62
goto illegal_op;
63
}
64
--
65
2.20.1
66
67
diff view generated by jsdifflib
Deleted patch
1
Convert the VCMLA (vector) insns in the 3same extension group to
2
decodetree.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-5-peter.maydell@linaro.org
7
---
8
target/arm/neon-shared.decode | 11 ++++++++++
9
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 11 +---------
11
3 files changed, 49 insertions(+), 10 deletions(-)
12
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
16
+++ b/target/arm/neon-shared.decode
17
@@ -XXX,XX +XXX,XX @@
18
# More specifically, this covers:
19
# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
20
# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
21
+
22
+# VFP/Neon register fields; same as vfp.decode
23
+%vm_dp 5:1 0:4
24
+%vm_sp 0:4 5:1
25
+%vn_dp 7:1 16:4
26
+%vn_sp 16:4 7:1
27
+%vd_dp 22:1 12:4
28
+%vd_sp 12:4 22:1
29
+
30
+VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
31
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
32
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-neon.inc.c
35
+++ b/target/arm/translate-neon.inc.c
36
@@ -XXX,XX +XXX,XX @@
37
#include "decode-neon-dp.inc.c"
38
#include "decode-neon-ls.inc.c"
39
#include "decode-neon-shared.inc.c"
40
+
41
+static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
42
+{
43
+ int opr_sz;
44
+ TCGv_ptr fpst;
45
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
46
+
47
+ if (!dc_isar_feature(aa32_vcma, s)
48
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
49
+ return false;
50
+ }
51
+
52
+ /* UNDEF accesses to D16-D31 if they don't exist. */
53
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
54
+ ((a->vd | a->vn | a->vm) & 0x10)) {
55
+ return false;
56
+ }
57
+
58
+ if ((a->vn | a->vm | a->vd) & a->q) {
59
+ return false;
60
+ }
61
+
62
+ if (!vfp_access_check(s)) {
63
+ return true;
64
+ }
65
+
66
+ opr_sz = (1 + a->q) * 8;
67
+ fpst = get_fpstatus_ptr(1);
68
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
69
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
70
+ vfp_reg_offset(1, a->vn),
71
+ vfp_reg_offset(1, a->vm),
72
+ fpst, opr_sz, opr_sz, a->rot,
73
+ fn_gvec_ptr);
74
+ tcg_temp_free_ptr(fpst);
75
+ return true;
76
+}
77
diff --git a/target/arm/translate.c b/target/arm/translate.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/translate.c
80
+++ b/target/arm/translate.c
81
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
82
bool is_long = false, q = extract32(insn, 6, 1);
83
bool ptr_is_env = false;
84
85
- if ((insn & 0xfe200f10) == 0xfc200800) {
86
- /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
87
- int size = extract32(insn, 20, 1);
88
- data = extract32(insn, 23, 2); /* rot */
89
- if (!dc_isar_feature(aa32_vcma, s)
90
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
91
- return 1;
92
- }
93
- fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
94
- } else if ((insn & 0xfea00f10) == 0xfc800800) {
95
+ if ((insn & 0xfea00f10) == 0xfc800800) {
96
/* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
97
int size = extract32(insn, 20, 1);
98
data = extract32(insn, 24, 1); /* rot */
99
--
100
2.20.1
101
102
diff view generated by jsdifflib
Deleted patch
1
Convert the VCADD (vector) insns to decodetree.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-6-peter.maydell@linaro.org
6
---
7
target/arm/neon-shared.decode | 3 +++
8
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 11 +---------
10
3 files changed, 41 insertions(+), 10 deletions(-)
11
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
15
+++ b/target/arm/neon-shared.decode
16
@@ -XXX,XX +XXX,XX @@
17
18
VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
+
21
+VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
22
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
23
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/translate-neon.inc.c
26
+++ b/target/arm/translate-neon.inc.c
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
28
tcg_temp_free_ptr(fpst);
29
return true;
30
}
31
+
32
+static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
33
+{
34
+ int opr_sz;
35
+ TCGv_ptr fpst;
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
37
+
38
+ if (!dc_isar_feature(aa32_vcma, s)
39
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
40
+ return false;
41
+ }
42
+
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
45
+ ((a->vd | a->vn | a->vm) & 0x10)) {
46
+ return false;
47
+ }
48
+
49
+ if ((a->vn | a->vm | a->vd) & a->q) {
50
+ return false;
51
+ }
52
+
53
+ if (!vfp_access_check(s)) {
54
+ return true;
55
+ }
56
+
57
+ opr_sz = (1 + a->q) * 8;
58
+ fpst = get_fpstatus_ptr(1);
59
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
60
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->vm),
63
+ fpst, opr_sz, opr_sz, a->rot,
64
+ fn_gvec_ptr);
65
+ tcg_temp_free_ptr(fpst);
66
+ return true;
67
+}
68
diff --git a/target/arm/translate.c b/target/arm/translate.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/translate.c
71
+++ b/target/arm/translate.c
72
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
73
bool is_long = false, q = extract32(insn, 6, 1);
74
bool ptr_is_env = false;
75
76
- if ((insn & 0xfea00f10) == 0xfc800800) {
77
- /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
78
- int size = extract32(insn, 20, 1);
79
- data = extract32(insn, 24, 1); /* rot */
80
- if (!dc_isar_feature(aa32_vcma, s)
81
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
82
- return 1;
83
- }
84
- fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
85
- } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
86
+ if ((insn & 0xfeb00f00) == 0xfc200d00) {
87
/* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
88
bool u = extract32(insn, 4, 1);
89
if (!dc_isar_feature(aa32_dp, s)) {
90
--
91
2.20.1
92
93
diff view generated by jsdifflib
Deleted patch
1
Convert the V[US]DOT (vector) insns to decodetree.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-7-peter.maydell@linaro.org
6
---
7
target/arm/neon-shared.decode | 4 ++++
8
target/arm/translate-neon.inc.c | 32 ++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 9 +--------
10
3 files changed, 37 insertions(+), 8 deletions(-)
11
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
15
+++ b/target/arm/neon-shared.decode
16
@@ -XXX,XX +XXX,XX @@ VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
17
18
VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
+
21
+# VUDOT and VSDOT
22
+VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-neon.inc.c
27
+++ b/target/arm/translate-neon.inc.c
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
29
tcg_temp_free_ptr(fpst);
30
return true;
31
}
32
+
33
+static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
34
+{
35
+ int opr_sz;
36
+ gen_helper_gvec_3 *fn_gvec;
37
+
38
+ if (!dc_isar_feature(aa32_dp, s)) {
39
+ return false;
40
+ }
41
+
42
+ /* UNDEF accesses to D16-D31 if they don't exist. */
43
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
44
+ ((a->vd | a->vn | a->vm) & 0x10)) {
45
+ return false;
46
+ }
47
+
48
+ if ((a->vn | a->vm | a->vd) & a->q) {
49
+ return false;
50
+ }
51
+
52
+ if (!vfp_access_check(s)) {
53
+ return true;
54
+ }
55
+
56
+ opr_sz = (1 + a->q) * 8;
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
58
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
59
+ vfp_reg_offset(1, a->vn),
60
+ vfp_reg_offset(1, a->vm),
61
+ opr_sz, opr_sz, 0, fn_gvec);
62
+ return true;
63
+}
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate.c
67
+++ b/target/arm/translate.c
68
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
69
bool is_long = false, q = extract32(insn, 6, 1);
70
bool ptr_is_env = false;
71
72
- if ((insn & 0xfeb00f00) == 0xfc200d00) {
73
- /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
74
- bool u = extract32(insn, 4, 1);
75
- if (!dc_isar_feature(aa32_dp, s)) {
76
- return 1;
77
- }
78
- fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
79
- } else if ((insn & 0xff300f10) == 0xfc200810) {
80
+ if ((insn & 0xff300f10) == 0xfc200810) {
81
/* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
82
int is_s = extract32(insn, 23, 1);
83
if (!dc_isar_feature(aa32_fhm, s)) {
84
--
85
2.20.1
86
87
diff view generated by jsdifflib
Deleted patch
1
Convert the VFM[AS]L (vector) insns to decodetree. This is the last
2
insn in the legacy decoder for the 3same_ext group, so we can
3
delete the legacy decoder function for the group entirely.
4
1
5
Note that in disas_thumb2_insn() the parts of this encoding space
6
where the decodetree decoder returns false will correctly be directed
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
8
into disas_coproc_insn() by mistake.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-8-peter.maydell@linaro.org
13
---
14
target/arm/neon-shared.decode | 6 +++
15
target/arm/translate-neon.inc.c | 31 +++++++++++
16
target/arm/translate.c | 92 +--------------------------------
17
3 files changed, 38 insertions(+), 91 deletions(-)
18
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
22
+++ b/target/arm/neon-shared.decode
23
@@ -XXX,XX +XXX,XX @@ VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
24
# VUDOT and VSDOT
25
VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
27
+
28
+# VFM[AS]L
29
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
30
+ vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
31
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
32
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
33
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-neon.inc.c
36
+++ b/target/arm/translate-neon.inc.c
37
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
38
opr_sz, opr_sz, 0, fn_gvec);
39
return true;
40
}
41
+
42
+static bool trans_VFML(DisasContext *s, arg_VFML *a)
43
+{
44
+ int opr_sz;
45
+
46
+ if (!dc_isar_feature(aa32_fhm, s)) {
47
+ return false;
48
+ }
49
+
50
+ /* UNDEF accesses to D16-D31 if they don't exist. */
51
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
52
+ (a->vd & 0x10)) {
53
+ return false;
54
+ }
55
+
56
+ if (a->vd & a->q) {
57
+ return false;
58
+ }
59
+
60
+ if (!vfp_access_check(s)) {
61
+ return true;
62
+ }
63
+
64
+ opr_sz = (1 + a->q) * 8;
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(a->q, a->vn),
67
+ vfp_reg_offset(a->q, a->vm),
68
+ cpu_env, opr_sz, opr_sz, a->s, /* is_2 == 0 */
69
+ gen_helper_gvec_fmlal_a32);
70
+ return true;
71
+}
72
diff --git a/target/arm/translate.c b/target/arm/translate.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/translate.c
75
+++ b/target/arm/translate.c
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
77
return 0;
78
}
79
80
-/* Advanced SIMD three registers of the same length extension.
81
- * 31 25 23 22 20 16 12 11 10 9 8 3 0
82
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
83
- * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
84
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
85
- */
86
-static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
87
-{
88
- gen_helper_gvec_3 *fn_gvec = NULL;
89
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
90
- int rd, rn, rm, opr_sz;
91
- int data = 0;
92
- int off_rn, off_rm;
93
- bool is_long = false, q = extract32(insn, 6, 1);
94
- bool ptr_is_env = false;
95
-
96
- if ((insn & 0xff300f10) == 0xfc200810) {
97
- /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
98
- int is_s = extract32(insn, 23, 1);
99
- if (!dc_isar_feature(aa32_fhm, s)) {
100
- return 1;
101
- }
102
- is_long = true;
103
- data = is_s; /* is_2 == 0 */
104
- fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
105
- ptr_is_env = true;
106
- } else {
107
- return 1;
108
- }
109
-
110
- VFP_DREG_D(rd, insn);
111
- if (rd & q) {
112
- return 1;
113
- }
114
- if (q || !is_long) {
115
- VFP_DREG_N(rn, insn);
116
- VFP_DREG_M(rm, insn);
117
- if ((rn | rm) & q & !is_long) {
118
- return 1;
119
- }
120
- off_rn = vfp_reg_offset(1, rn);
121
- off_rm = vfp_reg_offset(1, rm);
122
- } else {
123
- rn = VFP_SREG_N(insn);
124
- rm = VFP_SREG_M(insn);
125
- off_rn = vfp_reg_offset(0, rn);
126
- off_rm = vfp_reg_offset(0, rm);
127
- }
128
-
129
- if (s->fp_excp_el) {
130
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
131
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
132
- return 0;
133
- }
134
- if (!s->vfp_enabled) {
135
- return 1;
136
- }
137
-
138
- opr_sz = (1 + q) * 8;
139
- if (fn_gvec_ptr) {
140
- TCGv_ptr ptr;
141
- if (ptr_is_env) {
142
- ptr = cpu_env;
143
- } else {
144
- ptr = get_fpstatus_ptr(1);
145
- }
146
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
147
- opr_sz, opr_sz, data, fn_gvec_ptr);
148
- if (!ptr_is_env) {
149
- tcg_temp_free_ptr(ptr);
150
- }
151
- } else {
152
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
153
- opr_sz, opr_sz, data, fn_gvec);
154
- }
155
- return 0;
156
-}
157
-
158
/* Advanced SIMD two registers and a scalar extension.
159
* 31 24 23 22 20 16 12 11 10 9 8 3 0
160
* +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
161
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
162
}
163
}
164
}
165
- } else if ((insn & 0x0e000a00) == 0x0c000800
166
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
167
- if (disas_neon_insn_3same_ext(s, insn)) {
168
- goto illegal_op;
169
- }
170
- return;
171
} else if ((insn & 0x0f000a00) == 0x0e000800
172
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
173
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
174
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
175
}
176
break;
177
}
178
- if ((insn & 0xfe000a00) == 0xfc000800
179
+ if ((insn & 0xff000a00) == 0xfe000800
180
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
181
/* The Thumb2 and ARM encodings are identical. */
182
- if (disas_neon_insn_3same_ext(s, insn)) {
183
- goto illegal_op;
184
- }
185
- } else if ((insn & 0xff000a00) == 0xfe000800
186
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
187
- /* The Thumb2 and ARM encodings are identical. */
188
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
189
goto illegal_op;
190
}
191
--
192
2.20.1
193
194
diff view generated by jsdifflib
Deleted patch
1
Convert VCMLA (scalar) in the 2reg-scalar-ext group to decodetree.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-9-peter.maydell@linaro.org
6
---
7
target/arm/neon-shared.decode | 5 +++++
8
target/arm/translate-neon.inc.c | 40 +++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 26 +--------------------
10
3 files changed, 46 insertions(+), 25 deletions(-)
11
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
15
+++ b/target/arm/neon-shared.decode
16
@@ -XXX,XX +XXX,XX @@ VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
17
vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
18
VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
20
+
21
+VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
22
+ vn=%vn_dp vd=%vd_dp size=0
23
+VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
24
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
25
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/translate-neon.inc.c
28
+++ b/target/arm/translate-neon.inc.c
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML(DisasContext *s, arg_VFML *a)
30
gen_helper_gvec_fmlal_a32);
31
return true;
32
}
33
+
34
+static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
35
+{
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
37
+ int opr_sz;
38
+ TCGv_ptr fpst;
39
+
40
+ if (!dc_isar_feature(aa32_vcma, s)) {
41
+ return false;
42
+ }
43
+ if (a->size == 0 && !dc_isar_feature(aa32_fp16_arith, s)) {
44
+ return false;
45
+ }
46
+
47
+ /* UNDEF accesses to D16-D31 if they don't exist. */
48
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
49
+ ((a->vd | a->vn | a->vm) & 0x10)) {
50
+ return false;
51
+ }
52
+
53
+ if ((a->vd | a->vn) & a->q) {
54
+ return false;
55
+ }
56
+
57
+ if (!vfp_access_check(s)) {
58
+ return true;
59
+ }
60
+
61
+ fn_gvec_ptr = (a->size ? gen_helper_gvec_fcmlas_idx
62
+ : gen_helper_gvec_fcmlah_idx);
63
+ opr_sz = (1 + a->q) * 8;
64
+ fpst = get_fpstatus_ptr(1);
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(1, a->vn),
67
+ vfp_reg_offset(1, a->vm),
68
+ fpst, opr_sz, opr_sz,
69
+ (a->index << 2) | a->rot, fn_gvec_ptr);
70
+ tcg_temp_free_ptr(fpst);
71
+ return true;
72
+}
73
diff --git a/target/arm/translate.c b/target/arm/translate.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/target/arm/translate.c
76
+++ b/target/arm/translate.c
77
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
78
bool is_long = false, q = extract32(insn, 6, 1);
79
bool ptr_is_env = false;
80
81
- if ((insn & 0xff000f10) == 0xfe000800) {
82
- /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
83
- int rot = extract32(insn, 20, 2);
84
- int size = extract32(insn, 23, 1);
85
- int index;
86
-
87
- if (!dc_isar_feature(aa32_vcma, s)) {
88
- return 1;
89
- }
90
- if (size == 0) {
91
- if (!dc_isar_feature(aa32_fp16_arith, s)) {
92
- return 1;
93
- }
94
- /* For fp16, rm is just Vm, and index is M. */
95
- rm = extract32(insn, 0, 4);
96
- index = extract32(insn, 5, 1);
97
- } else {
98
- /* For fp32, rm is the usual M:Vm, and index is 0. */
99
- VFP_DREG_M(rm, insn);
100
- index = 0;
101
- }
102
- data = (index << 2) | rot;
103
- fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
104
- : gen_helper_gvec_fcmlah_idx);
105
- } else if ((insn & 0xffb00f00) == 0xfe200d00) {
106
+ if ((insn & 0xffb00f00) == 0xfe200d00) {
107
/* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
108
int u = extract32(insn, 4, 1);
109
110
--
111
2.20.1
112
113
diff view generated by jsdifflib
Deleted patch
1
Convert the V[US]DOT (scalar) insns in the 2reg-scalar-ext group
2
to decodetree.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-10-peter.maydell@linaro.org
7
---
8
target/arm/neon-shared.decode | 3 +++
9
target/arm/translate-neon.inc.c | 35 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 13 +-----------
11
3 files changed, 39 insertions(+), 12 deletions(-)
12
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
16
+++ b/target/arm/neon-shared.decode
17
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
18
vn=%vn_dp vd=%vd_dp size=0
19
VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
20
vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
21
+
22
+VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-neon.inc.c
27
+++ b/target/arm/translate-neon.inc.c
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
29
tcg_temp_free_ptr(fpst);
30
return true;
31
}
32
+
33
+static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
34
+{
35
+ gen_helper_gvec_3 *fn_gvec;
36
+ int opr_sz;
37
+ TCGv_ptr fpst;
38
+
39
+ if (!dc_isar_feature(aa32_dp, s)) {
40
+ return false;
41
+ }
42
+
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
45
+ ((a->vd | a->vn) & 0x10)) {
46
+ return false;
47
+ }
48
+
49
+ if ((a->vd | a->vn) & a->q) {
50
+ return false;
51
+ }
52
+
53
+ if (!vfp_access_check(s)) {
54
+ return true;
55
+ }
56
+
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
58
+ opr_sz = (1 + a->q) * 8;
59
+ fpst = get_fpstatus_ptr(1);
60
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->rm),
63
+ opr_sz, opr_sz, a->index, fn_gvec);
64
+ tcg_temp_free_ptr(fpst);
65
+ return true;
66
+}
67
diff --git a/target/arm/translate.c b/target/arm/translate.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/translate.c
70
+++ b/target/arm/translate.c
71
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
72
bool is_long = false, q = extract32(insn, 6, 1);
73
bool ptr_is_env = false;
74
75
- if ((insn & 0xffb00f00) == 0xfe200d00) {
76
- /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
77
- int u = extract32(insn, 4, 1);
78
-
79
- if (!dc_isar_feature(aa32_dp, s)) {
80
- return 1;
81
- }
82
- fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
83
- /* rm is just Vm, and index is M. */
84
- data = extract32(insn, 5, 1); /* index */
85
- rm = extract32(insn, 0, 4);
86
- } else if ((insn & 0xffa00f10) == 0xfe000810) {
87
+ if ((insn & 0xffa00f10) == 0xfe000810) {
88
/* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
89
int is_s = extract32(insn, 20, 1);
90
int vm20 = extract32(insn, 0, 3);
91
--
92
2.20.1
93
94
diff view generated by jsdifflib
Deleted patch
1
Convert the VFM[AS]L (scalar) insns in the 2reg-scalar-ext group
2
to decodetree. These are the last ones in the group so we can remove
3
all the legacy decode for the group.
4
1
5
Note that in disas_thumb2_insn() the parts of this encoding space
6
where the decodetree decoder returns false will correctly be directed
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
8
into disas_coproc_insn() by mistake.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-11-peter.maydell@linaro.org
13
---
14
target/arm/neon-shared.decode | 7 +++
15
target/arm/translate-neon.inc.c | 32 ++++++++++
16
target/arm/translate.c | 107 +-------------------------------
17
3 files changed, 40 insertions(+), 106 deletions(-)
18
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
22
+++ b/target/arm/neon-shared.decode
23
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
24
25
VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
27
+
28
+%vfml_scalar_q0_rm 0:3 5:1
29
+%vfml_scalar_q1_index 5:1 3:1
30
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 0 . 1 index:1 ... \
31
+ rm=%vfml_scalar_q0_rm vn=%vn_sp vd=%vd_dp q=0
32
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 1 . 1 . rm:3 \
33
+ index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp q=1
34
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-neon.inc.c
37
+++ b/target/arm/translate-neon.inc.c
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
39
tcg_temp_free_ptr(fpst);
40
return true;
41
}
42
+
43
+static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
44
+{
45
+ int opr_sz;
46
+
47
+ if (!dc_isar_feature(aa32_fhm, s)) {
48
+ return false;
49
+ }
50
+
51
+ /* UNDEF accesses to D16-D31 if they don't exist. */
52
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
53
+ ((a->vd & 0x10) || (a->q && (a->vn & 0x10)))) {
54
+ return false;
55
+ }
56
+
57
+ if (a->vd & a->q) {
58
+ return false;
59
+ }
60
+
61
+ if (!vfp_access_check(s)) {
62
+ return true;
63
+ }
64
+
65
+ opr_sz = (1 + a->q) * 8;
66
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
67
+ vfp_reg_offset(a->q, a->vn),
68
+ vfp_reg_offset(a->q, a->rm),
69
+ cpu_env, opr_sz, opr_sz,
70
+ (a->index << 2) | a->s, /* is_2 == 0 */
71
+ gen_helper_gvec_fmlal_idx_a32);
72
+ return true;
73
+}
74
diff --git a/target/arm/translate.c b/target/arm/translate.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/translate.c
77
+++ b/target/arm/translate.c
78
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
79
}
80
81
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
82
-#define VFP_SREG(insn, bigbit, smallbit) \
83
- ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
84
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
85
if (dc_isar_feature(aa32_simd_r32, s)) { \
86
reg = (((insn) >> (bigbit)) & 0x0f) \
87
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
88
reg = ((insn) >> (bigbit)) & 0x0f; \
89
}} while (0)
90
91
-#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
92
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
93
-#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
94
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
95
-#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
96
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
97
98
static void gen_neon_dup_low16(TCGv_i32 var)
99
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
100
return 0;
101
}
102
103
-/* Advanced SIMD two registers and a scalar extension.
104
- * 31 24 23 22 20 16 12 11 10 9 8 3 0
105
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
106
- * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
107
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
108
- *
109
- */
110
-
111
-static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
112
-{
113
- gen_helper_gvec_3 *fn_gvec = NULL;
114
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
115
- int rd, rn, rm, opr_sz, data;
116
- int off_rn, off_rm;
117
- bool is_long = false, q = extract32(insn, 6, 1);
118
- bool ptr_is_env = false;
119
-
120
- if ((insn & 0xffa00f10) == 0xfe000810) {
121
- /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
122
- int is_s = extract32(insn, 20, 1);
123
- int vm20 = extract32(insn, 0, 3);
124
- int vm3 = extract32(insn, 3, 1);
125
- int m = extract32(insn, 5, 1);
126
- int index;
127
-
128
- if (!dc_isar_feature(aa32_fhm, s)) {
129
- return 1;
130
- }
131
- if (q) {
132
- rm = vm20;
133
- index = m * 2 + vm3;
134
- } else {
135
- rm = vm20 * 2 + m;
136
- index = vm3;
137
- }
138
- is_long = true;
139
- data = (index << 2) | is_s; /* is_2 == 0 */
140
- fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
141
- ptr_is_env = true;
142
- } else {
143
- return 1;
144
- }
145
-
146
- VFP_DREG_D(rd, insn);
147
- if (rd & q) {
148
- return 1;
149
- }
150
- if (q || !is_long) {
151
- VFP_DREG_N(rn, insn);
152
- if (rn & q & !is_long) {
153
- return 1;
154
- }
155
- off_rn = vfp_reg_offset(1, rn);
156
- off_rm = vfp_reg_offset(1, rm);
157
- } else {
158
- rn = VFP_SREG_N(insn);
159
- off_rn = vfp_reg_offset(0, rn);
160
- off_rm = vfp_reg_offset(0, rm);
161
- }
162
- if (s->fp_excp_el) {
163
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
164
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
165
- return 0;
166
- }
167
- if (!s->vfp_enabled) {
168
- return 1;
169
- }
170
-
171
- opr_sz = (1 + q) * 8;
172
- if (fn_gvec_ptr) {
173
- TCGv_ptr ptr;
174
- if (ptr_is_env) {
175
- ptr = cpu_env;
176
- } else {
177
- ptr = get_fpstatus_ptr(1);
178
- }
179
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
180
- opr_sz, opr_sz, data, fn_gvec_ptr);
181
- if (!ptr_is_env) {
182
- tcg_temp_free_ptr(ptr);
183
- }
184
- } else {
185
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
186
- opr_sz, opr_sz, data, fn_gvec);
187
- }
188
- return 0;
189
-}
190
-
191
static int disas_coproc_insn(DisasContext *s, uint32_t insn)
192
{
193
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
194
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
195
}
196
}
197
}
198
- } else if ((insn & 0x0f000a00) == 0x0e000800
199
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
200
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
201
- goto illegal_op;
202
- }
203
- return;
204
}
205
goto illegal_op;
206
}
207
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
208
}
209
break;
210
}
211
- if ((insn & 0xff000a00) == 0xfe000800
212
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
213
- /* The Thumb2 and ARM encodings are identical. */
214
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
215
- goto illegal_op;
216
- }
217
- } else if (((insn >> 24) & 3) == 3) {
218
+ if (((insn >> 24) & 3) == 3) {
219
/* Translate into the equivalent ARM encoding. */
220
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
221
if (disas_neon_data_insn(s, insn)) {
222
--
223
2.20.1
224
225
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon "load single structure to all lanes" insns to
2
decodetree.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-13-peter.maydell@linaro.org
7
---
8
target/arm/neon-ls.decode | 5 +++
9
target/arm/translate-neon.inc.c | 73 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 55 +------------------------
11
3 files changed, 80 insertions(+), 53 deletions(-)
12
13
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-ls.decode
16
+++ b/target/arm/neon-ls.decode
17
@@ -XXX,XX +XXX,XX @@
18
19
VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
20
vd=%vd_dp
21
+
22
+# Neon load single element to all lanes
23
+
24
+VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
25
+ vd=%vd_dp
26
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/translate-neon.inc.c
29
+++ b/target/arm/translate-neon.inc.c
30
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
31
gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
32
return true;
33
}
34
+
35
+static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
36
+{
37
+ /* Neon load single structure to all lanes */
38
+ int reg, stride, vec_size;
39
+ int vd = a->vd;
40
+ int size = a->size;
41
+ int nregs = a->n + 1;
42
+ TCGv_i32 addr, tmp;
43
+
44
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
45
+ return false;
46
+ }
47
+
48
+ /* UNDEF accesses to D16-D31 if they don't exist */
49
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
50
+ return false;
51
+ }
52
+
53
+ if (size == 3) {
54
+ if (nregs != 4 || a->a == 0) {
55
+ return false;
56
+ }
57
+ /* For VLD4 size == 3 a == 1 means 32 bits at 16 byte alignment */
58
+ size = 2;
59
+ }
60
+ if (nregs == 1 && a->a == 1 && size == 0) {
61
+ return false;
62
+ }
63
+ if (nregs == 3 && a->a == 1) {
64
+ return false;
65
+ }
66
+
67
+ if (!vfp_access_check(s)) {
68
+ return true;
69
+ }
70
+
71
+ /*
72
+ * VLD1 to all lanes: T bit indicates how many Dregs to write.
73
+ * VLD2/3/4 to all lanes: T bit indicates register stride.
74
+ */
75
+ stride = a->t ? 2 : 1;
76
+ vec_size = nregs == 1 ? stride * 8 : 8;
77
+
78
+ tmp = tcg_temp_new_i32();
79
+ addr = tcg_temp_new_i32();
80
+ load_reg_var(s, addr, a->rn);
81
+ for (reg = 0; reg < nregs; reg++) {
82
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
83
+ s->be_data | size);
84
+ if ((vd & 1) && vec_size == 16) {
85
+ /*
86
+ * We cannot write 16 bytes at once because the
87
+ * destination is unaligned.
88
+ */
89
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
90
+ 8, 8, tmp);
91
+ tcg_gen_gvec_mov(0, neon_reg_offset(vd + 1, 0),
92
+ neon_reg_offset(vd, 0), 8, 8);
93
+ } else {
94
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
95
+ vec_size, vec_size, tmp);
96
+ }
97
+ tcg_gen_addi_i32(addr, addr, 1 << size);
98
+ vd += stride;
99
+ }
100
+ tcg_temp_free_i32(tmp);
101
+ tcg_temp_free_i32(addr);
102
+
103
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << size) * nregs);
104
+
105
+ return true;
106
+}
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/target/arm/translate.c
110
+++ b/target/arm/translate.c
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
112
int size;
113
int reg;
114
int load;
115
- int vec_size;
116
TCGv_i32 addr;
117
TCGv_i32 tmp;
118
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
120
} else {
121
size = (insn >> 10) & 3;
122
if (size == 3) {
123
- /* Load single element to all lanes. */
124
- int a = (insn >> 4) & 1;
125
- if (!load) {
126
- return 1;
127
- }
128
- size = (insn >> 6) & 3;
129
- nregs = ((insn >> 8) & 3) + 1;
130
-
131
- if (size == 3) {
132
- if (nregs != 4 || a == 0) {
133
- return 1;
134
- }
135
- /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
136
- size = 2;
137
- }
138
- if (nregs == 1 && a == 1 && size == 0) {
139
- return 1;
140
- }
141
- if (nregs == 3 && a == 1) {
142
- return 1;
143
- }
144
- addr = tcg_temp_new_i32();
145
- load_reg_var(s, addr, rn);
146
-
147
- /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
148
- * VLD2/3/4 to all lanes: bit 5 indicates register stride.
149
- */
150
- stride = (insn & (1 << 5)) ? 2 : 1;
151
- vec_size = nregs == 1 ? stride * 8 : 8;
152
-
153
- tmp = tcg_temp_new_i32();
154
- for (reg = 0; reg < nregs; reg++) {
155
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
156
- s->be_data | size);
157
- if ((rd & 1) && vec_size == 16) {
158
- /* We cannot write 16 bytes at once because the
159
- * destination is unaligned.
160
- */
161
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
162
- 8, 8, tmp);
163
- tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
164
- neon_reg_offset(rd, 0), 8, 8);
165
- } else {
166
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
167
- vec_size, vec_size, tmp);
168
- }
169
- tcg_gen_addi_i32(addr, addr, 1 << size);
170
- rd += stride;
171
- }
172
- tcg_temp_free_i32(tmp);
173
- tcg_temp_free_i32(addr);
174
- stride = (1 << size) * nregs;
175
+ /* Load single element to all lanes -- handled by decodetree */
176
+ return 1;
177
} else {
178
/* Single element. */
179
int idx = (insn >> 4) & 0xf;
180
--
181
2.20.1
182
183
diff view generated by jsdifflib
1
Convert the Neon 3-reg-same VMAX and VMIN insns to decodetree.
1
When we're using KVM, the PSCI implementation is provided by the
2
kernel, but QEMU has to tell the guest about it via the device tree.
3
Currently we look at the KVM_CAP_ARM_PSCI_0_2 capability to determine
4
if the kernel is providing at least PSCI 0.2, but if the kernel
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".)
2
14
3
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>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-17-peter.maydell@linaro.org
19
Reviewed-by: Andrew Jones <drjones@redhat.com>
20
Message-id: 20220224134655.1207865-1-peter.maydell@linaro.org
6
---
21
---
7
target/arm/neon-dp.decode | 5 +++++
22
target/arm/kvm-consts.h | 1 +
8
target/arm/translate-neon.inc.c | 14 ++++++++++++++
23
hw/arm/boot.c | 5 ++---
9
target/arm/translate.c | 21 ++-------------------
24
target/arm/kvm64.c | 12 ++++++++++++
10
3 files changed, 21 insertions(+), 19 deletions(-)
25
3 files changed, 15 insertions(+), 3 deletions(-)
11
26
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
27
diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h
13
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-dp.decode
29
--- a/target/arm/kvm-consts.h
15
+++ b/target/arm/neon-dp.decode
30
+++ b/target/arm/kvm-consts.h
16
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
31
@@ -XXX,XX +XXX,XX @@ MISMATCH_CHECK(QEMU_PSCI_1_0_FN_PSCI_FEATURES, PSCI_1_0_FN_PSCI_FEATURES);
17
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
32
18
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
33
#define QEMU_PSCI_VERSION_0_1 0x00001
19
34
#define QEMU_PSCI_VERSION_0_2 0x00002
20
+VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
35
+#define QEMU_PSCI_VERSION_1_0 0x10000
21
+VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
36
#define QEMU_PSCI_VERSION_1_1 0x10001
22
+VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
37
23
+VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
38
MISMATCH_CHECK(QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED, PSCI_0_2_TOS_MP);
24
+
39
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
25
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
26
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
41
--- a/hw/arm/boot.c
30
+++ b/target/arm/translate-neon.inc.c
42
+++ b/hw/arm/boot.c
31
@@ -XXX,XX +XXX,XX @@ DO_3SAME(VEOR, tcg_gen_gvec_xor)
43
@@ -XXX,XX +XXX,XX @@ static void fdt_add_psci_node(void *fdt)
32
DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
44
}
33
DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
45
34
DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
46
qemu_fdt_add_subnode(fdt, "/psci");
35
+
47
- if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2 ||
36
+#define DO_3SAME_NO_SZ_3(INSN, FUNC) \
48
- armcpu->psci_version == QEMU_PSCI_VERSION_1_1) {
37
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
49
- if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2) {
38
+ { \
50
+ if (armcpu->psci_version >= QEMU_PSCI_VERSION_0_2) {
39
+ if (a->size == 3) { \
51
+ if (armcpu->psci_version < QEMU_PSCI_VERSION_1_0) {
40
+ return false; \
52
const char comp[] = "arm,psci-0.2\0arm,psci";
41
+ } \
53
qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
42
+ return do_3same(s, a, FUNC); \
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;
43
+ }
80
+ }
44
+
81
+
45
+DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
82
/*
46
+DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
83
* When KVM is in use, PSCI is emulated in-kernel and not by qemu.
47
+DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
84
* Currently KVM has its own idea about MPIDR assignment, so we
48
+DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/translate.c
52
+++ b/target/arm/translate.c
53
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
54
rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
55
return 0;
56
57
- case NEON_3R_VMAX:
58
- if (u) {
59
- tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
60
- vec_size, vec_size);
61
- } else {
62
- tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
63
- vec_size, vec_size);
64
- }
65
- return 0;
66
- case NEON_3R_VMIN:
67
- if (u) {
68
- tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
69
- vec_size, vec_size);
70
- } else {
71
- tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
72
- vec_size, vec_size);
73
- }
74
- return 0;
75
-
76
case NEON_3R_VSHL:
77
/* Note the operation is vshl vd,vm,vn */
78
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
79
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
80
81
case NEON_3R_VADD_VSUB:
82
case NEON_3R_LOGIC:
83
+ case NEON_3R_VMAX:
84
+ case NEON_3R_VMIN:
85
/* Already handled by decodetree */
86
return 1;
87
}
88
--
85
--
89
2.20.1
86
2.25.1
90
91
diff view generated by jsdifflib
1
Convert the Neon 3-reg-same VADD and VSUB insns to decodetree.
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
Note that we don't need the neon_3r_sizes[op] check here because all
7
Fix the places where we got this wrong, by taking the iothread lock
4
size values are OK for VADD and VSUB; we'll add this when we convert
8
while executing updateUIInfo, and moving the call in cocoa_switch()
5
the first insn that has size restrictions.
9
inside the dispatch_async block.
6
10
7
For this we need one of the GVecGen*Fn typedefs currently in
11
Some of the Cocoa UI methods which call updateUIInfo are invoked as
8
translate-a64.h; move them all to translate.h as a block so they
12
part of the initial application startup, while we're still doing the
9
are visible to the 32-bit decoder.
13
little cross-thread dance described in the comment just above
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.
10
23
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
13
Message-id: 20200430181003.21682-15-peter.maydell@linaro.org
26
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
27
Message-id: 20220224101330.967429-2-peter.maydell@linaro.org
14
---
28
---
15
target/arm/translate-a64.h | 9 --------
29
ui/cocoa.m | 25 ++++++++++++++++++++++---
16
target/arm/translate.h | 9 ++++++++
30
1 file changed, 22 insertions(+), 3 deletions(-)
17
target/arm/neon-dp.decode | 17 +++++++++++++++
18
target/arm/translate-neon.inc.c | 38 +++++++++++++++++++++++++++++++++
19
target/arm/translate.c | 14 ++++--------
20
5 files changed, 68 insertions(+), 19 deletions(-)
21
31
22
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
32
diff --git a/ui/cocoa.m b/ui/cocoa.m
23
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/translate-a64.h
34
--- a/ui/cocoa.m
25
+++ b/target/arm/translate-a64.h
35
+++ b/ui/cocoa.m
26
@@ -XXX,XX +XXX,XX @@ static inline int vec_full_reg_size(DisasContext *s)
36
@@ -XXX,XX +XXX,XX @@ QemuCocoaView *cocoaView;
27
37
}
28
bool disas_sve(DisasContext *, uint32_t);
29
30
-/* Note that the gvec expanders operate on offsets + sizes. */
31
-typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
32
-typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
33
- uint32_t, uint32_t);
34
-typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
35
- uint32_t, uint32_t, uint32_t);
36
-typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
37
- uint32_t, uint32_t, uint32_t);
38
-
39
#endif /* TARGET_ARM_TRANSLATE_A64_H */
40
diff --git a/target/arm/translate.h b/target/arm/translate.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate.h
43
+++ b/target/arm/translate.h
44
@@ -XXX,XX +XXX,XX @@ void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
45
#define dc_isar_feature(name, ctx) \
46
({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
47
48
+/* Note that the gvec expanders operate on offsets + sizes. */
49
+typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
50
+typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
51
+ uint32_t, uint32_t);
52
+typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
53
+ uint32_t, uint32_t, uint32_t);
54
+typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
55
+ uint32_t, uint32_t, uint32_t);
56
+
57
#endif /* TARGET_ARM_TRANSLATE_H */
58
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/neon-dp.decode
61
+++ b/target/arm/neon-dp.decode
62
@@ -XXX,XX +XXX,XX @@
63
#
64
# This file is processed by scripts/decodetree.py
65
#
66
+# VFP/Neon register fields; same as vfp.decode
67
+%vm_dp 5:1 0:4
68
+%vn_dp 7:1 16:4
69
+%vd_dp 22:1 12:4
70
71
# Encodings for Neon data processing instructions where the T32 encoding
72
# is a simple transformation of the A32 encoding.
73
@@ -XXX,XX +XXX,XX @@
74
# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
75
# This file works on the A32 encoding only; calling code for T32 has to
76
# transform the insn into the A32 version first.
77
+
78
+######################################################################
79
+# 3-reg-same grouping:
80
+# 1111 001 U 0 D sz:2 Vn:4 Vd:4 opc:4 N Q M op Vm:4
81
+######################################################################
82
+
83
+&3same vm vn vd q size
84
+
85
+@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
86
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
87
+
88
+VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
89
+VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
90
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/translate-neon.inc.c
93
+++ b/target/arm/translate-neon.inc.c
94
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
95
96
return true;
97
}
38
}
98
+
39
99
+static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
40
-- (void) updateUIInfo
41
+- (void) updateUIInfoLocked
42
{
43
+ /* Must be called with the iothread lock, i.e. via updateUIInfo */
44
NSSize frameSize;
45
QemuUIInfo info;
46
47
@@ -XXX,XX +XXX,XX @@ QemuCocoaView *cocoaView;
48
dpy_set_ui_info(dcl.con, &info, TRUE);
49
}
50
51
+- (void) updateUIInfo
100
+{
52
+{
101
+ int vec_size = a->q ? 16 : 8;
53
+ if (!allow_events) {
102
+ int rd_ofs = neon_reg_offset(a->vd, 0);
54
+ /*
103
+ int rn_ofs = neon_reg_offset(a->vn, 0);
55
+ * Don't try to tell QEMU about UI information in the application
104
+ int rm_ofs = neon_reg_offset(a->vm, 0);
56
+ * startup phase -- we haven't yet registered dcl with the QEMU UI
105
+
57
+ * layer, and also trying to take the iothread lock would deadlock.
106
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
58
+ * When cocoa_display_init() does register the dcl, the UI layer
107
+ return false;
59
+ * will call cocoa_switch(), which will call updateUIInfo, so
60
+ * we don't lose any information here.
61
+ */
62
+ return;
108
+ }
63
+ }
109
+
64
+
110
+ /* UNDEF accesses to D16-D31 if they don't exist. */
65
+ with_iothread_lock(^{
111
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
66
+ [self updateUIInfoLocked];
112
+ ((a->vd | a->vn | a->vm) & 0x10)) {
67
+ });
113
+ return false;
114
+ }
115
+
116
+ if ((a->vn | a->vm | a->vd) & a->q) {
117
+ return false;
118
+ }
119
+
120
+ if (!vfp_access_check(s)) {
121
+ return true;
122
+ }
123
+
124
+ fn(a->size, rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
125
+ return true;
126
+}
68
+}
127
+
69
+
128
+#define DO_3SAME(INSN, FUNC) \
70
- (void)viewDidMoveToWindow
129
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
71
{
130
+ { \
72
[self updateUIInfo];
131
+ return do_3same(s, a, FUNC); \
73
@@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl,
132
+ }
74
133
+
75
COCOA_DEBUG("qemu_cocoa: cocoa_switch\n");
134
+DO_3SAME(VADD, tcg_gen_gvec_add)
76
135
+DO_3SAME(VSUB, tcg_gen_gvec_sub)
77
- [cocoaView updateUIInfo];
136
diff --git a/target/arm/translate.c b/target/arm/translate.c
137
index XXXXXXX..XXXXXXX 100644
138
--- a/target/arm/translate.c
139
+++ b/target/arm/translate.c
140
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
141
}
142
return 0;
143
144
- case NEON_3R_VADD_VSUB:
145
- if (u) {
146
- tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
147
- vec_size, vec_size);
148
- } else {
149
- tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
150
- vec_size, vec_size);
151
- }
152
- return 0;
153
-
78
-
154
case NEON_3R_VQADD:
79
// The DisplaySurface will be freed as soon as this callback returns.
155
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
80
// We take a reference to the underlying pixman image here so it does
156
rn_ofs, rm_ofs, vec_size, vec_size,
81
// not disappear from under our feet; the switchSurface method will
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
82
@@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl,
158
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
83
pixman_image_ref(image);
159
u ? &ushl_op[size] : &sshl_op[size]);
84
160
return 0;
85
dispatch_async(dispatch_get_main_queue(), ^{
161
+
86
+ [cocoaView updateUIInfo];
162
+ case NEON_3R_VADD_VSUB:
87
[cocoaView switchSurface:image];
163
+ /* Already handled by decodetree */
88
});
164
+ return 1;
89
[pool release];
165
}
166
167
if (size == 3) {
168
--
90
--
169
2.20.1
91
2.25.1
170
171
diff view generated by jsdifflib
1
Convert the Neon "load/store single structure to one lane" insns to
1
In commit 6e657e64cdc478 in 2013 we added some autorelease pools to
2
decodetree.
2
deal with complaints from macOS when we made calls into Cocoa from
3
threads that didn't have automatically created autorelease pools.
4
Later on, macOS got stricter about forbidding cross-thread Cocoa
5
calls, and in commit 5588840ff77800e839d8 we restructured the code to
6
avoid them. This left the autorelease pool creation in several
7
functions without any purpose; delete it.
3
8
4
As this is the last set of insns in the neon load/store group,
9
We still need the pool in cocoa_refresh() for the clipboard related
5
we can remove the whole disas_neon_ls_insn() function.
10
code which is called directly there.
6
11
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>
9
Message-id: 20200430181003.21682-14-peter.maydell@linaro.org
14
Tested-by: Akihiko Odaki <akihiko.odaki@gmail.com>
15
Message-id: 20220224101330.967429-3-peter.maydell@linaro.org
10
---
16
---
11
target/arm/neon-ls.decode | 11 +++
17
ui/cocoa.m | 6 ------
12
target/arm/translate-neon.inc.c | 89 +++++++++++++++++++
18
1 file changed, 6 deletions(-)
13
target/arm/translate.c | 147 --------------------------------
14
3 files changed, 100 insertions(+), 147 deletions(-)
15
19
16
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
20
diff --git a/ui/cocoa.m b/ui/cocoa.m
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/neon-ls.decode
22
--- a/ui/cocoa.m
19
+++ b/target/arm/neon-ls.decode
23
+++ b/ui/cocoa.m
20
@@ -XXX,XX +XXX,XX @@ VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
24
@@ -XXX,XX +XXX,XX @@ int main (int argc, char **argv) {
21
25
static void cocoa_update(DisplayChangeListener *dcl,
22
VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
26
int x, int y, int w, int h)
23
vd=%vd_dp
27
{
24
+
28
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
25
+# Neon load/store single structure to one lane
29
-
26
+%imm1_5_p1 5:1 !function=plus1
30
COCOA_DEBUG("qemu_cocoa: cocoa_update\n");
27
+%imm1_6_p1 6:1 !function=plus1
31
28
+
32
dispatch_async(dispatch_get_main_queue(), ^{
29
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 00 n:2 reg_idx:3 align:1 rm:4 \
33
@@ -XXX,XX +XXX,XX @@ static void cocoa_update(DisplayChangeListener *dcl,
30
+ vd=%vd_dp size=0 stride=1
34
}
31
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 01 n:2 reg_idx:2 align:2 rm:4 \
35
[cocoaView setNeedsDisplayInRect:rect];
32
+ vd=%vd_dp size=1 stride=%imm1_5_p1
36
});
33
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 10 n:2 reg_idx:1 align:3 rm:4 \
37
-
34
+ vd=%vd_dp size=2 stride=%imm1_6_p1
38
- [pool release];
35
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate-neon.inc.c
38
+++ b/target/arm/translate-neon.inc.c
39
@@ -XXX,XX +XXX,XX @@
40
* It might be possible to convert it to a standalone .c file eventually.
41
*/
42
43
+static inline int plus1(DisasContext *s, int x)
44
+{
45
+ return x + 1;
46
+}
47
+
48
/* Include the generated Neon decoder */
49
#include "decode-neon-dp.inc.c"
50
#include "decode-neon-ls.inc.c"
51
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
52
53
return true;
54
}
39
}
55
+
40
56
+static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
41
static void cocoa_switch(DisplayChangeListener *dcl,
57
+{
42
DisplaySurface *surface)
58
+ /* Neon load/store single structure to one lane */
43
{
59
+ int reg;
44
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
60
+ int nregs = a->n + 1;
45
pixman_image_t *image = surface->image;
61
+ int vd = a->vd;
46
62
+ TCGv_i32 addr, tmp;
47
COCOA_DEBUG("qemu_cocoa: cocoa_switch\n");
63
+
48
@@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl,
64
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
49
[cocoaView updateUIInfo];
65
+ return false;
50
[cocoaView switchSurface:image];
66
+ }
51
});
67
+
52
- [pool release];
68
+ /* UNDEF accesses to D16-D31 if they don't exist */
69
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
70
+ return false;
71
+ }
72
+
73
+ /* Catch the UNDEF cases. This is unavoidably a bit messy. */
74
+ switch (nregs) {
75
+ case 1:
76
+ if (((a->align & (1 << a->size)) != 0) ||
77
+ (a->size == 2 && ((a->align & 3) == 1 || (a->align & 3) == 2))) {
78
+ return false;
79
+ }
80
+ break;
81
+ case 3:
82
+ if ((a->align & 1) != 0) {
83
+ return false;
84
+ }
85
+ /* fall through */
86
+ case 2:
87
+ if (a->size == 2 && (a->align & 2) != 0) {
88
+ return false;
89
+ }
90
+ break;
91
+ case 4:
92
+ if ((a->size == 2) && ((a->align & 3) == 3)) {
93
+ return false;
94
+ }
95
+ break;
96
+ default:
97
+ abort();
98
+ }
99
+ if ((vd + a->stride * (nregs - 1)) > 31) {
100
+ /*
101
+ * Attempts to write off the end of the register file are
102
+ * UNPREDICTABLE; we choose to UNDEF because otherwise we would
103
+ * access off the end of the array that holds the register data.
104
+ */
105
+ return false;
106
+ }
107
+
108
+ if (!vfp_access_check(s)) {
109
+ return true;
110
+ }
111
+
112
+ tmp = tcg_temp_new_i32();
113
+ addr = tcg_temp_new_i32();
114
+ load_reg_var(s, addr, a->rn);
115
+ /*
116
+ * TODO: if we implemented alignment exceptions, we should check
117
+ * addr against the alignment encoded in a->align here.
118
+ */
119
+ for (reg = 0; reg < nregs; reg++) {
120
+ if (a->l) {
121
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
122
+ s->be_data | a->size);
123
+ neon_store_element(vd, a->reg_idx, a->size, tmp);
124
+ } else { /* Store */
125
+ neon_load_element(tmp, vd, a->reg_idx, a->size);
126
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
127
+ s->be_data | a->size);
128
+ }
129
+ vd += a->stride;
130
+ tcg_gen_addi_i32(addr, addr, 1 << a->size);
131
+ }
132
+ tcg_temp_free_i32(addr);
133
+ tcg_temp_free_i32(tmp);
134
+
135
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << a->size) * nregs);
136
+
137
+ return true;
138
+}
139
diff --git a/target/arm/translate.c b/target/arm/translate.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/target/arm/translate.c
142
+++ b/target/arm/translate.c
143
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
144
tcg_temp_free_i32(rd);
145
}
53
}
146
54
147
-
55
static void cocoa_refresh(DisplayChangeListener *dcl)
148
-/* Translate a NEON load/store element instruction. Return nonzero if the
149
- instruction is invalid. */
150
-static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
151
-{
152
- int rd, rn, rm;
153
- int nregs;
154
- int stride;
155
- int size;
156
- int reg;
157
- int load;
158
- TCGv_i32 addr;
159
- TCGv_i32 tmp;
160
-
161
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
162
- return 1;
163
- }
164
-
165
- /* FIXME: this access check should not take precedence over UNDEF
166
- * for invalid encodings; we will generate incorrect syndrome information
167
- * for attempts to execute invalid vfp/neon encodings with FP disabled.
168
- */
169
- if (s->fp_excp_el) {
170
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
171
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
172
- return 0;
173
- }
174
-
175
- if (!s->vfp_enabled)
176
- return 1;
177
- VFP_DREG_D(rd, insn);
178
- rn = (insn >> 16) & 0xf;
179
- rm = insn & 0xf;
180
- load = (insn & (1 << 21)) != 0;
181
- if ((insn & (1 << 23)) == 0) {
182
- /* Load store all elements -- handled already by decodetree */
183
- return 1;
184
- } else {
185
- size = (insn >> 10) & 3;
186
- if (size == 3) {
187
- /* Load single element to all lanes -- handled by decodetree */
188
- return 1;
189
- } else {
190
- /* Single element. */
191
- int idx = (insn >> 4) & 0xf;
192
- int reg_idx;
193
- switch (size) {
194
- case 0:
195
- reg_idx = (insn >> 5) & 7;
196
- stride = 1;
197
- break;
198
- case 1:
199
- reg_idx = (insn >> 6) & 3;
200
- stride = (insn & (1 << 5)) ? 2 : 1;
201
- break;
202
- case 2:
203
- reg_idx = (insn >> 7) & 1;
204
- stride = (insn & (1 << 6)) ? 2 : 1;
205
- break;
206
- default:
207
- abort();
208
- }
209
- nregs = ((insn >> 8) & 3) + 1;
210
- /* Catch the UNDEF cases. This is unavoidably a bit messy. */
211
- switch (nregs) {
212
- case 1:
213
- if (((idx & (1 << size)) != 0) ||
214
- (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
215
- return 1;
216
- }
217
- break;
218
- case 3:
219
- if ((idx & 1) != 0) {
220
- return 1;
221
- }
222
- /* fall through */
223
- case 2:
224
- if (size == 2 && (idx & 2) != 0) {
225
- return 1;
226
- }
227
- break;
228
- case 4:
229
- if ((size == 2) && ((idx & 3) == 3)) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- abort();
235
- }
236
- if ((rd + stride * (nregs - 1)) > 31) {
237
- /* Attempts to write off the end of the register file
238
- * are UNPREDICTABLE; we choose to UNDEF because otherwise
239
- * the neon_load_reg() would write off the end of the array.
240
- */
241
- return 1;
242
- }
243
- tmp = tcg_temp_new_i32();
244
- addr = tcg_temp_new_i32();
245
- load_reg_var(s, addr, rn);
246
- for (reg = 0; reg < nregs; reg++) {
247
- if (load) {
248
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
249
- s->be_data | size);
250
- neon_store_element(rd, reg_idx, size, tmp);
251
- } else { /* Store */
252
- neon_load_element(tmp, rd, reg_idx, size);
253
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
254
- s->be_data | size);
255
- }
256
- rd += stride;
257
- tcg_gen_addi_i32(addr, addr, 1 << size);
258
- }
259
- tcg_temp_free_i32(addr);
260
- tcg_temp_free_i32(tmp);
261
- stride = nregs * (1 << size);
262
- }
263
- }
264
- if (rm != 15) {
265
- TCGv_i32 base;
266
-
267
- base = load_reg(s, rn);
268
- if (rm == 13) {
269
- tcg_gen_addi_i32(base, base, stride);
270
- } else {
271
- TCGv_i32 index;
272
- index = load_reg(s, rm);
273
- tcg_gen_add_i32(base, base, index);
274
- tcg_temp_free_i32(index);
275
- }
276
- store_reg(s, rn, base);
277
- }
278
- return 0;
279
-}
280
-
281
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
282
{
283
switch (size) {
284
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
285
}
286
return;
287
}
288
- if ((insn & 0x0f100000) == 0x04000000) {
289
- /* NEON load/store. */
290
- if (disas_neon_ls_insn(s, insn)) {
291
- goto illegal_op;
292
- }
293
- return;
294
- }
295
if ((insn & 0x0e000f00) == 0x0c000100) {
296
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
297
/* iWMMXt register transfer. */
298
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
299
}
300
break;
301
case 12:
302
- if ((insn & 0x01100000) == 0x01000000) {
303
- if (disas_neon_ls_insn(s, insn)) {
304
- goto illegal_op;
305
- }
306
- break;
307
- }
308
goto illegal_op;
309
default:
310
illegal_op:
311
--
56
--
312
2.20.1
57
2.25.1
313
314
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon logic ops in the 3-reg-same grouping to decodetree.
2
Note that for the logic ops the 'size' field forms part of their
3
decode and the actual operations are always bitwise.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200430181003.21682-16-peter.maydell@linaro.org
8
---
9
target/arm/neon-dp.decode | 12 +++++++++++
10
target/arm/translate-neon.inc.c | 19 +++++++++++++++++
11
target/arm/translate.c | 38 +--------------------------------
12
3 files changed, 32 insertions(+), 37 deletions(-)
13
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/neon-dp.decode
17
+++ b/target/arm/neon-dp.decode
18
@@ -XXX,XX +XXX,XX @@
19
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
20
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
21
22
+@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
23
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
24
+
25
+VAND_3s 1111 001 0 0 . 00 .... .... 0001 ... 1 .... @3same_logic
26
+VBIC_3s 1111 001 0 0 . 01 .... .... 0001 ... 1 .... @3same_logic
27
+VORR_3s 1111 001 0 0 . 10 .... .... 0001 ... 1 .... @3same_logic
28
+VORN_3s 1111 001 0 0 . 11 .... .... 0001 ... 1 .... @3same_logic
29
+VEOR_3s 1111 001 1 0 . 00 .... .... 0001 ... 1 .... @3same_logic
30
+VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
31
+VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
32
+VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
33
+
34
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
35
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-neon.inc.c
39
+++ b/target/arm/translate-neon.inc.c
40
@@ -XXX,XX +XXX,XX @@ static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
41
42
DO_3SAME(VADD, tcg_gen_gvec_add)
43
DO_3SAME(VSUB, tcg_gen_gvec_sub)
44
+DO_3SAME(VAND, tcg_gen_gvec_and)
45
+DO_3SAME(VBIC, tcg_gen_gvec_andc)
46
+DO_3SAME(VORR, tcg_gen_gvec_or)
47
+DO_3SAME(VORN, tcg_gen_gvec_orc)
48
+DO_3SAME(VEOR, tcg_gen_gvec_xor)
49
+
50
+/* These insns are all gvec_bitsel but with the inputs in various orders. */
51
+#define DO_3SAME_BITSEL(INSN, O1, O2, O3) \
52
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
53
+ uint32_t rn_ofs, uint32_t rm_ofs, \
54
+ uint32_t oprsz, uint32_t maxsz) \
55
+ { \
56
+ tcg_gen_gvec_bitsel(vece, rd_ofs, O1, O2, O3, oprsz, maxsz); \
57
+ } \
58
+ DO_3SAME(INSN, gen_##INSN##_3s)
59
+
60
+DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
61
+DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
62
+DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
63
diff --git a/target/arm/translate.c b/target/arm/translate.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate.c
66
+++ b/target/arm/translate.c
67
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
68
}
69
return 1;
70
71
- case NEON_3R_LOGIC: /* Logic ops. */
72
- switch ((u << 2) | size) {
73
- case 0: /* VAND */
74
- tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
75
- vec_size, vec_size);
76
- break;
77
- case 1: /* VBIC */
78
- tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
79
- vec_size, vec_size);
80
- break;
81
- case 2: /* VORR */
82
- tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
83
- vec_size, vec_size);
84
- break;
85
- case 3: /* VORN */
86
- tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
87
- vec_size, vec_size);
88
- break;
89
- case 4: /* VEOR */
90
- tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
91
- vec_size, vec_size);
92
- break;
93
- case 5: /* VBSL */
94
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
95
- vec_size, vec_size);
96
- break;
97
- case 6: /* VBIT */
98
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
99
- vec_size, vec_size);
100
- break;
101
- case 7: /* VBIF */
102
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
103
- vec_size, vec_size);
104
- break;
105
- }
106
- return 0;
107
-
108
case NEON_3R_VQADD:
109
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
110
rn_ofs, rm_ofs, vec_size, vec_size,
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
112
return 0;
113
114
case NEON_3R_VADD_VSUB:
115
+ case NEON_3R_LOGIC:
116
/* Already handled by decodetree */
117
return 1;
118
}
119
--
120
2.20.1
121
122
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon comparison ops in the 3-reg-same grouping
2
to decodetree.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-18-peter.maydell@linaro.org
7
---
8
target/arm/neon-dp.decode | 8 ++++++++
9
target/arm/translate-neon.inc.c | 22 ++++++++++++++++++++++
10
target/arm/translate.c | 23 +++--------------------
11
3 files changed, 33 insertions(+), 20 deletions(-)
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
18
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
19
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
20
21
+VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
22
+VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
23
+VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
24
+VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
25
+
26
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
27
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
28
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
29
@@ -XXX,XX +XXX,XX @@ VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
30
31
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
32
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
33
+
34
+VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
35
+VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-neon.inc.c
39
+++ b/target/arm/translate-neon.inc.c
40
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
41
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
42
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
43
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
44
+
45
+#define DO_3SAME_CMP(INSN, COND) \
46
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
47
+ uint32_t rn_ofs, uint32_t rm_ofs, \
48
+ uint32_t oprsz, uint32_t maxsz) \
49
+ { \
50
+ tcg_gen_gvec_cmp(COND, vece, rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz); \
51
+ } \
52
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
53
+
54
+DO_3SAME_CMP(VCGT_S, TCG_COND_GT)
55
+DO_3SAME_CMP(VCGT_U, TCG_COND_GTU)
56
+DO_3SAME_CMP(VCGE_S, TCG_COND_GE)
57
+DO_3SAME_CMP(VCGE_U, TCG_COND_GEU)
58
+DO_3SAME_CMP(VCEQ, TCG_COND_EQ)
59
+
60
+static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
61
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
62
+{
63
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
64
+}
65
+DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
71
u ? &mls_op[size] : &mla_op[size]);
72
return 0;
73
74
- case NEON_3R_VTST_VCEQ:
75
- if (u) { /* VCEQ */
76
- tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
77
- vec_size, vec_size);
78
- } else { /* VTST */
79
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
80
- vec_size, vec_size, &cmtst_op[size]);
81
- }
82
- return 0;
83
-
84
- case NEON_3R_VCGT:
85
- tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
86
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
87
- return 0;
88
-
89
- case NEON_3R_VCGE:
90
- tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
91
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
92
- return 0;
93
-
94
case NEON_3R_VSHL:
95
/* Note the operation is vshl vd,vm,vn */
96
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
97
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
98
case NEON_3R_LOGIC:
99
case NEON_3R_VMAX:
100
case NEON_3R_VMIN:
101
+ case NEON_3R_VTST_VCEQ:
102
+ case NEON_3R_VCGT:
103
+ case NEON_3R_VCGE:
104
/* Already handled by decodetree */
105
return 1;
106
}
107
--
108
2.20.1
109
110
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon VQADD/VQSUB insns in the 3-reg-same grouping
2
to decodetree.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-19-peter.maydell@linaro.org
7
---
8
target/arm/neon-dp.decode | 6 ++++++
9
target/arm/translate-neon.inc.c | 15 +++++++++++++++
10
target/arm/translate.c | 14 ++------------
11
3 files changed, 23 insertions(+), 12 deletions(-)
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@
18
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
19
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
21
+VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
22
+VQADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 1 .... @3same
23
+
24
@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
25
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
26
27
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
28
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
29
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
30
31
+VQSUB_S_3s 1111 001 0 0 . .. .... .... 0010 . . . 1 .... @3same
32
+VQSUB_U_3s 1111 001 1 0 . .. .... .... 0010 . . . 1 .... @3same
33
+
34
VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
35
VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
36
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-neon.inc.c
40
+++ b/target/arm/translate-neon.inc.c
41
@@ -XXX,XX +XXX,XX @@ static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
42
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
43
}
44
DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
45
+
46
+#define DO_3SAME_GVEC4(INSN, OPARRAY) \
47
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
48
+ uint32_t rn_ofs, uint32_t rm_ofs, \
49
+ uint32_t oprsz, uint32_t maxsz) \
50
+ { \
51
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc), \
52
+ rn_ofs, rm_ofs, oprsz, maxsz, &OPARRAY[vece]); \
53
+ } \
54
+ DO_3SAME(INSN, gen_##INSN##_3s)
55
+
56
+DO_3SAME_GVEC4(VQADD_S, sqadd_op)
57
+DO_3SAME_GVEC4(VQADD_U, uqadd_op)
58
+DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
59
+DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
60
diff --git a/target/arm/translate.c b/target/arm/translate.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/translate.c
63
+++ b/target/arm/translate.c
64
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
65
}
66
return 1;
67
68
- case NEON_3R_VQADD:
69
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
70
- rn_ofs, rm_ofs, vec_size, vec_size,
71
- (u ? uqadd_op : sqadd_op) + size);
72
- return 0;
73
-
74
- case NEON_3R_VQSUB:
75
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
76
- rn_ofs, rm_ofs, vec_size, vec_size,
77
- (u ? uqsub_op : sqsub_op) + size);
78
- return 0;
79
-
80
case NEON_3R_VMUL: /* VMUL */
81
if (u) {
82
/* Polynomial case allows only P8. */
83
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
84
case NEON_3R_VTST_VCEQ:
85
case NEON_3R_VCGT:
86
case NEON_3R_VCGE:
87
+ case NEON_3R_VQADD:
88
+ case NEON_3R_VQSUB:
89
/* Already handled by decodetree */
90
return 1;
91
}
92
--
93
2.20.1
94
95
diff view generated by jsdifflib