1
A largish pull request: the big things are Richard's PAuth work
1
The following changes since commit 5a67d7735d4162630769ef495cf813244fc850df:
2
and Aaron's PMU emulation improvements.
3
2
4
thanks
3
Merge remote-tracking branch 'remotes/berrange-gitlab/tags/tls-deps-pull-request' into staging (2021-07-02 08:22:39 +0100)
5
-- PMM
6
7
8
The following changes since commit 681d61362d3f766a00806b89d6581869041f73cb:
9
10
Merge remote-tracking branch 'remotes/jnsnow/tags/bitmaps-pull-request' into staging (2019-01-17 12:48:42 +0000)
11
4
12
are available in the Git repository at:
5
are available in the Git repository at:
13
6
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190118
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210702
15
8
16
for you to fetch changes up to 2a0ed2804e2c77a1c4e255f05ab739618e05c85d:
9
for you to fetch changes up to 04ea4d3cfd0a21b248ece8eb7a9436a3d9898dd8:
17
10
18
tests/libqtest: Introduce qtest_init_with_serial() (2019-01-18 14:17:38 +0000)
11
target/arm: Implement MVE shifts by register (2021-07-02 11:48:38 +0100)
19
12
20
----------------------------------------------------------------
13
----------------------------------------------------------------
21
target-arm queue:
14
target-arm queue:
22
* hw/char/stm32f2xx_usart: Do not update data register when device is disabled
15
* more MVE instructions
23
* hw/arm/virt-acpi-build: Set COHACC override flag in IORT SMMUv3 node
16
* hw/gpio/gpio_pwr: use shutdown function for reboot
24
* target/arm: Allow Aarch32 exception return to switch from Mon->Hyp
17
* target/arm: Check NaN mode before silencing NaN
25
* ftgmac100: implement the new MDIO interface on Aspeed SoC
18
* tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
26
* implement the ARMv8.3-PAuth extension
19
* hw/arm: Add basic power management to raspi.
27
* improve emulation of the ARM PMU
20
* docs/system/arm: Add quanta-gbs-bmc, quanta-q7l1-bmc
28
21
29
----------------------------------------------------------------
22
----------------------------------------------------------------
30
Aaron Lindsay (13):
23
Joe Komlodi (1):
31
migration: Add post_save function to VMStateDescription
24
target/arm: Check NaN mode before silencing NaN
32
target/arm: Reorganize PMCCNTR accesses
33
target/arm: Swap PMU values before/after migrations
34
target/arm: Filter cycle counter based on PMCCFILTR_EL0
35
target/arm: Allow AArch32 access for PMCCFILTR
36
target/arm: Implement PMOVSSET
37
target/arm: Define FIELDs for ID_DFR0
38
target/arm: Make PMCEID[01]_EL0 64 bit registers, add PMCEID[23]
39
target/arm: Add array for supported PMU events, generate PMCEID[01]_EL0
40
target/arm: Finish implementation of PM[X]EVCNTR and PM[X]EVTYPER
41
target/arm: PMU: Add instruction and cycle events
42
target/arm: PMU: Set PMCR.N to 4
43
target/arm: Implement PMSWINC
44
25
45
Alexander Graf (1):
26
Maxim Uvarov (1):
46
target/arm: Allow Aarch32 exception return to switch from Mon->Hyp
27
hw/gpio/gpio_pwr: use shutdown function for reboot
47
28
48
Cédric Le Goater (1):
29
Nolan Leake (1):
49
ftgmac100: implement the new MDIO interface on Aspeed SoC
30
hw/arm: Add basic power management to raspi.
50
31
51
Eric Auger (1):
32
Patrick Venture (2):
52
hw/arm/virt-acpi-build: Set COHACC override flag in IORT SMMUv3 node
33
docs/system/arm: Add quanta-q7l1-bmc reference
34
docs/system/arm: Add quanta-gbs-bmc reference
53
35
54
Julia Suvorova (1):
36
Peter Maydell (18):
55
tests/libqtest: Introduce qtest_init_with_serial()
37
target/arm: Fix MVE widening/narrowing VLDR/VSTR offset calculation
38
target/arm: Fix bugs in MVE VRMLALDAVH, VRMLSLDAVH
39
target/arm: Make asimd_imm_const() public
40
target/arm: Use asimd_imm_const for A64 decode
41
target/arm: Use dup_const() instead of bitfield_replicate()
42
target/arm: Implement MVE logical immediate insns
43
target/arm: Implement MVE vector shift left by immediate insns
44
target/arm: Implement MVE vector shift right by immediate insns
45
target/arm: Implement MVE VSHLL
46
target/arm: Implement MVE VSRI, VSLI
47
target/arm: Implement MVE VSHRN, VRSHRN
48
target/arm: Implement MVE saturating narrowing shifts
49
target/arm: Implement MVE VSHLC
50
target/arm: Implement MVE VADDLV
51
target/arm: Implement MVE long shifts by immediate
52
target/arm: Implement MVE long shifts by register
53
target/arm: Implement MVE shifts by immediate
54
target/arm: Implement MVE shifts by register
56
55
57
Philippe Mathieu-Daudé (1):
56
Philippe Mathieu-Daudé (1):
58
hw/char/stm32f2xx_usart: Do not update data register when device is disabled
57
tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
59
58
60
Richard Henderson (31):
59
docs/system/arm/aspeed.rst | 1 +
61
target/arm: Add state for the ARMv8.3-PAuth extension
60
docs/system/arm/nuvoton.rst | 5 +-
62
target/arm: Add SCTLR bits through ARMv8.5
61
include/hw/arm/bcm2835_peripherals.h | 3 +-
63
target/arm: Add PAuth active bit to tbflags
62
include/hw/misc/bcm2835_powermgt.h | 29 ++
64
target/arm: Introduce raise_exception_ra
63
target/arm/helper-mve.h | 108 +++++++
65
target/arm: Add PAuth helpers
64
target/arm/translate.h | 41 +++
66
target/arm: Decode PAuth within system hint space
65
target/arm/mve.decode | 177 ++++++++++-
67
target/arm: Rearrange decode in disas_data_proc_1src
66
target/arm/t32.decode | 71 ++++-
68
target/arm: Decode PAuth within disas_data_proc_1src
67
hw/arm/bcm2835_peripherals.c | 13 +-
69
target/arm: Decode PAuth within disas_data_proc_2src
68
hw/gpio/gpio_pwr.c | 2 +-
70
target/arm: Move helper_exception_return to helper-a64.c
69
hw/misc/bcm2835_powermgt.c | 160 ++++++++++
71
target/arm: Add new_pc argument to helper_exception_return
70
target/arm/helper-a64.c | 12 +-
72
target/arm: Rearrange decode in disas_uncond_b_reg
71
target/arm/mve_helper.c | 524 +++++++++++++++++++++++++++++++--
73
target/arm: Decode PAuth within disas_uncond_b_reg
72
target/arm/translate-a64.c | 86 +-----
74
target/arm: Decode Load/store register (pac)
73
target/arm/translate-mve.c | 261 +++++++++++++++-
75
target/arm: Move cpu_mmu_index out of line
74
target/arm/translate-neon.c | 81 -----
76
target/arm: Introduce arm_mmu_idx
75
target/arm/translate.c | 327 +++++++++++++++++++-
77
target/arm: Introduce arm_stage1_mmu_idx
76
target/arm/vfp_helper.c | 24 +-
78
target/arm: Create ARMVAParameters and helpers
77
hw/misc/meson.build | 1 +
79
target/arm: Merge TBFLAG_AA_TB{0, 1} to TBII
78
tests/acceptance/boot_linux_console.py | 43 +++
80
target/arm: Export aa64_va_parameters to internals.h
79
20 files changed, 1760 insertions(+), 209 deletions(-)
81
target/arm: Add aa64_va_parameters_both
80
create mode 100644 include/hw/misc/bcm2835_powermgt.h
82
target/arm: Decode TBID from TCR
81
create mode 100644 hw/misc/bcm2835_powermgt.c
83
target/arm: Reuse aa64_va_parameters for setting tbflags
84
target/arm: Implement pauth_strip
85
target/arm: Implement pauth_auth
86
target/arm: Implement pauth_addpac
87
target/arm: Implement pauth_computepac
88
target/arm: Add PAuth system registers
89
target/arm: Enable PAuth for -cpu max
90
target/arm: Enable PAuth for user-only
91
target/arm: Tidy TBI handling in gen_a64_set_pc
92
82
93
target/arm/Makefile.objs | 1 +
94
include/hw/acpi/acpi-defs.h | 2 +
95
include/migration/vmstate.h | 1 +
96
target/arm/cpu.h | 244 +++++----
97
target/arm/helper-a64.h | 14 +
98
target/arm/helper.h | 1 -
99
target/arm/internals.h | 77 +++
100
target/arm/translate.h | 5 +-
101
tests/libqtest.h | 11 +
102
hw/arm/virt-acpi-build.c | 1 +
103
hw/char/stm32f2xx_usart.c | 3 +-
104
hw/net/ftgmac100.c | 80 ++-
105
migration/vmstate.c | 13 +-
106
target/arm/cpu.c | 19 +-
107
target/arm/cpu64.c | 68 ++-
108
target/arm/helper-a64.c | 155 ++++++
109
target/arm/helper.c | 1222 +++++++++++++++++++++++++++++++++----------
110
target/arm/machine.c | 24 +
111
target/arm/op_helper.c | 174 +-----
112
target/arm/pauth_helper.c | 497 ++++++++++++++++++
113
target/arm/translate-a64.c | 537 ++++++++++++++++---
114
tests/libqtest.c | 26 +
115
docs/devel/migration.rst | 9 +-
116
23 files changed, 2552 insertions(+), 632 deletions(-)
117
create mode 100644 target/arm/pauth_helper.c
118
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
When the device is disabled, the internal circuitry keeps the data
4
register loaded and doesn't update it.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20190104182057.8778-1-philmd@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/char/stm32f2xx_usart.c | 3 +--
12
1 file changed, 1 insertion(+), 2 deletions(-)
13
14
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/char/stm32f2xx_usart.c
17
+++ b/hw/char/stm32f2xx_usart.c
18
@@ -XXX,XX +XXX,XX @@ static void stm32f2xx_usart_receive(void *opaque, const uint8_t *buf, int size)
19
{
20
STM32F2XXUsartState *s = opaque;
21
22
- s->usart_dr = *buf;
23
-
24
if (!(s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_RE)) {
25
/* USART not enabled - drop the chars */
26
DB_PRINT("Dropping the chars\n");
27
return;
28
}
29
30
+ s->usart_dr = *buf;
31
s->usart_sr |= USART_SR_RXNE;
32
33
if (s->usart_cr1 & USART_CR1_RXNEIE) {
34
--
35
2.20.1
36
37
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
Let's report IO-coherent access is supported for translation
4
table walks, descriptor fetches and queues by setting the COHACC
5
override flag. Without that, we observe wrong command opcodes.
6
The DT description also advertises the dma coherency.
7
8
Fixes a703b4f6c1ee ("hw/arm/virt-acpi-build: Add smmuv3 node in IORT table")
9
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Reported-by: Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com>
12
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
13
Reviewed-by: Andrew Jones <drjones@redhat.com>
14
Message-id: 20190107101041.765-1-eric.auger@redhat.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
include/hw/acpi/acpi-defs.h | 2 ++
18
hw/arm/virt-acpi-build.c | 1 +
19
2 files changed, 3 insertions(+)
20
21
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/acpi/acpi-defs.h
24
+++ b/include/hw/acpi/acpi-defs.h
25
@@ -XXX,XX +XXX,XX @@ struct AcpiIortItsGroup {
26
} QEMU_PACKED;
27
typedef struct AcpiIortItsGroup AcpiIortItsGroup;
28
29
+#define ACPI_IORT_SMMU_V3_COHACC_OVERRIDE 1
30
+
31
struct AcpiIortSmmu3 {
32
ACPI_IORT_NODE_HEADER_DEF
33
uint64_t base_address;
34
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/virt-acpi-build.c
37
+++ b/hw/arm/virt-acpi-build.c
38
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
39
smmu->mapping_count = cpu_to_le32(1);
40
smmu->mapping_offset = cpu_to_le32(sizeof(*smmu));
41
smmu->base_address = cpu_to_le64(vms->memmap[VIRT_SMMU].base);
42
+ smmu->flags = cpu_to_le32(ACPI_IORT_SMMU_V3_COHACC_OVERRIDE);
43
smmu->event_gsiv = cpu_to_le32(irq);
44
smmu->pri_gsiv = cpu_to_le32(irq + 1);
45
smmu->gerr_gsiv = cpu_to_le32(irq + 2);
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
Deleted patch
1
From: Alexander Graf <agraf@suse.de>
2
1
3
In U-boot, we switch from S-SVC -> Mon -> Hyp mode when we want to
4
enter Hyp mode. The change into Hyp mode is done by doing an
5
exception return from Mon. This doesn't work with current QEMU.
6
7
The problem is that in bad_mode_switch() we refuse to allow
8
the change of mode.
9
10
Note that bad_mode_switch() is used to do validation for two situations:
11
12
(1) changes to mode by instructions writing to CPSR.M
13
(ie not exception take/return) -- this corresponds to the
14
Armv8 Arm ARM pseudocode Arch32.WriteModeByInstr
15
(2) changes to mode by exception return
16
17
Attempting to enter or leave Hyp mode via case (1) is forbidden in
18
v8 and UNPREDICTABLE in v7, and QEMU is correct to disallow it
19
there. However, we're already doing that check at the top of the
20
bad_mode_switch() function, so if that passes then we should allow
21
the case (2) exception return mode changes to switch into Hyp mode.
22
23
We want to test whether we're trying to return to the nonexistent
24
"secure Hyp" mode, so we need to look at arm_is_secure_below_el3()
25
rather than arm_is_secure(), since the latter is always true if
26
we're in Mon (EL3).
27
28
Signed-off-by: Alexander Graf <agraf@suse.de>
29
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
30
Message-id: 20190109152430.32359-1-agraf@suse.de
31
[PMM: rewrote commit message]
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
---
34
target/arm/helper.c | 2 +-
35
1 file changed, 1 insertion(+), 1 deletion(-)
36
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.c
40
+++ b/target/arm/helper.c
41
@@ -XXX,XX +XXX,XX @@ static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type)
42
return 0;
43
case ARM_CPU_MODE_HYP:
44
return !arm_feature(env, ARM_FEATURE_EL2)
45
- || arm_current_el(env) < 2 || arm_is_secure(env);
46
+ || arm_current_el(env) < 2 || arm_is_secure_below_el3(env);
47
case ARM_CPU_MODE_MON:
48
return arm_current_el(env) < 3;
49
default:
50
--
51
2.20.1
52
53
diff view generated by jsdifflib
1
From: Julia Suvorova <jusual@mail.ru>
1
From: Patrick Venture <venture@google.com>
2
2
3
Run qtest with a socket that connects QEMU chardev and test code.
3
Adds a line-item reference to the supported quanta-q71l-bmc aspeed
4
entry.
4
5
5
Signed-off-by: Julia Suvorova <jusual@mail.ru>
6
Signed-off-by: Patrick Venture <venture@google.com>
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Message-id: 20190117161640.5496-2-jusual@mail.ru
8
Message-id: 20210615192848.1065297-2-venture@google.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
tests/libqtest.h | 11 +++++++++++
11
docs/system/arm/aspeed.rst | 1 +
11
tests/libqtest.c | 26 ++++++++++++++++++++++++++
12
1 file changed, 1 insertion(+)
12
2 files changed, 37 insertions(+)
13
13
14
diff --git a/tests/libqtest.h b/tests/libqtest.h
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/libqtest.h
16
--- a/docs/system/arm/aspeed.rst
17
+++ b/tests/libqtest.h
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@ QTestState *qtest_init(const char *extra_args);
18
@@ -XXX,XX +XXX,XX @@ etc.
19
*/
19
AST2400 SoC based machines :
20
QTestState *qtest_init_without_qmp_handshake(const char *extra_args);
20
21
21
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
22
+/**
22
+- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
23
+ * qtest_init_with_serial:
23
24
+ * @extra_args: other arguments to pass to QEMU. CAUTION: these
24
AST2500 SoC based machines :
25
+ * arguments are subject to word splitting and shell evaluation.
25
26
+ * @sock_fd: pointer to store the socket file descriptor for
27
+ * connection with serial.
28
+ *
29
+ * Returns: #QTestState instance.
30
+ */
31
+QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd);
32
+
33
/**
34
* qtest_quit:
35
* @s: #QTestState instance to operate on.
36
diff --git a/tests/libqtest.c b/tests/libqtest.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/tests/libqtest.c
39
+++ b/tests/libqtest.c
40
@@ -XXX,XX +XXX,XX @@ QTestState *qtest_initf(const char *fmt, ...)
41
return s;
42
}
43
44
+QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd)
45
+{
46
+ int sock_fd_init;
47
+ char *sock_path, sock_dir[] = "/tmp/qtest-serial-XXXXXX";
48
+ QTestState *qts;
49
+
50
+ g_assert(mkdtemp(sock_dir));
51
+ sock_path = g_strdup_printf("%s/sock", sock_dir);
52
+
53
+ sock_fd_init = init_socket(sock_path);
54
+
55
+ qts = qtest_initf("-chardev socket,id=s0,path=%s,nowait "
56
+ "-serial chardev:s0 %s",
57
+ sock_path, extra_args);
58
+
59
+ *sock_fd = socket_accept(sock_fd_init);
60
+
61
+ unlink(sock_path);
62
+ g_free(sock_path);
63
+ rmdir(sock_dir);
64
+
65
+ g_assert(*sock_fd >= 0);
66
+
67
+ return qts;
68
+}
69
+
70
void qtest_quit(QTestState *s)
71
{
72
g_hook_destroy_link(&abrt_hooks, g_hook_find_data(&abrt_hooks, TRUE, s));
73
--
26
--
74
2.20.1
27
2.20.1
75
28
76
29
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: Patrick Venture <venture@google.com>
2
2
3
This both advertises that we support four counters and enables them
3
Add line item reference to quanta-gbs-bmc machine.
4
because the pmu_num_counters() reads this value from PMCR.
5
4
6
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
5
Signed-off-by: Patrick Venture <venture@google.com>
7
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20210615192848.1065297-3-venture@google.com
9
Message-id: 20181211151945.29137-13-aaron@os.amperecomputing.com
8
[PMM: fixed underline Sphinx warning]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
target/arm/helper.c | 10 +++++-----
11
docs/system/arm/nuvoton.rst | 5 +++--
13
1 file changed, 5 insertions(+), 5 deletions(-)
12
1 file changed, 3 insertions(+), 2 deletions(-)
14
13
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
16
--- a/docs/system/arm/nuvoton.rst
18
+++ b/target/arm/helper.c
17
+++ b/docs/system/arm/nuvoton.rst
19
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
18
@@ -XXX,XX +XXX,XX @@
20
.access = PL1_W, .type = ARM_CP_NOP },
19
-Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
21
/* Performance monitors are implementation defined in v7,
20
-=====================================================
22
* but with an ARM recommended set of registers, which we
21
+Nuvoton iBMC boards (``*-bmc``, ``npcm750-evb``, ``quanta-gsj``)
23
- * follow (although we don't actually implement any counters)
22
+================================================================
24
+ * follow.
23
25
*
24
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
26
* Performance registers fall into three categories:
25
designed to be used as Baseboard Management Controllers (BMCs) in various
27
* (a) always UNDEF in PL0, RW in PL1 (PMINTENSET, PMINTENCLR)
26
@@ -XXX,XX +XXX,XX @@ segment. The following machines are based on this chip :
28
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
27
The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
29
}
28
Hyperscale applications. The following machines are based on this chip :
30
if (arm_feature(env, ARM_FEATURE_V7)) {
29
31
/* v7 performance monitor control register: same implementor
30
+- ``quanta-gbs-bmc`` Quanta GBS server BMC
32
- * field as main ID register, and we implement only the cycle
31
- ``quanta-gsj`` Quanta GSJ server BMC
33
- * count register.
32
34
+ * field as main ID register, and we implement four counters in
33
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
35
+ * addition to the cycle count register.
36
*/
37
- unsigned int i, pmcrn = 0;
38
+ unsigned int i, pmcrn = 4;
39
ARMCPRegInfo pmcr = {
40
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
41
.access = PL0_RW,
42
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
43
.access = PL0_RW, .accessfn = pmreg_access,
44
.type = ARM_CP_IO,
45
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
46
- .resetvalue = cpu->midr & 0xff000000,
47
+ .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
48
.writefn = pmcr_write, .raw_writefn = raw_write,
49
};
50
define_one_arm_cp_reg(cpu, &pmcr);
51
--
34
--
52
2.20.1
35
2.20.1
53
36
54
37
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Nolan Leake <nolan@sigbus.net>
2
2
3
The PHY behind the MAC of an Aspeed SoC can be controlled using two
3
This is just enough to make reboot and poweroff work. Works for
4
different MDC/MDIO interfaces. The same registers PHYCR (MAC60) and
4
linux, u-boot, and the arm trusted firmware. Not tested, but should
5
PHYDATA (MAC64) are involved but they have a different layout.
5
work for plan9, and bare-metal/hobby OSes, since they seem to generally
6
6
do what linux does for reset.
7
BIT31 of the Feature Register (MAC40) controls which MDC/MDIO
7
8
interface is active.
8
The watchdog timer functionality is not yet implemented.
9
9
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/64
11
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
11
Signed-off-by: Nolan Leake <nolan@sigbus.net>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20190111125759.31577-1-clg@kaod.org
13
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20210625210209.1870217-1-nolan@sigbus.net
15
[PMM: tweaked commit title; fixed region size to 0x200;
16
moved header file to include/]
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
18
---
16
hw/net/ftgmac100.c | 80 +++++++++++++++++++++++++++++++++++++++-------
19
include/hw/arm/bcm2835_peripherals.h | 3 +-
17
1 file changed, 68 insertions(+), 12 deletions(-)
20
include/hw/misc/bcm2835_powermgt.h | 29 +++++
18
21
hw/arm/bcm2835_peripherals.c | 13 ++-
19
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
22
hw/misc/bcm2835_powermgt.c | 160 +++++++++++++++++++++++++++
23
hw/misc/meson.build | 1 +
24
5 files changed, 204 insertions(+), 2 deletions(-)
25
create mode 100644 include/hw/misc/bcm2835_powermgt.h
26
create mode 100644 hw/misc/bcm2835_powermgt.c
27
28
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
20
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/net/ftgmac100.c
30
--- a/include/hw/arm/bcm2835_peripherals.h
22
+++ b/hw/net/ftgmac100.c
31
+++ b/include/hw/arm/bcm2835_peripherals.h
23
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@
24
#define FTGMAC100_PHYDATA_MIIWDATA(x) ((x) & 0xffff)
33
#include "hw/misc/bcm2835_mphi.h"
25
#define FTGMAC100_PHYDATA_MIIRDATA(x) (((x) >> 16) & 0xffff)
34
#include "hw/misc/bcm2835_thermal.h"
26
35
#include "hw/misc/bcm2835_cprman.h"
36
+#include "hw/misc/bcm2835_powermgt.h"
37
#include "hw/sd/sdhci.h"
38
#include "hw/sd/bcm2835_sdhost.h"
39
#include "hw/gpio/bcm2835_gpio.h"
40
@@ -XXX,XX +XXX,XX @@ struct BCM2835PeripheralState {
41
BCM2835MphiState mphi;
42
UnimplementedDeviceState txp;
43
UnimplementedDeviceState armtmr;
44
- UnimplementedDeviceState powermgt;
45
+ BCM2835PowerMgtState powermgt;
46
BCM2835CprmanState cprman;
47
PL011State uart0;
48
BCM2835AuxState aux;
49
diff --git a/include/hw/misc/bcm2835_powermgt.h b/include/hw/misc/bcm2835_powermgt.h
50
new file mode 100644
51
index XXXXXXX..XXXXXXX
52
--- /dev/null
53
+++ b/include/hw/misc/bcm2835_powermgt.h
54
@@ -XXX,XX +XXX,XX @@
27
+/*
55
+/*
28
+ * PHY control register - New MDC/MDIO interface
56
+ * BCM2835 Power Management emulation
57
+ *
58
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
59
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
60
+ *
61
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
62
+ * See the COPYING file in the top-level directory.
29
+ */
63
+ */
30
+#define FTGMAC100_PHYCR_NEW_DATA(x) (((x) >> 16) & 0xffff)
64
+
31
+#define FTGMAC100_PHYCR_NEW_FIRE (1 << 15)
65
+#ifndef BCM2835_POWERMGT_H
32
+#define FTGMAC100_PHYCR_NEW_ST_22 (1 << 12)
66
+#define BCM2835_POWERMGT_H
33
+#define FTGMAC100_PHYCR_NEW_OP(x) (((x) >> 10) & 3)
67
+
34
+#define FTGMAC100_PHYCR_NEW_OP_WRITE 0x1
68
+#include "hw/sysbus.h"
35
+#define FTGMAC100_PHYCR_NEW_OP_READ 0x2
69
+#include "qom/object.h"
36
+#define FTGMAC100_PHYCR_NEW_DEV(x) (((x) >> 5) & 0x1f)
70
+
37
+#define FTGMAC100_PHYCR_NEW_REG(x) ((x) & 0x1f)
71
+#define TYPE_BCM2835_POWERMGT "bcm2835-powermgt"
38
+
72
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PowerMgtState, BCM2835_POWERMGT)
39
/*
73
+
40
* Feature Register
74
+struct BCM2835PowerMgtState {
41
*/
75
+ SysBusDevice busdev;
42
@@ -XXX,XX +XXX,XX @@ static void phy_reset(FTGMAC100State *s)
76
+ MemoryRegion iomem;
43
s->phy_int = 0;
77
+
78
+ uint32_t rstc;
79
+ uint32_t rsts;
80
+ uint32_t wdog;
81
+};
82
+
83
+#endif
84
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/arm/bcm2835_peripherals.c
87
+++ b/hw/arm/bcm2835_peripherals.c
88
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
89
90
object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr",
91
OBJECT(&s->gpu_bus_mr));
92
+
93
+ /* Power Management */
94
+ object_initialize_child(obj, "powermgt", &s->powermgt,
95
+ TYPE_BCM2835_POWERMGT);
44
}
96
}
45
97
46
-static uint32_t do_phy_read(FTGMAC100State *s, int reg)
98
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
47
+static uint16_t do_phy_read(FTGMAC100State *s, uint8_t reg)
99
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
48
{
100
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
49
- uint32_t val;
101
INTERRUPT_USB));
50
+ uint16_t val;
102
51
103
+ /* Power Management */
52
switch (reg) {
104
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->powermgt), errp)) {
53
case MII_BMCR: /* Basic Control */
54
@@ -XXX,XX +XXX,XX @@ static uint32_t do_phy_read(FTGMAC100State *s, int reg)
55
MII_BMCR_FD | MII_BMCR_CTST)
56
#define MII_ANAR_MASK 0x2d7f
57
58
-static void do_phy_write(FTGMAC100State *s, int reg, uint32_t val)
59
+static void do_phy_write(FTGMAC100State *s, uint8_t reg, uint16_t val)
60
{
61
switch (reg) {
62
case MII_BMCR: /* Basic Control */
63
@@ -XXX,XX +XXX,XX @@ static void do_phy_write(FTGMAC100State *s, int reg, uint32_t val)
64
}
65
}
66
67
+static void do_phy_new_ctl(FTGMAC100State *s)
68
+{
69
+ uint8_t reg;
70
+ uint16_t data;
71
+
72
+ if (!(s->phycr & FTGMAC100_PHYCR_NEW_ST_22)) {
73
+ qemu_log_mask(LOG_UNIMP, "%s: unsupported ST code\n", __func__);
74
+ return;
105
+ return;
75
+ }
106
+ }
76
+
107
+
77
+ /* Nothing to do */
108
+ memory_region_add_subregion(&s->peri_mr, PM_OFFSET,
78
+ if (!(s->phycr & FTGMAC100_PHYCR_NEW_FIRE)) {
109
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->powermgt), 0));
110
+
111
create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000);
112
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
113
- create_unimp(s, &s->powermgt, "bcm2835-powermgt", PM_OFFSET, 0x114);
114
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
115
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
116
create_unimp(s, &s->spi[0], "bcm2835-spi0", SPI0_OFFSET, 0x20);
117
diff --git a/hw/misc/bcm2835_powermgt.c b/hw/misc/bcm2835_powermgt.c
118
new file mode 100644
119
index XXXXXXX..XXXXXXX
120
--- /dev/null
121
+++ b/hw/misc/bcm2835_powermgt.c
122
@@ -XXX,XX +XXX,XX @@
123
+/*
124
+ * BCM2835 Power Management emulation
125
+ *
126
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
127
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
128
+ *
129
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
130
+ * See the COPYING file in the top-level directory.
131
+ */
132
+
133
+#include "qemu/osdep.h"
134
+#include "qemu/log.h"
135
+#include "qemu/module.h"
136
+#include "hw/misc/bcm2835_powermgt.h"
137
+#include "migration/vmstate.h"
138
+#include "sysemu/runstate.h"
139
+
140
+#define PASSWORD 0x5a000000
141
+#define PASSWORD_MASK 0xff000000
142
+
143
+#define R_RSTC 0x1c
144
+#define V_RSTC_RESET 0x20
145
+#define R_RSTS 0x20
146
+#define V_RSTS_POWEROFF 0x555 /* Linux uses partition 63 to indicate halt. */
147
+#define R_WDOG 0x24
148
+
149
+static uint64_t bcm2835_powermgt_read(void *opaque, hwaddr offset,
150
+ unsigned size)
151
+{
152
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
153
+ uint32_t res = 0;
154
+
155
+ switch (offset) {
156
+ case R_RSTC:
157
+ res = s->rstc;
158
+ break;
159
+ case R_RSTS:
160
+ res = s->rsts;
161
+ break;
162
+ case R_WDOG:
163
+ res = s->wdog;
164
+ break;
165
+
166
+ default:
167
+ qemu_log_mask(LOG_UNIMP,
168
+ "bcm2835_powermgt_read: Unknown offset 0x%08"HWADDR_PRIx
169
+ "\n", offset);
170
+ res = 0;
171
+ break;
172
+ }
173
+
174
+ return res;
175
+}
176
+
177
+static void bcm2835_powermgt_write(void *opaque, hwaddr offset,
178
+ uint64_t value, unsigned size)
179
+{
180
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
181
+
182
+ if ((value & PASSWORD_MASK) != PASSWORD) {
183
+ qemu_log_mask(LOG_GUEST_ERROR,
184
+ "bcm2835_powermgt_write: Bad password 0x%"PRIx64
185
+ " at offset 0x%08"HWADDR_PRIx"\n",
186
+ value, offset);
79
+ return;
187
+ return;
80
+ }
188
+ }
81
+
189
+
82
+ reg = FTGMAC100_PHYCR_NEW_REG(s->phycr);
190
+ value = value & ~PASSWORD_MASK;
83
+ data = FTGMAC100_PHYCR_NEW_DATA(s->phycr);
191
+
84
+
192
+ switch (offset) {
85
+ switch (FTGMAC100_PHYCR_NEW_OP(s->phycr)) {
193
+ case R_RSTC:
86
+ case FTGMAC100_PHYCR_NEW_OP_WRITE:
194
+ s->rstc = value;
87
+ do_phy_write(s, reg, data);
195
+ if (value & V_RSTC_RESET) {
88
+ break;
196
+ if ((s->rsts & 0xfff) == V_RSTS_POWEROFF) {
89
+ case FTGMAC100_PHYCR_NEW_OP_READ:
197
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
90
+ s->phydata = do_phy_read(s, reg) & 0xffff;
198
+ } else {
91
+ break;
199
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
200
+ }
201
+ }
202
+ break;
203
+ case R_RSTS:
204
+ qemu_log_mask(LOG_UNIMP,
205
+ "bcm2835_powermgt_write: RSTS\n");
206
+ s->rsts = value;
207
+ break;
208
+ case R_WDOG:
209
+ qemu_log_mask(LOG_UNIMP,
210
+ "bcm2835_powermgt_write: WDOG\n");
211
+ s->wdog = value;
212
+ break;
213
+
92
+ default:
214
+ default:
93
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid OP code %08x\n",
215
+ qemu_log_mask(LOG_UNIMP,
94
+ __func__, s->phycr);
216
+ "bcm2835_powermgt_write: Unknown offset 0x%08"HWADDR_PRIx
95
+ }
217
+ "\n", offset);
96
+
218
+ break;
97
+ s->phycr &= ~FTGMAC100_PHYCR_NEW_FIRE;
219
+ }
98
+}
220
+}
99
+
221
+
100
+static void do_phy_ctl(FTGMAC100State *s)
222
+static const MemoryRegionOps bcm2835_powermgt_ops = {
101
+{
223
+ .read = bcm2835_powermgt_read,
102
+ uint8_t reg = FTGMAC100_PHYCR_REG(s->phycr);
224
+ .write = bcm2835_powermgt_write,
103
+
225
+ .endianness = DEVICE_NATIVE_ENDIAN,
104
+ if (s->phycr & FTGMAC100_PHYCR_MIIWR) {
226
+ .impl.min_access_size = 4,
105
+ do_phy_write(s, reg, s->phydata & 0xffff);
227
+ .impl.max_access_size = 4,
106
+ s->phycr &= ~FTGMAC100_PHYCR_MIIWR;
228
+};
107
+ } else if (s->phycr & FTGMAC100_PHYCR_MIIRD) {
229
+
108
+ s->phydata = do_phy_read(s, reg) << 16;
230
+static const VMStateDescription vmstate_bcm2835_powermgt = {
109
+ s->phycr &= ~FTGMAC100_PHYCR_MIIRD;
231
+ .name = TYPE_BCM2835_POWERMGT,
110
+ } else {
232
+ .version_id = 1,
111
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: no OP code %08x\n",
233
+ .minimum_version_id = 1,
112
+ __func__, s->phycr);
234
+ .fields = (VMStateField[]) {
113
+ }
235
+ VMSTATE_UINT32(rstc, BCM2835PowerMgtState),
114
+}
236
+ VMSTATE_UINT32(rsts, BCM2835PowerMgtState),
115
+
237
+ VMSTATE_UINT32(wdog, BCM2835PowerMgtState),
116
static int ftgmac100_read_bd(FTGMAC100Desc *bd, dma_addr_t addr)
238
+ VMSTATE_END_OF_LIST()
117
{
239
+ }
118
if (dma_memory_read(&address_space_memory, addr, bd, sizeof(*bd))) {
240
+};
119
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_write(void *opaque, hwaddr addr,
241
+
120
uint64_t value, unsigned size)
242
+static void bcm2835_powermgt_init(Object *obj)
121
{
243
+{
122
FTGMAC100State *s = FTGMAC100(opaque);
244
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(obj);
123
- int reg;
245
+
124
246
+ memory_region_init_io(&s->iomem, obj, &bcm2835_powermgt_ops, s,
125
switch (addr & 0xff) {
247
+ TYPE_BCM2835_POWERMGT, 0x200);
126
case FTGMAC100_ISR: /* Interrupt status */
248
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
127
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_write(void *opaque, hwaddr addr,
249
+}
128
break;
250
+
129
251
+static void bcm2835_powermgt_reset(DeviceState *dev)
130
case FTGMAC100_PHYCR: /* PHY Device control */
252
+{
131
- reg = FTGMAC100_PHYCR_REG(value);
253
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(dev);
132
s->phycr = value;
254
+
133
- if (value & FTGMAC100_PHYCR_MIIWR) {
255
+ /* https://elinux.org/BCM2835_registers#PM */
134
- do_phy_write(s, reg, s->phydata & 0xffff);
256
+ s->rstc = 0x00000102;
135
- s->phycr &= ~FTGMAC100_PHYCR_MIIWR;
257
+ s->rsts = 0x00001000;
136
+ if (s->revr & FTGMAC100_REVR_NEW_MDIO_INTERFACE) {
258
+ s->wdog = 0x00000000;
137
+ do_phy_new_ctl(s);
259
+}
138
} else {
260
+
139
- s->phydata = do_phy_read(s, reg) << 16;
261
+static void bcm2835_powermgt_class_init(ObjectClass *klass, void *data)
140
- s->phycr &= ~FTGMAC100_PHYCR_MIIRD;
262
+{
141
+ do_phy_ctl(s);
263
+ DeviceClass *dc = DEVICE_CLASS(klass);
142
}
264
+
143
break;
265
+ dc->reset = bcm2835_powermgt_reset;
144
case FTGMAC100_PHYDATA:
266
+ dc->vmsd = &vmstate_bcm2835_powermgt;
145
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_write(void *opaque, hwaddr addr,
267
+}
146
s->dblac = value;
268
+
147
break;
269
+static TypeInfo bcm2835_powermgt_info = {
148
case FTGMAC100_REVR: /* Feature Register */
270
+ .name = TYPE_BCM2835_POWERMGT,
149
- /* TODO: Only Old MDIO interface is supported */
271
+ .parent = TYPE_SYS_BUS_DEVICE,
150
- s->revr = value & ~FTGMAC100_REVR_NEW_MDIO_INTERFACE;
272
+ .instance_size = sizeof(BCM2835PowerMgtState),
151
+ s->revr = value;
273
+ .class_init = bcm2835_powermgt_class_init,
152
break;
274
+ .instance_init = bcm2835_powermgt_init,
153
case FTGMAC100_FEAR1: /* Feature Register 1 */
275
+};
154
s->fear1 = value;
276
+
277
+static void bcm2835_powermgt_register_types(void)
278
+{
279
+ type_register_static(&bcm2835_powermgt_info);
280
+}
281
+
282
+type_init(bcm2835_powermgt_register_types)
283
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
284
index XXXXXXX..XXXXXXX 100644
285
--- a/hw/misc/meson.build
286
+++ b/hw/misc/meson.build
287
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
288
'bcm2835_rng.c',
289
'bcm2835_thermal.c',
290
'bcm2835_cprman.c',
291
+ 'bcm2835_powermgt.c',
292
))
293
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
294
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 'zynq-xadc.c'))
155
--
295
--
156
2.20.1
296
2.20.1
157
297
158
298
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Add storage space for the 5 encryption keys.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190108223129.5570-2-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/cpu.h | 30 +++++++++++++++++++++++++++++-
11
1 file changed, 29 insertions(+), 1 deletion(-)
12
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVectorReg {
18
uint64_t d[2 * ARM_MAX_VQ] QEMU_ALIGNED(16);
19
} ARMVectorReg;
20
21
-/* In AArch32 mode, predicate registers do not exist at all. */
22
#ifdef TARGET_AARCH64
23
+/* In AArch32 mode, predicate registers do not exist at all. */
24
typedef struct ARMPredicateReg {
25
uint64_t p[2 * ARM_MAX_VQ / 8] QEMU_ALIGNED(16);
26
} ARMPredicateReg;
27
+
28
+/* In AArch32 mode, PAC keys do not exist at all. */
29
+typedef struct ARMPACKey {
30
+ uint64_t lo, hi;
31
+} ARMPACKey;
32
#endif
33
34
35
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
36
uint32_t cregs[16];
37
} iwmmxt;
38
39
+#ifdef TARGET_AARCH64
40
+ ARMPACKey apia_key;
41
+ ARMPACKey apib_key;
42
+ ARMPACKey apda_key;
43
+ ARMPACKey apdb_key;
44
+ ARMPACKey apga_key;
45
+#endif
46
+
47
#if defined(CONFIG_USER_ONLY)
48
/* For usermode syscall translation. */
49
int eabi;
50
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
51
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
52
}
53
54
+static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
55
+{
56
+ /*
57
+ * Note that while QEMU will only implement the architected algorithm
58
+ * QARMA, and thus APA+GPA, the host cpu for kvm may use implementation
59
+ * defined algorithms, and thus API+GPI, and this predicate controls
60
+ * migration of the 128-bit keys.
61
+ */
62
+ return (id->id_aa64isar1 &
63
+ (FIELD_DP64(0, ID_AA64ISAR1, APA, -1) |
64
+ FIELD_DP64(0, ID_AA64ISAR1, API, -1) |
65
+ FIELD_DP64(0, ID_AA64ISAR1, GPA, -1) |
66
+ FIELD_DP64(0, ID_AA64ISAR1, GPI, -1))) != 0;
67
+}
68
+
69
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
70
{
71
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
72
--
73
2.20.1
74
75
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Post v8.4 bits taken from SysReg_v85_xml-00bet8.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190108223129.5570-3-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/cpu.h | 45 +++++++++++++++++++++++++++++++++------------
11
1 file changed, 33 insertions(+), 12 deletions(-)
12
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ void pmccntr_sync(CPUARMState *env);
18
#define SCTLR_A (1U << 1)
19
#define SCTLR_C (1U << 2)
20
#define SCTLR_W (1U << 3) /* up to v6; RAO in v7 */
21
-#define SCTLR_SA (1U << 3)
22
+#define SCTLR_nTLSMD_32 (1U << 3) /* v8.2-LSMAOC, AArch32 only */
23
+#define SCTLR_SA (1U << 3) /* AArch64 only */
24
#define SCTLR_P (1U << 4) /* up to v5; RAO in v6 and v7 */
25
+#define SCTLR_LSMAOE_32 (1U << 4) /* v8.2-LSMAOC, AArch32 only */
26
#define SCTLR_SA0 (1U << 4) /* v8 onward, AArch64 only */
27
#define SCTLR_D (1U << 5) /* up to v5; RAO in v6 */
28
#define SCTLR_CP15BEN (1U << 5) /* v7 onward */
29
#define SCTLR_L (1U << 6) /* up to v5; RAO in v6 and v7; RAZ in v8 */
30
+#define SCTLR_nAA (1U << 6) /* when v8.4-LSE is implemented */
31
#define SCTLR_B (1U << 7) /* up to v6; RAZ in v7 */
32
#define SCTLR_ITD (1U << 7) /* v8 onward */
33
#define SCTLR_S (1U << 8) /* up to v6; RAZ in v7 */
34
@@ -XXX,XX +XXX,XX @@ void pmccntr_sync(CPUARMState *env);
35
#define SCTLR_R (1U << 9) /* up to v6; RAZ in v7 */
36
#define SCTLR_UMA (1U << 9) /* v8 onward, AArch64 only */
37
#define SCTLR_F (1U << 10) /* up to v6 */
38
-#define SCTLR_SW (1U << 10) /* v7 onward */
39
-#define SCTLR_Z (1U << 11)
40
+#define SCTLR_SW (1U << 10) /* v7, RES0 in v8 */
41
+#define SCTLR_Z (1U << 11) /* in v7, RES1 in v8 */
42
+#define SCTLR_EOS (1U << 11) /* v8.5-ExS */
43
#define SCTLR_I (1U << 12)
44
-#define SCTLR_V (1U << 13)
45
+#define SCTLR_V (1U << 13) /* AArch32 only */
46
+#define SCTLR_EnDB (1U << 13) /* v8.3, AArch64 only */
47
#define SCTLR_RR (1U << 14) /* up to v7 */
48
#define SCTLR_DZE (1U << 14) /* v8 onward, AArch64 only */
49
#define SCTLR_L4 (1U << 15) /* up to v6; RAZ in v7 */
50
#define SCTLR_UCT (1U << 15) /* v8 onward, AArch64 only */
51
#define SCTLR_DT (1U << 16) /* up to ??, RAO in v6 and v7 */
52
#define SCTLR_nTWI (1U << 16) /* v8 onward */
53
-#define SCTLR_HA (1U << 17)
54
+#define SCTLR_HA (1U << 17) /* up to v7, RES0 in v8 */
55
#define SCTLR_BR (1U << 17) /* PMSA only */
56
#define SCTLR_IT (1U << 18) /* up to ??, RAO in v6 and v7 */
57
#define SCTLR_nTWE (1U << 18) /* v8 onward */
58
#define SCTLR_WXN (1U << 19)
59
#define SCTLR_ST (1U << 20) /* up to ??, RAZ in v6 */
60
-#define SCTLR_UWXN (1U << 20) /* v7 onward */
61
-#define SCTLR_FI (1U << 21)
62
-#define SCTLR_U (1U << 22)
63
+#define SCTLR_UWXN (1U << 20) /* v7 onward, AArch32 only */
64
+#define SCTLR_FI (1U << 21) /* up to v7, v8 RES0 */
65
+#define SCTLR_IESB (1U << 21) /* v8.2-IESB, AArch64 only */
66
+#define SCTLR_U (1U << 22) /* up to v6, RAO in v7 */
67
+#define SCTLR_EIS (1U << 22) /* v8.5-ExS */
68
#define SCTLR_XP (1U << 23) /* up to v6; v7 onward RAO */
69
+#define SCTLR_SPAN (1U << 23) /* v8.1-PAN */
70
#define SCTLR_VE (1U << 24) /* up to v7 */
71
#define SCTLR_E0E (1U << 24) /* v8 onward, AArch64 only */
72
#define SCTLR_EE (1U << 25)
73
#define SCTLR_L2 (1U << 26) /* up to v6, RAZ in v7 */
74
#define SCTLR_UCI (1U << 26) /* v8 onward, AArch64 only */
75
-#define SCTLR_NMFI (1U << 27)
76
-#define SCTLR_TRE (1U << 28)
77
-#define SCTLR_AFE (1U << 29)
78
-#define SCTLR_TE (1U << 30)
79
+#define SCTLR_NMFI (1U << 27) /* up to v7, RAZ in v7VE and v8 */
80
+#define SCTLR_EnDA (1U << 27) /* v8.3, AArch64 only */
81
+#define SCTLR_TRE (1U << 28) /* AArch32 only */
82
+#define SCTLR_nTLSMD_64 (1U << 28) /* v8.2-LSMAOC, AArch64 only */
83
+#define SCTLR_AFE (1U << 29) /* AArch32 only */
84
+#define SCTLR_LSMAOE_64 (1U << 29) /* v8.2-LSMAOC, AArch64 only */
85
+#define SCTLR_TE (1U << 30) /* AArch32 only */
86
+#define SCTLR_EnIB (1U << 30) /* v8.3, AArch64 only */
87
+#define SCTLR_EnIA (1U << 31) /* v8.3, AArch64 only */
88
+#define SCTLR_BT0 (1ULL << 35) /* v8.5-BTI */
89
+#define SCTLR_BT1 (1ULL << 36) /* v8.5-BTI */
90
+#define SCTLR_ITFSB (1ULL << 37) /* v8.5-MemTag */
91
+#define SCTLR_TCF0 (3ULL << 38) /* v8.5-MemTag */
92
+#define SCTLR_TCF (3ULL << 40) /* v8.5-MemTag */
93
+#define SCTLR_ATA0 (1ULL << 42) /* v8.5-MemTag */
94
+#define SCTLR_ATA (1ULL << 43) /* v8.5-MemTag */
95
+#define SCTLR_DSSBS (1ULL << 44) /* v8.5 */
96
97
#define CPTR_TCPAC (1U << 31)
98
#define CPTR_TTA (1U << 20)
99
--
100
2.20.1
101
102
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
This commit doesn't add any supported events, but provides the framework
3
Add a test booting and quickly shutdown a raspi2 machine,
4
for adding them. We store the pm_event structs in a simple array, and
4
to test the power management model:
5
provide the mapping from the event numbers to array indexes in the
6
supported_event_map array. Because the value of PMCEID[01] depends upon
7
which events are supported at runtime, generate it dynamically.
8
5
9
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
6
(1/1) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_initrd:
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
console: [ 0.000000] Booting Linux on physical CPU 0xf00
11
Message-id: 20181211151945.29137-10-aaron@os.amperecomputing.com
8
console: [ 0.000000] Linux version 4.14.98-v7+ (dom@dom-XPS-13-9370) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1200 SMP Tue Feb 12 20:27:48 GMT 2019
9
console: [ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
10
console: [ 0.000000] CPU: div instructions available: patching division code
11
console: [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
12
console: [ 0.000000] OF: fdt: Machine model: Raspberry Pi 2 Model B
13
...
14
console: Boot successful.
15
console: cat /proc/cpuinfo
16
console: / # cat /proc/cpuinfo
17
...
18
console: processor : 3
19
console: model name : ARMv7 Processor rev 5 (v7l)
20
console: BogoMIPS : 125.00
21
console: Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
22
console: CPU implementer : 0x41
23
console: CPU architecture: 7
24
console: CPU variant : 0x0
25
console: CPU part : 0xc07
26
console: CPU revision : 5
27
console: Hardware : BCM2835
28
console: Revision : 0000
29
console: Serial : 0000000000000000
30
console: cat /proc/iomem
31
console: / # cat /proc/iomem
32
console: 00000000-3bffffff : System RAM
33
console: 00008000-00afffff : Kernel code
34
console: 00c00000-00d468ef : Kernel data
35
console: 3f006000-3f006fff : dwc_otg
36
console: 3f007000-3f007eff : /soc/dma@7e007000
37
console: 3f00b880-3f00b8bf : /soc/mailbox@7e00b880
38
console: 3f100000-3f100027 : /soc/watchdog@7e100000
39
console: 3f101000-3f102fff : /soc/cprman@7e101000
40
console: 3f200000-3f2000b3 : /soc/gpio@7e200000
41
PASS (24.59 s)
42
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
43
JOB TIME : 25.02 s
44
45
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
46
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
47
Message-id: 20210531113837.1689775-1-f4bug@amsat.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
49
---
14
target/arm/cpu.h | 10 ++++++++
50
tests/acceptance/boot_linux_console.py | 43 ++++++++++++++++++++++++++
15
target/arm/cpu.c | 19 +++++++++------
51
1 file changed, 43 insertions(+)
16
target/arm/cpu64.c | 4 ----
17
target/arm/helper.c | 57 +++++++++++++++++++++++++++++++++++++++++++++
18
4 files changed, 79 insertions(+), 11 deletions(-)
19
52
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
53
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
21
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
55
--- a/tests/acceptance/boot_linux_console.py
23
+++ b/target/arm/cpu.h
56
+++ b/tests/acceptance/boot_linux_console.py
24
@@ -XXX,XX +XXX,XX @@ void pmu_op_finish(CPUARMState *env);
57
@@ -XXX,XX +XXX,XX @@
25
void pmu_pre_el_change(ARMCPU *cpu, void *ignored);
58
from avocado import skip
26
void pmu_post_el_change(ARMCPU *cpu, void *ignored);
59
from avocado import skipUnless
27
60
from avocado_qemu import Test
28
+/*
61
+from avocado_qemu import exec_command
29
+ * get_pmceid
62
from avocado_qemu import exec_command_and_wait_for_pattern
30
+ * @env: CPUARMState
63
from avocado_qemu import interrupt_interactive_console_until_pattern
31
+ * @which: which PMCEID register to return (0 or 1)
64
from avocado_qemu import wait_for_console_pattern
32
+ *
65
@@ -XXX,XX +XXX,XX @@ def test_arm_raspi2_uart0(self):
33
+ * Return the PMCEID[01]_EL0 register values corresponding to the counters
66
"""
34
+ * which are supported given the current configuration
67
self.do_test_arm_raspi2(0)
35
+ */
68
36
+uint64_t get_pmceid(CPUARMState *env, unsigned which);
69
+ def test_arm_raspi2_initrd(self):
70
+ """
71
+ :avocado: tags=arch:arm
72
+ :avocado: tags=machine:raspi2
73
+ """
74
+ deb_url = ('http://archive.raspberrypi.org/debian/'
75
+ 'pool/main/r/raspberrypi-firmware/'
76
+ 'raspberrypi-kernel_1.20190215-1_armhf.deb')
77
+ deb_hash = 'cd284220b32128c5084037553db3c482426f3972'
78
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
79
+ kernel_path = self.extract_from_deb(deb_path, '/boot/kernel7.img')
80
+ dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2709-rpi-2-b.dtb')
37
+
81
+
38
/* SCTLR bit meanings. Several bits have been reused in newer
82
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
39
* versions of the architecture; in that case we define constants
83
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
40
* for both old and new bit meanings. Code which tests against those
84
+ 'arm/rootfs-armv7a.cpio.gz')
41
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
85
+ initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c'
42
index XXXXXXX..XXXXXXX 100644
86
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
43
--- a/target/arm/cpu.c
87
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
44
+++ b/target/arm/cpu.c
88
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
45
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
46
47
if (!cpu->has_pmu) {
48
unset_feature(env, ARM_FEATURE_PMU);
49
+ }
50
+ if (arm_feature(env, ARM_FEATURE_PMU)) {
51
+ cpu->pmceid0 = get_pmceid(&cpu->env, 0);
52
+ cpu->pmceid1 = get_pmceid(&cpu->env, 1);
53
+
89
+
54
+ if (!kvm_enabled()) {
90
+ self.vm.set_console()
55
+ arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0);
91
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
56
+ arm_register_el_change_hook(cpu, &pmu_post_el_change, 0);
92
+ 'earlycon=pl011,0x3f201000 console=ttyAMA0 '
57
+ }
93
+ 'panic=-1 noreboot ' +
58
+ } else {
94
+ 'dwc_otg.fiq_fsm_enable=0')
59
cpu->id_aa64dfr0 &= ~0xf00;
95
+ self.vm.add_args('-kernel', kernel_path,
60
- } else if (!kvm_enabled()) {
96
+ '-dtb', dtb_path,
61
- arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0);
97
+ '-initrd', initrd_path,
62
- arm_register_el_change_hook(cpu, &pmu_post_el_change, 0);
98
+ '-append', kernel_command_line,
63
+ cpu->pmceid0 = 0;
99
+ '-no-reboot')
64
+ cpu->pmceid1 = 0;
100
+ self.vm.launch()
65
}
101
+ self.wait_for_console_pattern('Boot successful.')
66
67
if (!arm_feature(env, ARM_FEATURE_EL2)) {
68
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
69
cpu->id_pfr0 = 0x00001131;
70
cpu->id_pfr1 = 0x00011011;
71
cpu->id_dfr0 = 0x02010555;
72
- cpu->pmceid0 = 0x00000000;
73
- cpu->pmceid1 = 0x00000000;
74
cpu->id_afr0 = 0x00000000;
75
cpu->id_mmfr0 = 0x10101105;
76
cpu->id_mmfr1 = 0x40000000;
77
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
78
cpu->id_pfr0 = 0x00001131;
79
cpu->id_pfr1 = 0x00011011;
80
cpu->id_dfr0 = 0x02010555;
81
- cpu->pmceid0 = 0x0000000;
82
- cpu->pmceid1 = 0x00000000;
83
cpu->id_afr0 = 0x00000000;
84
cpu->id_mmfr0 = 0x10201105;
85
cpu->id_mmfr1 = 0x20000000;
86
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/arm/cpu64.c
89
+++ b/target/arm/cpu64.c
90
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
91
cpu->isar.id_isar6 = 0;
92
cpu->isar.id_aa64pfr0 = 0x00002222;
93
cpu->id_aa64dfr0 = 0x10305106;
94
- cpu->pmceid0 = 0x00000000;
95
- cpu->pmceid1 = 0x00000000;
96
cpu->isar.id_aa64isar0 = 0x00011120;
97
cpu->isar.id_aa64mmfr0 = 0x00001124;
98
cpu->dbgdidr = 0x3516d000;
99
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
100
cpu->isar.id_isar5 = 0x00011121;
101
cpu->isar.id_aa64pfr0 = 0x00002222;
102
cpu->id_aa64dfr0 = 0x10305106;
103
- cpu->pmceid0 = 0x00000000;
104
- cpu->pmceid1 = 0x00000000;
105
cpu->isar.id_aa64isar0 = 0x00011120;
106
cpu->isar.id_aa64mmfr0 = 0x00001124;
107
cpu->dbgdidr = 0x3516d000;
108
diff --git a/target/arm/helper.c b/target/arm/helper.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/target/arm/helper.c
111
+++ b/target/arm/helper.c
112
@@ -XXX,XX +XXX,XX @@ static inline uint64_t pmu_counter_mask(CPUARMState *env)
113
return (1 << 31) | ((1 << pmu_num_counters(env)) - 1);
114
}
115
116
+typedef struct pm_event {
117
+ uint16_t number; /* PMEVTYPER.evtCount is 16 bits wide */
118
+ /* If the event is supported on this CPU (used to generate PMCEID[01]) */
119
+ bool (*supported)(CPUARMState *);
120
+ /*
121
+ * Retrieve the current count of the underlying event. The programmed
122
+ * counters hold a difference from the return value from this function
123
+ */
124
+ uint64_t (*get_count)(CPUARMState *);
125
+} pm_event;
126
+
102
+
127
+static const pm_event pm_events[] = {
103
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
128
+};
104
+ 'BCM2835')
105
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
106
+ '/soc/cprman@7e101000')
107
+ exec_command(self, 'halt')
108
+ # Wait for VM to shut down gracefully
109
+ self.vm.wait()
129
+
110
+
130
+/*
111
def test_arm_exynos4210_initrd(self):
131
+ * Note: Before increasing MAX_EVENT_ID beyond 0x3f into the 0x40xx range of
112
"""
132
+ * events (i.e. the statistical profiling extension), this implementation
113
:avocado: tags=arch:arm
133
+ * should first be updated to something sparse instead of the current
134
+ * supported_event_map[] array.
135
+ */
136
+#define MAX_EVENT_ID 0x0
137
+#define UNSUPPORTED_EVENT UINT16_MAX
138
+static uint16_t supported_event_map[MAX_EVENT_ID + 1];
139
+
140
+/*
141
+ * Called upon initialization to build PMCEID0_EL0 or PMCEID1_EL0 (indicated by
142
+ * 'which'). We also use it to build a map of ARM event numbers to indices in
143
+ * our pm_events array.
144
+ *
145
+ * Note: Events in the 0x40XX range are not currently supported.
146
+ */
147
+uint64_t get_pmceid(CPUARMState *env, unsigned which)
148
+{
149
+ uint64_t pmceid = 0;
150
+ unsigned int i;
151
+
152
+ assert(which <= 1);
153
+
154
+ for (i = 0; i < ARRAY_SIZE(supported_event_map); i++) {
155
+ supported_event_map[i] = UNSUPPORTED_EVENT;
156
+ }
157
+
158
+ for (i = 0; i < ARRAY_SIZE(pm_events); i++) {
159
+ const pm_event *cnt = &pm_events[i];
160
+ assert(cnt->number <= MAX_EVENT_ID);
161
+ /* We do not currently support events in the 0x40xx range */
162
+ assert(cnt->number <= 0x3f);
163
+
164
+ if ((cnt->number & 0x20) == (which << 6) &&
165
+ cnt->supported(env)) {
166
+ pmceid |= (1 << (cnt->number & 0x1f));
167
+ supported_event_map[cnt->number] = i;
168
+ }
169
+ }
170
+ return pmceid;
171
+}
172
+
173
static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
174
bool isread)
175
{
176
--
114
--
177
2.20.1
115
2.20.1
178
116
179
117
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
2
2
3
If the CPU is running in default NaN mode (FPCR.DN == 1) and we execute
4
FRSQRTE, FRECPE, or FRECPX with a signaling NaN, parts_silence_nan_frac() will
5
assert due to fpst->default_nan_mode being set.
6
7
To avoid this, we check to see what NaN mode we're running in before we call
8
floatxx_silence_nan().
9
10
Signed-off-by: Joe Komlodi <joe.komlodi@xilinx.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 1624662174-175828-2-git-send-email-joe.komlodi@xilinx.com
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-12-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
15
---
8
target/arm/helper-a64.h | 2 +-
16
target/arm/helper-a64.c | 12 +++++++++---
9
target/arm/helper-a64.c | 10 +++++-----
17
target/arm/vfp_helper.c | 24 ++++++++++++++++++------
10
target/arm/translate-a64.c | 7 ++++++-
18
2 files changed, 27 insertions(+), 9 deletions(-)
11
3 files changed, 12 insertions(+), 7 deletions(-)
12
19
13
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper-a64.h
16
+++ b/target/arm/helper-a64.h
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
18
DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
19
DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
20
21
-DEF_HELPER_1(exception_return, void, env)
22
+DEF_HELPER_2(exception_return, void, env, i64)
23
24
DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64)
25
DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64)
26
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
20
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
27
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/helper-a64.c
22
--- a/target/arm/helper-a64.c
29
+++ b/target/arm/helper-a64.c
23
+++ b/target/arm/helper-a64.c
30
@@ -XXX,XX +XXX,XX @@ static int el_from_spsr(uint32_t spsr)
24
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
31
}
25
float16 nan = a;
32
}
26
if (float16_is_signaling_nan(a, fpst)) {
33
27
float_raise(float_flag_invalid, fpst);
34
-void HELPER(exception_return)(CPUARMState *env)
28
- nan = float16_silence_nan(a, fpst);
35
+void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
29
+ if (!fpst->default_nan_mode) {
36
{
30
+ nan = float16_silence_nan(a, fpst);
37
int cur_el = arm_current_el(env);
31
+ }
38
unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
39
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env)
40
aarch64_sync_64_to_32(env);
41
42
if (spsr & CPSR_T) {
43
- env->regs[15] = env->elr_el[cur_el] & ~0x1;
44
+ env->regs[15] = new_pc & ~0x1;
45
} else {
46
- env->regs[15] = env->elr_el[cur_el] & ~0x3;
47
+ env->regs[15] = new_pc & ~0x3;
48
}
32
}
49
qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
33
if (fpst->default_nan_mode) {
50
"AArch32 EL%d PC 0x%" PRIx32 "\n",
34
nan = float16_default_nan(fpst);
51
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env)
35
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
52
env->pstate &= ~PSTATE_SS;
36
float32 nan = a;
37
if (float32_is_signaling_nan(a, fpst)) {
38
float_raise(float_flag_invalid, fpst);
39
- nan = float32_silence_nan(a, fpst);
40
+ if (!fpst->default_nan_mode) {
41
+ nan = float32_silence_nan(a, fpst);
42
+ }
53
}
43
}
54
aarch64_restore_sp(env, new_el);
44
if (fpst->default_nan_mode) {
55
- env->pc = env->elr_el[cur_el];
45
nan = float32_default_nan(fpst);
56
+ env->pc = new_pc;
46
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
57
qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
47
float64 nan = a;
58
"AArch64 EL%d PC 0x%" PRIx64 "\n",
48
if (float64_is_signaling_nan(a, fpst)) {
59
cur_el, new_el, env->pc);
49
float_raise(float_flag_invalid, fpst);
60
@@ -XXX,XX +XXX,XX @@ illegal_return:
50
- nan = float64_silence_nan(a, fpst);
61
* no change to exception level, execution state or stack pointer
51
+ if (!fpst->default_nan_mode) {
62
*/
52
+ nan = float64_silence_nan(a, fpst);
63
env->pstate |= PSTATE_IL;
53
+ }
64
- env->pc = env->elr_el[cur_el];
54
}
65
+ env->pc = new_pc;
55
if (fpst->default_nan_mode) {
66
spsr &= PSTATE_NZCV | PSTATE_DAIF;
56
nan = float64_default_nan(fpst);
67
spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF);
57
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
68
pstate_write(env, spsr);
69
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
70
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/translate-a64.c
59
--- a/target/arm/vfp_helper.c
72
+++ b/target/arm/translate-a64.c
60
+++ b/target/arm/vfp_helper.c
73
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
61
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
74
static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
62
float16 nan = f16;
75
{
63
if (float16_is_signaling_nan(f16, fpst)) {
76
unsigned int opc, op2, op3, rn, op4;
64
float_raise(float_flag_invalid, fpst);
77
+ TCGv_i64 dst;
65
- nan = float16_silence_nan(f16, fpst);
78
66
+ if (!fpst->default_nan_mode) {
79
opc = extract32(insn, 21, 4);
67
+ nan = float16_silence_nan(f16, fpst);
80
op2 = extract32(insn, 16, 5);
68
+ }
81
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
82
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
83
gen_io_start();
84
}
69
}
85
- gen_helper_exception_return(cpu_env);
70
if (fpst->default_nan_mode) {
86
+ dst = tcg_temp_new_i64();
71
nan = float16_default_nan(fpst);
87
+ tcg_gen_ld_i64(dst, cpu_env,
72
@@ -XXX,XX +XXX,XX @@ float32 HELPER(recpe_f32)(float32 input, void *fpstp)
88
+ offsetof(CPUARMState, elr_el[s->current_el]));
73
float32 nan = f32;
89
+ gen_helper_exception_return(cpu_env, dst);
74
if (float32_is_signaling_nan(f32, fpst)) {
90
+ tcg_temp_free_i64(dst);
75
float_raise(float_flag_invalid, fpst);
91
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
76
- nan = float32_silence_nan(f32, fpst);
92
gen_io_end();
77
+ if (!fpst->default_nan_mode) {
78
+ nan = float32_silence_nan(f32, fpst);
79
+ }
93
}
80
}
81
if (fpst->default_nan_mode) {
82
nan = float32_default_nan(fpst);
83
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
84
float64 nan = f64;
85
if (float64_is_signaling_nan(f64, fpst)) {
86
float_raise(float_flag_invalid, fpst);
87
- nan = float64_silence_nan(f64, fpst);
88
+ if (!fpst->default_nan_mode) {
89
+ nan = float64_silence_nan(f64, fpst);
90
+ }
91
}
92
if (fpst->default_nan_mode) {
93
nan = float64_default_nan(fpst);
94
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(rsqrte_f16)(uint32_t input, void *fpstp)
95
float16 nan = f16;
96
if (float16_is_signaling_nan(f16, s)) {
97
float_raise(float_flag_invalid, s);
98
- nan = float16_silence_nan(f16, s);
99
+ if (!s->default_nan_mode) {
100
+ nan = float16_silence_nan(f16, fpstp);
101
+ }
102
}
103
if (s->default_nan_mode) {
104
nan = float16_default_nan(s);
105
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
106
float32 nan = f32;
107
if (float32_is_signaling_nan(f32, s)) {
108
float_raise(float_flag_invalid, s);
109
- nan = float32_silence_nan(f32, s);
110
+ if (!s->default_nan_mode) {
111
+ nan = float32_silence_nan(f32, fpstp);
112
+ }
113
}
114
if (s->default_nan_mode) {
115
nan = float32_default_nan(s);
116
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
117
float64 nan = f64;
118
if (float64_is_signaling_nan(f64, s)) {
119
float_raise(float_flag_invalid, s);
120
- nan = float64_silence_nan(f64, s);
121
+ if (!s->default_nan_mode) {
122
+ nan = float64_silence_nan(f64, fpstp);
123
+ }
124
}
125
if (s->default_nan_mode) {
126
nan = float64_default_nan(s);
94
--
127
--
95
2.20.1
128
2.20.1
96
129
97
130
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
2
2
3
qemu has 2 type of functions: shutdown and reboot. Shutdown
4
function has to be used for machine shutdown. Otherwise we cause
5
a reset with a bogus "cause" value, when we intended a shutdown.
6
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210625111842.3790-3-maxim.uvarov@linaro.org
5
Message-id: 20190108223129.5570-7-richard.henderson@linaro.org
10
[PMM: tweaked commit message]
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
target/arm/translate-a64.c | 93 +++++++++++++++++++++++++++++++++-----
13
hw/gpio/gpio_pwr.c | 2 +-
9
1 file changed, 81 insertions(+), 12 deletions(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
10
15
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.c
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
18
--- a/hw/gpio/gpio_pwr.c
14
+++ b/target/arm/translate-a64.c
19
+++ b/hw/gpio/gpio_pwr.c
15
@@ -XXX,XX +XXX,XX @@ static void handle_hint(DisasContext *s, uint32_t insn,
20
@@ -XXX,XX +XXX,XX @@ static void gpio_pwr_reset(void *opaque, int n, int level)
16
}
21
static void gpio_pwr_shutdown(void *opaque, int n, int level)
17
22
{
18
switch (selector) {
23
if (level) {
19
- case 0: /* NOP */
24
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
20
- return;
25
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
21
- case 3: /* WFI */
22
+ case 0b00000: /* NOP */
23
+ break;
24
+ case 0b00011: /* WFI */
25
s->base.is_jmp = DISAS_WFI;
26
- return;
27
+ break;
28
+ case 0b00001: /* YIELD */
29
/* When running in MTTCG we don't generate jumps to the yield and
30
* WFE helpers as it won't affect the scheduling of other vCPUs.
31
* If we wanted to more completely model WFE/SEV so we don't busy
32
* spin unnecessarily we would need to do something more involved.
33
*/
34
- case 1: /* YIELD */
35
if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
36
s->base.is_jmp = DISAS_YIELD;
37
}
38
- return;
39
- case 2: /* WFE */
40
+ break;
41
+ case 0b00010: /* WFE */
42
if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
43
s->base.is_jmp = DISAS_WFE;
44
}
45
- return;
46
- case 4: /* SEV */
47
- case 5: /* SEVL */
48
+ break;
49
+ case 0b00100: /* SEV */
50
+ case 0b00101: /* SEVL */
51
/* we treat all as NOP at least for now */
52
- return;
53
+ break;
54
+ case 0b00111: /* XPACLRI */
55
+ if (s->pauth_active) {
56
+ gen_helper_xpaci(cpu_X[30], cpu_env, cpu_X[30]);
57
+ }
58
+ break;
59
+ case 0b01000: /* PACIA1716 */
60
+ if (s->pauth_active) {
61
+ gen_helper_pacia(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
62
+ }
63
+ break;
64
+ case 0b01010: /* PACIB1716 */
65
+ if (s->pauth_active) {
66
+ gen_helper_pacib(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
67
+ }
68
+ break;
69
+ case 0b01100: /* AUTIA1716 */
70
+ if (s->pauth_active) {
71
+ gen_helper_autia(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
72
+ }
73
+ break;
74
+ case 0b01110: /* AUTIB1716 */
75
+ if (s->pauth_active) {
76
+ gen_helper_autib(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
77
+ }
78
+ break;
79
+ case 0b11000: /* PACIAZ */
80
+ if (s->pauth_active) {
81
+ gen_helper_pacia(cpu_X[30], cpu_env, cpu_X[30],
82
+ new_tmp_a64_zero(s));
83
+ }
84
+ break;
85
+ case 0b11001: /* PACIASP */
86
+ if (s->pauth_active) {
87
+ gen_helper_pacia(cpu_X[30], cpu_env, cpu_X[30], cpu_X[31]);
88
+ }
89
+ break;
90
+ case 0b11010: /* PACIBZ */
91
+ if (s->pauth_active) {
92
+ gen_helper_pacib(cpu_X[30], cpu_env, cpu_X[30],
93
+ new_tmp_a64_zero(s));
94
+ }
95
+ break;
96
+ case 0b11011: /* PACIBSP */
97
+ if (s->pauth_active) {
98
+ gen_helper_pacib(cpu_X[30], cpu_env, cpu_X[30], cpu_X[31]);
99
+ }
100
+ break;
101
+ case 0b11100: /* AUTIAZ */
102
+ if (s->pauth_active) {
103
+ gen_helper_autia(cpu_X[30], cpu_env, cpu_X[30],
104
+ new_tmp_a64_zero(s));
105
+ }
106
+ break;
107
+ case 0b11101: /* AUTIASP */
108
+ if (s->pauth_active) {
109
+ gen_helper_autia(cpu_X[30], cpu_env, cpu_X[30], cpu_X[31]);
110
+ }
111
+ break;
112
+ case 0b11110: /* AUTIBZ */
113
+ if (s->pauth_active) {
114
+ gen_helper_autib(cpu_X[30], cpu_env, cpu_X[30],
115
+ new_tmp_a64_zero(s));
116
+ }
117
+ break;
118
+ case 0b11111: /* AUTIBSP */
119
+ if (s->pauth_active) {
120
+ gen_helper_autib(cpu_X[30], cpu_env, cpu_X[30], cpu_X[31]);
121
+ }
122
+ break;
123
default:
124
/* default specified as NOP equivalent */
125
- return;
126
+ break;
127
}
26
}
128
}
27
}
129
28
130
--
29
--
131
2.20.1
30
2.20.1
132
31
133
32
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
In do_ldst(), the calculation of the offset needs to be based on the
2
size of the memory access, not the size of the elements in the
3
vector. This meant we were getting it wrong for the widening and
4
narrowing variants of the various VLDR and VSTR insns.
2
5
3
The pattern
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-2-peter.maydell@linaro.org
9
---
10
target/arm/translate-mve.c | 17 +++++++++--------
11
1 file changed, 9 insertions(+), 8 deletions(-)
4
12
5
ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
13
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
6
7
is computing the full ARMMMUIdx, stripping off the ARM bits,
8
and then putting them back.
9
10
Avoid the extra two steps with the appropriate helper function.
11
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190108223129.5570-17-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/cpu.h | 9 ++++++++-
18
target/arm/internals.h | 8 ++++++++
19
target/arm/helper.c | 27 ++++++++++++++++-----------
20
3 files changed, 32 insertions(+), 12 deletions(-)
21
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
15
--- a/target/arm/translate-mve.c
25
+++ b/target/arm/cpu.h
16
+++ b/target/arm/translate-mve.c
26
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
17
@@ -XXX,XX +XXX,XX @@ static bool mve_skip_first_beat(DisasContext *s)
27
/* Return the MMU index for a v7M CPU in the specified security state */
28
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate);
29
30
-/* Determine the current mmu_idx to use for normal loads/stores */
31
+/**
32
+ * cpu_mmu_index:
33
+ * @env: The cpu environment
34
+ * @ifetch: True for code access, false for data access.
35
+ *
36
+ * Return the core mmu index for the current translation regime.
37
+ * This function is used by generic TCG code paths.
38
+ */
39
int cpu_mmu_index(CPUARMState *env, bool ifetch);
40
41
/* Indexes used when registering address spaces with cpu_address_space_init */
42
diff --git a/target/arm/internals.h b/target/arm/internals.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/internals.h
45
+++ b/target/arm/internals.h
46
@@ -XXX,XX +XXX,XX @@ void arm_cpu_update_virq(ARMCPU *cpu);
47
*/
48
void arm_cpu_update_vfiq(ARMCPU *cpu);
49
50
+/**
51
+ * arm_mmu_idx:
52
+ * @env: The cpu environment
53
+ *
54
+ * Return the full ARMMMUIdx for the current translation regime.
55
+ */
56
+ARMMMUIdx arm_mmu_idx(CPUARMState *env);
57
+
58
#endif
59
diff --git a/target/arm/helper.c b/target/arm/helper.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/arm/helper.c
62
+++ b/target/arm/helper.c
63
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
64
limit = env->v7m.msplim[M_REG_S];
65
}
66
} else {
67
- mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
68
+ mmu_idx = arm_mmu_idx(env);
69
frame_sp_p = &env->regs[13];
70
limit = v7m_sp_limit(env);
71
}
18
}
72
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
73
CPUARMState *env = &cpu->env;
74
uint32_t xpsr = xpsr_read(env);
75
uint32_t frameptr = env->regs[13];
76
- ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
77
+ ARMMMUIdx mmu_idx = arm_mmu_idx(env);
78
79
/* Align stack pointer if the guest wants that */
80
if ((frameptr & 4) &&
81
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
82
int prot;
83
bool ret;
84
ARMMMUFaultInfo fi = {};
85
- ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
86
+ ARMMMUIdx mmu_idx = arm_mmu_idx(env);
87
88
*attrs = (MemTxAttrs) {};
89
90
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
91
return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
92
}
19
}
93
20
94
-int cpu_mmu_index(CPUARMState *env, bool ifetch)
21
-static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
95
+ARMMMUIdx arm_mmu_idx(CPUARMState *env)
22
+static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn,
23
+ unsigned msize)
96
{
24
{
97
- int el = arm_current_el(env);
25
TCGv_i32 addr;
98
+ int el;
26
uint32_t offset;
99
27
@@ -XXX,XX +XXX,XX @@ static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
100
if (arm_feature(env, ARM_FEATURE_M)) {
28
return true;
101
- ARMMMUIdx mmu_idx = arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
102
-
103
- return arm_to_core_mmu_idx(mmu_idx);
104
+ return arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
105
}
29
}
106
30
107
+ el = arm_current_el(env);
31
- offset = a->imm << a->size;
108
if (el < 2 && arm_is_secure_below_el3(env)) {
32
+ offset = a->imm << msize;
109
- return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el);
33
if (!a->a) {
110
+ return ARMMMUIdx_S1SE0 + el;
34
offset = -offset;
111
+ } else {
112
+ return ARMMMUIdx_S12NSE0 + el;
113
}
35
}
114
- return el;
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR(DisasContext *s, arg_VLDR_VSTR *a)
115
+}
37
{ gen_helper_mve_vstrw, gen_helper_mve_vldrw },
116
+
38
{ NULL, NULL }
117
+int cpu_mmu_index(CPUARMState *env, bool ifetch)
39
};
118
+{
40
- return do_ldst(s, a, ldstfns[a->size][a->l]);
119
+ return arm_to_core_mmu_idx(arm_mmu_idx(env));
41
+ return do_ldst(s, a, ldstfns[a->size][a->l], a->size);
120
}
42
}
121
43
122
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
44
-#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST) \
123
target_ulong *cs_base, uint32_t *pflags)
45
+#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST, MSIZE) \
46
static bool trans_##OP(DisasContext *s, arg_VLDR_VSTR *a) \
47
{ \
48
static MVEGenLdStFn * const ldstfns[2][2] = { \
49
{ gen_helper_mve_##ST, gen_helper_mve_##SLD }, \
50
{ NULL, gen_helper_mve_##ULD }, \
51
}; \
52
- return do_ldst(s, a, ldstfns[a->u][a->l]); \
53
+ return do_ldst(s, a, ldstfns[a->u][a->l], MSIZE); \
54
}
55
56
-DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h)
57
-DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w)
58
-DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w)
59
+DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h, MO_8)
60
+DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w, MO_8)
61
+DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w, MO_16)
62
63
static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
124
{
64
{
125
- ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
126
+ ARMMMUIdx mmu_idx = arm_mmu_idx(env);
127
int current_el = arm_current_el(env);
128
int fp_el = fp_exception_el(env, current_el);
129
uint32_t flags = 0;
130
--
65
--
131
2.20.1
66
2.20.1
132
67
133
68
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
The initial implementation of the MVE VRMLALDAVH and VRMLSLDAVH
2
insns had some bugs:
3
* the 32x32 multiply of elements was being done as 32x32->32,
4
not 32x32->64
5
* we were incorrectly maintaining the accumulator in its full
6
72-bit form across all 4 beats of the insn; in the pseudocode
7
it is squashed back into the 64 bits of the RdaHi:RdaLo
8
registers after each beat
2
9
3
In some cases it may be helpful to modify state before saving it for
10
In particular, fixing the second of these allows us to recast
4
migration, and then modify the state back after it has been saved. The
11
the implementation to avoid 128-bit arithmetic entirely.
5
existing pre_save function provides half of this functionality. This
6
patch adds a post_save function to provide the second half.
7
12
8
Signed-off-by: Aaron Lindsay <aclindsa@gmail.com>
13
Since the element size here is always 4, we can also drop the
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
parameterization of ESIZE to make the code a little more readable.
10
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
15
11
Message-id: 20181211151945.29137-2-aaron@os.amperecomputing.com
16
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210628135835.6690-3-peter.maydell@linaro.org
13
---
20
---
14
include/migration/vmstate.h | 1 +
21
target/arm/mve_helper.c | 38 +++++++++++++++++++++-----------------
15
migration/vmstate.c | 13 ++++++++++++-
22
1 file changed, 21 insertions(+), 17 deletions(-)
16
docs/devel/migration.rst | 9 +++++++--
17
3 files changed, 20 insertions(+), 3 deletions(-)
18
23
19
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
24
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
20
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
21
--- a/include/migration/vmstate.h
26
--- a/target/arm/mve_helper.c
22
+++ b/include/migration/vmstate.h
27
+++ b/target/arm/mve_helper.c
23
@@ -XXX,XX +XXX,XX @@ struct VMStateDescription {
28
@@ -XXX,XX +XXX,XX @@
24
int (*pre_load)(void *opaque);
29
*/
25
int (*post_load)(void *opaque, int version_id);
30
26
int (*pre_save)(void *opaque);
31
#include "qemu/osdep.h"
27
+ int (*post_save)(void *opaque);
32
-#include "qemu/int128.h"
28
bool (*needed)(void *opaque);
33
#include "cpu.h"
29
const VMStateField *fields;
34
#include "internals.h"
30
const VMStateDescription **subsections;
35
#include "vec_internal.h"
31
diff --git a/migration/vmstate.c b/migration/vmstate.c
36
@@ -XXX,XX +XXX,XX @@ DO_LDAV(vmlsldavsw, 4, int32_t, false, +=, -=)
32
index XXXXXXX..XXXXXXX 100644
37
DO_LDAV(vmlsldavxsw, 4, int32_t, true, +=, -=)
33
--- a/migration/vmstate.c
38
34
+++ b/migration/vmstate.c
39
/*
35
@@ -XXX,XX +XXX,XX @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
40
- * Rounding multiply add long dual accumulate high: we must keep
36
if (ret) {
41
- * a 72-bit internal accumulator value and return the top 64 bits.
37
error_report("Save of field %s/%s failed",
42
+ * Rounding multiply add long dual accumulate high. In the pseudocode
38
vmsd->name, field->name);
43
+ * this is implemented with a 72-bit internal accumulator value of which
39
+ if (vmsd->post_save) {
44
+ * the top 64 bits are returned. We optimize this to avoid having to
40
+ vmsd->post_save(opaque);
45
+ * use 128-bit arithmetic -- we can do this because the 74-bit accumulator
41
+ }
46
+ * is squashed back into 64-bits after each beat.
42
return ret;
47
*/
43
}
48
-#define DO_LDAVH(OP, ESIZE, TYPE, XCHG, EVENACC, ODDACC, TO128) \
44
49
+#define DO_LDAVH(OP, TYPE, LTYPE, XCHG, SUB) \
45
@@ -XXX,XX +XXX,XX @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
50
uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vn, \
46
json_end_array(vmdesc);
51
void *vm, uint64_t a) \
52
{ \
53
uint16_t mask = mve_element_mask(env); \
54
unsigned e; \
55
TYPE *n = vn, *m = vm; \
56
- Int128 acc = int128_lshift(TO128(a), 8); \
57
- for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
58
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
59
if (mask & 1) { \
60
+ LTYPE mul; \
61
if (e & 1) { \
62
- acc = ODDACC(acc, TO128(n[H##ESIZE(e - 1 * XCHG)] * \
63
- m[H##ESIZE(e)])); \
64
+ mul = (LTYPE)n[H4(e - 1 * XCHG)] * m[H4(e)]; \
65
+ if (SUB) { \
66
+ mul = -mul; \
67
+ } \
68
} else { \
69
- acc = EVENACC(acc, TO128(n[H##ESIZE(e + 1 * XCHG)] * \
70
- m[H##ESIZE(e)])); \
71
+ mul = (LTYPE)n[H4(e + 1 * XCHG)] * m[H4(e)]; \
72
} \
73
- acc = int128_add(acc, int128_make64(1 << 7)); \
74
+ mul = (mul >> 8) + ((mul >> 7) & 1); \
75
+ a += mul; \
76
} \
77
} \
78
mve_advance_vpt(env); \
79
- return int128_getlo(int128_rshift(acc, 8)); \
80
+ return a; \
47
}
81
}
48
82
49
- return vmstate_subsection_save(f, vmsd, opaque, vmdesc);
83
-DO_LDAVH(vrmlaldavhsw, 4, int32_t, false, int128_add, int128_add, int128_makes64)
50
+ ret = vmstate_subsection_save(f, vmsd, opaque, vmdesc);
84
-DO_LDAVH(vrmlaldavhxsw, 4, int32_t, true, int128_add, int128_add, int128_makes64)
51
+
85
+DO_LDAVH(vrmlaldavhsw, int32_t, int64_t, false, false)
52
+ if (vmsd->post_save) {
86
+DO_LDAVH(vrmlaldavhxsw, int32_t, int64_t, true, false)
53
+ int ps_ret = vmsd->post_save(opaque);
87
54
+ if (!ret) {
88
-DO_LDAVH(vrmlaldavhuw, 4, uint32_t, false, int128_add, int128_add, int128_make64)
55
+ ret = ps_ret;
89
+DO_LDAVH(vrmlaldavhuw, uint32_t, uint64_t, false, false)
56
+ }
90
57
+ }
91
-DO_LDAVH(vrmlsldavhsw, 4, int32_t, false, int128_add, int128_sub, int128_makes64)
58
+ return ret;
92
-DO_LDAVH(vrmlsldavhxsw, 4, int32_t, true, int128_add, int128_sub, int128_makes64)
59
}
93
+DO_LDAVH(vrmlsldavhsw, int32_t, int64_t, false, true)
60
94
+DO_LDAVH(vrmlsldavhxsw, int32_t, int64_t, true, true)
61
static const VMStateDescription *
95
62
diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
96
/* Vector add across vector */
63
index XXXXXXX..XXXXXXX 100644
97
#define DO_VADDV(OP, ESIZE, TYPE) \
64
--- a/docs/devel/migration.rst
65
+++ b/docs/devel/migration.rst
66
@@ -XXX,XX +XXX,XX @@ The functions to do that are inside a vmstate definition, and are called:
67
68
This function is called before we save the state of one device.
69
70
-Example: You can look at hpet.c, that uses the three function to
71
-massage the state that is transferred.
72
+- ``int (*post_save)(void *opaque);``
73
+
74
+ This function is called after we save the state of one device
75
+ (even upon failure, unless the call to pre_save returned an error).
76
+
77
+Example: You can look at hpet.c, that uses the first three functions
78
+to massage the state that is transferred.
79
80
The ``VMSTATE_WITH_TMP`` macro may be useful when the migration
81
data doesn't match the stored device data well; it allows an
82
--
98
--
83
2.20.1
99
2.20.1
84
100
85
101
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The function asimd_imm_const() in translate-neon.c is an
2
implementation of the pseudocode AdvSIMDExpandImm(), which we will
3
also want for MVE. Move the implementation to translate.c, with a
4
prototype in translate.h.
2
5
3
This function is, or will shortly become, too big to inline.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-4-peter.maydell@linaro.org
9
---
10
target/arm/translate.h | 16 ++++++++++
11
target/arm/translate-neon.c | 63 -------------------------------------
12
target/arm/translate.c | 57 +++++++++++++++++++++++++++++++++
13
3 files changed, 73 insertions(+), 63 deletions(-)
4
14
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190108223129.5570-16-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/cpu.h | 48 +++++----------------------------------------
11
target/arm/helper.c | 44 +++++++++++++++++++++++++++++++++++++++++
12
2 files changed, 49 insertions(+), 43 deletions(-)
13
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
17
--- a/target/arm/translate.h
17
+++ b/target/arm/cpu.h
18
+++ b/target/arm/translate.h
18
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
20
return opc | s->be_data;
19
}
21
}
20
22
21
/* Return the MMU index for a v7M CPU in the specified security and
23
+/**
22
- * privilege state
24
+ * asimd_imm_const: Expand an encoded SIMD constant value
23
+ * privilege state.
25
+ *
24
*/
26
+ * Expand a SIMD constant value. This is essentially the pseudocode
25
-static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
27
+ * AdvSIMDExpandImm, except that we also perform the boolean NOT needed for
26
- bool secstate,
28
+ * VMVN and VBIC (when cmode < 14 && op == 1).
27
- bool priv)
29
+ *
30
+ * The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
31
+ * callers must catch this.
32
+ *
33
+ * cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
34
+ * is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
35
+ * we produce an immediate constant value of 0 in these cases.
36
+ */
37
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
38
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
40
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-neon.c
43
+++ b/target/arm/translate-neon.c
44
@@ -XXX,XX +XXX,XX @@ DO_FP_2SH(VCVT_UH, gen_helper_gvec_vcvt_uh)
45
DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_hs)
46
DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_hu)
47
48
-static uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
28
-{
49
-{
29
- ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
50
- /*
51
- * Expand the encoded constant.
52
- * Note that cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
53
- * We choose to not special-case this and will behave as if a
54
- * valid constant encoding of 0 had been given.
55
- * cmode = 15 op = 1 must UNDEF; we assume decode has handled that.
56
- */
57
- switch (cmode) {
58
- case 0: case 1:
59
- /* no-op */
60
- break;
61
- case 2: case 3:
62
- imm <<= 8;
63
- break;
64
- case 4: case 5:
65
- imm <<= 16;
66
- break;
67
- case 6: case 7:
68
- imm <<= 24;
69
- break;
70
- case 8: case 9:
71
- imm |= imm << 16;
72
- break;
73
- case 10: case 11:
74
- imm = (imm << 8) | (imm << 24);
75
- break;
76
- case 12:
77
- imm = (imm << 8) | 0xff;
78
- break;
79
- case 13:
80
- imm = (imm << 16) | 0xffff;
81
- break;
82
- case 14:
83
- if (op) {
84
- /*
85
- * This is the only case where the top and bottom 32 bits
86
- * of the encoded constant differ.
87
- */
88
- uint64_t imm64 = 0;
89
- int n;
30
-
90
-
31
- if (priv) {
91
- for (n = 0; n < 8; n++) {
32
- mmu_idx |= ARM_MMU_IDX_M_PRIV;
92
- if (imm & (1 << n)) {
93
- imm64 |= (0xffULL << (n * 8));
94
- }
95
- }
96
- return imm64;
97
- }
98
- imm |= (imm << 8) | (imm << 16) | (imm << 24);
99
- break;
100
- case 15:
101
- imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
102
- | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
103
- break;
33
- }
104
- }
105
- if (op) {
106
- imm = ~imm;
107
- }
108
- return dup_const(MO_32, imm);
109
-}
34
-
110
-
35
- if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
111
static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
36
- mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
112
GVecGen2iFn *fn)
37
- }
113
{
38
-
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
39
- if (secstate) {
40
- mmu_idx |= ARM_MMU_IDX_M_S;
41
- }
42
-
43
- return mmu_idx;
44
-}
45
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
46
+ bool secstate, bool priv);
47
48
/* Return the MMU index for a v7M CPU in the specified security state */
49
-static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env,
50
- bool secstate)
51
-{
52
- bool priv = arm_current_el(env) != 0;
53
-
54
- return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
55
-}
56
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate);
57
58
/* Determine the current mmu_idx to use for normal loads/stores */
59
-static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
60
-{
61
- int el = arm_current_el(env);
62
-
63
- if (arm_feature(env, ARM_FEATURE_M)) {
64
- ARMMMUIdx mmu_idx = arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
65
-
66
- return arm_to_core_mmu_idx(mmu_idx);
67
- }
68
-
69
- if (el < 2 && arm_is_secure_below_el3(env)) {
70
- return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el);
71
- }
72
- return el;
73
-}
74
+int cpu_mmu_index(CPUARMState *env, bool ifetch);
75
76
/* Indexes used when registering address spaces with cpu_address_space_init */
77
typedef enum ARMASIdx {
78
diff --git a/target/arm/helper.c b/target/arm/helper.c
79
index XXXXXXX..XXXXXXX 100644
115
index XXXXXXX..XXXXXXX 100644
80
--- a/target/arm/helper.c
116
--- a/target/arm/translate.c
81
+++ b/target/arm/helper.c
117
+++ b/target/arm/translate.c
82
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
118
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
83
return 0;
119
a64_translate_init();
84
}
120
}
85
121
86
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
122
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
87
+ bool secstate, bool priv)
88
+{
123
+{
89
+ ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
124
+ /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
125
+ switch (cmode) {
126
+ case 0: case 1:
127
+ /* no-op */
128
+ break;
129
+ case 2: case 3:
130
+ imm <<= 8;
131
+ break;
132
+ case 4: case 5:
133
+ imm <<= 16;
134
+ break;
135
+ case 6: case 7:
136
+ imm <<= 24;
137
+ break;
138
+ case 8: case 9:
139
+ imm |= imm << 16;
140
+ break;
141
+ case 10: case 11:
142
+ imm = (imm << 8) | (imm << 24);
143
+ break;
144
+ case 12:
145
+ imm = (imm << 8) | 0xff;
146
+ break;
147
+ case 13:
148
+ imm = (imm << 16) | 0xffff;
149
+ break;
150
+ case 14:
151
+ if (op) {
152
+ /*
153
+ * This is the only case where the top and bottom 32 bits
154
+ * of the encoded constant differ.
155
+ */
156
+ uint64_t imm64 = 0;
157
+ int n;
90
+
158
+
91
+ if (priv) {
159
+ for (n = 0; n < 8; n++) {
92
+ mmu_idx |= ARM_MMU_IDX_M_PRIV;
160
+ if (imm & (1 << n)) {
161
+ imm64 |= (0xffULL << (n * 8));
162
+ }
163
+ }
164
+ return imm64;
165
+ }
166
+ imm |= (imm << 8) | (imm << 16) | (imm << 24);
167
+ break;
168
+ case 15:
169
+ imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
170
+ | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
171
+ break;
93
+ }
172
+ }
94
+
173
+ if (op) {
95
+ if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
174
+ imm = ~imm;
96
+ mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
97
+ }
175
+ }
98
+
176
+ return dup_const(MO_32, imm);
99
+ if (secstate) {
100
+ mmu_idx |= ARM_MMU_IDX_M_S;
101
+ }
102
+
103
+ return mmu_idx;
104
+}
177
+}
105
+
178
+
106
+/* Return the MMU index for a v7M CPU in the specified security state */
179
/* Generate a label used for skipping this instruction */
107
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
180
void arm_gen_condlabel(DisasContext *s)
108
+{
109
+ bool priv = arm_current_el(env) != 0;
110
+
111
+ return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
112
+}
113
+
114
+int cpu_mmu_index(CPUARMState *env, bool ifetch)
115
+{
116
+ int el = arm_current_el(env);
117
+
118
+ if (arm_feature(env, ARM_FEATURE_M)) {
119
+ ARMMMUIdx mmu_idx = arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
120
+
121
+ return arm_to_core_mmu_idx(mmu_idx);
122
+ }
123
+
124
+ if (el < 2 && arm_is_secure_below_el3(env)) {
125
+ return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el);
126
+ }
127
+ return el;
128
+}
129
+
130
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
131
target_ulong *cs_base, uint32_t *pflags)
132
{
181
{
133
--
182
--
134
2.20.1
183
2.20.1
135
184
136
185
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The A64 AdvSIMD modified-immediate grouping uses almost the same
2
constant encoding that A32 Neon does; reuse asimd_imm_const() (to
3
which we add the AArch64-specific case for cmode 15 op 1) instead of
4
reimplementing it all.
2
5
3
Now properly signals unallocated for REV64 with SF=0.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Allows for the opcode2 field to be decoded shortly.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-5-peter.maydell@linaro.org
9
---
10
target/arm/translate.h | 3 +-
11
target/arm/translate-a64.c | 86 ++++----------------------------------
12
target/arm/translate.c | 17 +++++++-
13
3 files changed, 24 insertions(+), 82 deletions(-)
5
14
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
index XXXXXXX..XXXXXXX 100644
8
Message-id: 20190108223129.5570-8-richard.henderson@linaro.org
17
--- a/target/arm/translate.h
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
+++ b/target/arm/translate.h
10
---
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
11
target/arm/translate-a64.c | 31 ++++++++++++++++++++++---------
20
* VMVN and VBIC (when cmode < 14 && op == 1).
12
1 file changed, 22 insertions(+), 9 deletions(-)
21
*
13
22
* The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
23
- * callers must catch this.
24
+ * callers must catch this; we return the 64-bit constant value defined
25
+ * for AArch64.
26
*
27
* cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
28
* is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
31
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
32
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void handle_rev16(DisasContext *s, unsigned int sf,
33
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
19
*/
20
static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
21
{
34
{
22
- unsigned int sf, opcode, rn, rd;
35
int rd = extract32(insn, 0, 5);
23
+ unsigned int sf, opcode, opcode2, rn, rd;
36
int cmode = extract32(insn, 12, 4);
24
37
- int cmode_3_1 = extract32(cmode, 1, 3);
25
- if (extract32(insn, 29, 1) || extract32(insn, 16, 5)) {
38
- int cmode_0 = extract32(cmode, 0, 1);
26
+ if (extract32(insn, 29, 1)) {
39
int o2 = extract32(insn, 11, 1);
27
unallocated_encoding(s);
40
uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) << 5);
41
bool is_neg = extract32(insn, 29, 1);
42
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
28
return;
43
return;
29
}
44
}
30
45
31
sf = extract32(insn, 31, 1);
46
- /* See AdvSIMDExpandImm() in ARM ARM */
32
opcode = extract32(insn, 10, 6);
47
- switch (cmode_3_1) {
33
+ opcode2 = extract32(insn, 16, 5);
48
- case 0: /* Replicate(Zeros(24):imm8, 2) */
34
rn = extract32(insn, 5, 5);
49
- case 1: /* Replicate(Zeros(16):imm8:Zeros(8), 2) */
35
rd = extract32(insn, 0, 5);
50
- case 2: /* Replicate(Zeros(8):imm8:Zeros(16), 2) */
36
51
- case 3: /* Replicate(imm8:Zeros(24), 2) */
37
- switch (opcode) {
52
- {
38
- case 0: /* RBIT */
53
- int shift = cmode_3_1 * 8;
39
+#define MAP(SF, O2, O1) ((SF) | (O1 << 1) | (O2 << 7))
54
- imm = bitfield_replicate(abcdefgh << shift, 32);
40
+
55
- break;
41
+ switch (MAP(sf, opcode2, opcode)) {
56
- }
42
+ case MAP(0, 0x00, 0x00): /* RBIT */
57
- case 4: /* Replicate(Zeros(8):imm8, 4) */
43
+ case MAP(1, 0x00, 0x00):
58
- case 5: /* Replicate(imm8:Zeros(8), 4) */
44
handle_rbit(s, sf, rn, rd);
59
- {
60
- int shift = (cmode_3_1 & 0x1) * 8;
61
- imm = bitfield_replicate(abcdefgh << shift, 16);
62
- break;
63
- }
64
- case 6:
65
- if (cmode_0) {
66
- /* Replicate(Zeros(8):imm8:Ones(16), 2) */
67
- imm = (abcdefgh << 16) | 0xffff;
68
- } else {
69
- /* Replicate(Zeros(16):imm8:Ones(8), 2) */
70
- imm = (abcdefgh << 8) | 0xff;
71
- }
72
- imm = bitfield_replicate(imm, 32);
73
- break;
74
- case 7:
75
- if (!cmode_0 && !is_neg) {
76
- imm = bitfield_replicate(abcdefgh, 8);
77
- } else if (!cmode_0 && is_neg) {
78
- int i;
79
- imm = 0;
80
- for (i = 0; i < 8; i++) {
81
- if ((abcdefgh) & (1 << i)) {
82
- imm |= 0xffULL << (i * 8);
83
- }
84
- }
85
- } else if (cmode_0) {
86
- if (is_neg) {
87
- imm = (abcdefgh & 0x3f) << 48;
88
- if (abcdefgh & 0x80) {
89
- imm |= 0x8000000000000000ULL;
90
- }
91
- if (abcdefgh & 0x40) {
92
- imm |= 0x3fc0000000000000ULL;
93
- } else {
94
- imm |= 0x4000000000000000ULL;
95
- }
96
- } else {
97
- if (o2) {
98
- /* FMOV (vector, immediate) - half-precision */
99
- imm = vfp_expand_imm(MO_16, abcdefgh);
100
- /* now duplicate across the lanes */
101
- imm = bitfield_replicate(imm, 16);
102
- } else {
103
- imm = (abcdefgh & 0x3f) << 19;
104
- if (abcdefgh & 0x80) {
105
- imm |= 0x80000000;
106
- }
107
- if (abcdefgh & 0x40) {
108
- imm |= 0x3e000000;
109
- } else {
110
- imm |= 0x40000000;
111
- }
112
- imm |= (imm << 32);
113
- }
114
- }
115
- }
116
- break;
117
- default:
118
- g_assert_not_reached();
119
- }
120
-
121
- if (cmode_3_1 != 7 && is_neg) {
122
- imm = ~imm;
123
+ if (cmode == 15 && o2 && !is_neg) {
124
+ /* FMOV (vector, immediate) - half-precision */
125
+ imm = vfp_expand_imm(MO_16, abcdefgh);
126
+ /* now duplicate across the lanes */
127
+ imm = bitfield_replicate(imm, 16);
128
+ } else {
129
+ imm = asimd_imm_const(abcdefgh, cmode, is_neg);
130
}
131
132
if (!((cmode & 0x9) == 0x1 || (cmode & 0xd) == 0x9)) {
133
diff --git a/target/arm/translate.c b/target/arm/translate.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/target/arm/translate.c
136
+++ b/target/arm/translate.c
137
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
138
case 14:
139
if (op) {
140
/*
141
- * This is the only case where the top and bottom 32 bits
142
- * of the encoded constant differ.
143
+ * This and cmode == 15 op == 1 are the only cases where
144
+ * the top and bottom 32 bits of the encoded constant differ.
145
*/
146
uint64_t imm64 = 0;
147
int n;
148
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
149
imm |= (imm << 8) | (imm << 16) | (imm << 24);
45
break;
150
break;
46
- case 1: /* REV16 */
151
case 15:
47
+ case MAP(0, 0x00, 0x01): /* REV16 */
152
+ if (op) {
48
+ case MAP(1, 0x00, 0x01):
153
+ /* Reserved encoding for AArch32; valid for AArch64 */
49
handle_rev16(s, sf, rn, rd);
154
+ uint64_t imm64 = (uint64_t)(imm & 0x3f) << 48;
155
+ if (imm & 0x80) {
156
+ imm64 |= 0x8000000000000000ULL;
157
+ }
158
+ if (imm & 0x40) {
159
+ imm64 |= 0x3fc0000000000000ULL;
160
+ } else {
161
+ imm64 |= 0x4000000000000000ULL;
162
+ }
163
+ return imm64;
164
+ }
165
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
166
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
50
break;
167
break;
51
- case 2: /* REV32 */
52
+ case MAP(0, 0x00, 0x02): /* REV/REV32 */
53
+ case MAP(1, 0x00, 0x02):
54
handle_rev32(s, sf, rn, rd);
55
break;
56
- case 3: /* REV64 */
57
+ case MAP(1, 0x00, 0x03): /* REV64 */
58
handle_rev64(s, sf, rn, rd);
59
break;
60
- case 4: /* CLZ */
61
+ case MAP(0, 0x00, 0x04): /* CLZ */
62
+ case MAP(1, 0x00, 0x04):
63
handle_clz(s, sf, rn, rd);
64
break;
65
- case 5: /* CLS */
66
+ case MAP(0, 0x00, 0x05): /* CLS */
67
+ case MAP(1, 0x00, 0x05):
68
handle_cls(s, sf, rn, rd);
69
break;
70
+ default:
71
+ unallocated_encoding(s);
72
+ break;
73
}
74
+
75
+#undef MAP
76
}
77
78
static void handle_div(DisasContext *s, bool is_signed, unsigned int sf,
79
--
168
--
80
2.20.1
169
2.20.1
81
170
82
171
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Use dup_const() instead of bitfield_replicate() in
2
disas_simd_mod_imm().
2
3
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
(We can't replace the other use of bitfield_replicate() in this file,
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
in logic_imm_decode_wmask(), because that location needs to handle 2
5
Message-id: 20190108223129.5570-10-richard.henderson@linaro.org
6
and 4 bit elements, which dup_const() cannot.)
7
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210628135835.6690-6-peter.maydell@linaro.org
7
---
11
---
8
target/arm/translate-a64.c | 8 ++++++++
12
target/arm/translate-a64.c | 2 +-
9
1 file changed, 8 insertions(+)
13
1 file changed, 1 insertion(+), 1 deletion(-)
10
14
11
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
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
17
--- a/target/arm/translate-a64.c
14
+++ b/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
15
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
16
case 11: /* RORV */
20
/* FMOV (vector, immediate) - half-precision */
17
handle_shift_reg(s, A64_SHIFT_TYPE_ROR, sf, rm, rn, rd);
21
imm = vfp_expand_imm(MO_16, abcdefgh);
18
break;
22
/* now duplicate across the lanes */
19
+ case 12: /* PACGA */
23
- imm = bitfield_replicate(imm, 16);
20
+ if (sf == 0 || !dc_isar_feature(aa64_pauth, s)) {
24
+ imm = dup_const(MO_16, imm);
21
+ goto do_unallocated;
25
} else {
22
+ }
26
imm = asimd_imm_const(abcdefgh, cmode, is_neg);
23
+ gen_helper_pacga(cpu_reg(s, rd), cpu_env,
24
+ cpu_reg(s, rn), cpu_reg_sp(s, rm));
25
+ break;
26
case 16:
27
case 17:
28
case 18:
29
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
30
break;
31
}
32
default:
33
+ do_unallocated:
34
unallocated_encoding(s);
35
break;
36
}
27
}
37
--
28
--
38
2.20.1
29
2.20.1
39
30
40
31
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
Implement the MVE logical-immediate insns (VMOV, VMVN,
2
VORR and VBIC). These have essentially the same encoding
3
as their Neon equivalents, and we implement the decode
4
in the same way.
2
5
3
Because of the PMU's design, many register accesses have side effects
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
which are inter-related, meaning that the normal method of saving CP
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
registers can result in inconsistent state. These side-effects are
8
Message-id: 20210628135835.6690-7-peter.maydell@linaro.org
6
largely handled in pmu_op_start/finish functions which can be called
9
---
7
before and after the state is saved/restored. By doing this and adding
10
target/arm/helper-mve.h | 4 +++
8
raw read/write functions for the affected registers, we avoid
11
target/arm/mve.decode | 17 +++++++++++++
9
migration-related inconsistencies.
12
target/arm/mve_helper.c | 24 ++++++++++++++++++
13
target/arm/translate-mve.c | 50 ++++++++++++++++++++++++++++++++++++++
14
4 files changed, 95 insertions(+)
10
15
11
Signed-off-by: Aaron Lindsay <aclindsa@gmail.com>
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
12
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20181211151945.29137-4-aaron@os.amperecomputing.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/helper.c | 6 ++++--
18
target/arm/machine.c | 24 ++++++++++++++++++++++++
19
2 files changed, 28 insertions(+), 2 deletions(-)
20
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper.c
18
--- a/target/arm/helper-mve.h
24
+++ b/target/arm/helper.c
19
+++ b/target/arm/helper-mve.h
25
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvsh, TCG_CALL_NO_WG, i32, env, ptr, i32)
26
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 0,
21
DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
27
.access = PL0_RW, .accessfn = pmreg_access_ccntr,
22
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
28
.type = ARM_CP_IO,
23
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
29
- .readfn = pmccntr_read, .writefn = pmccntr_write, },
24
+
30
+ .fieldoffset = offsetof(CPUARMState, cp15.c15_ccnt),
25
+DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
31
+ .readfn = pmccntr_read, .writefn = pmccntr_write,
26
+DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
32
+ .raw_readfn = raw_read, .raw_writefn = raw_write, },
27
+DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
33
#endif
28
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
34
{ .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
35
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
36
- .writefn = pmccfiltr_write,
37
+ .writefn = pmccfiltr_write, .raw_writefn = raw_write,
38
.access = PL0_RW, .accessfn = pmreg_access,
39
.type = ARM_CP_IO,
40
.fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0),
41
diff --git a/target/arm/machine.c b/target/arm/machine.c
42
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/machine.c
30
--- a/target/arm/mve.decode
44
+++ b/target/arm/machine.c
31
+++ b/target/arm/mve.decode
45
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
32
@@ -XXX,XX +XXX,XX @@
46
{
33
# VQDMULL has size in bit 28: 0 for 16 bit, 1 for 32 bit
47
ARMCPU *cpu = opaque;
34
%size_28 28:1 !function=plus_1
48
35
49
+ if (!kvm_enabled()) {
36
+# 1imm format immediate
50
+ pmu_op_start(&cpu->env);
37
+%imm_28_16_0 28:1 16:3 0:4
38
+
39
&vldr_vstr rn qd imm p a w size l u
40
&1op qd qm size
41
&2op qd qm qn size
42
&2scalar qd qn rm size
43
+&1imm qd imm cmode op
44
45
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
46
# Note that both Rn and Qd are 3 bits only (no D bit)
47
@@ -XXX,XX +XXX,XX @@
48
@2op_nosz .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn size=0
49
@2op_sz28 .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn \
50
size=%size_28
51
+@1imm .... .... .... .... .... cmode:4 .. op:1 . .... &1imm qd=%qd imm=%imm_28_16_0
52
53
# The _rev suffix indicates that Vn and Vm are reversed. This is
54
# the case for shifts. In the Arm ARM these insns are documented
55
@@ -XXX,XX +XXX,XX @@ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rd
56
# Predicate operations
57
%mask_22_13 22:1 13:3
58
VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
59
+
60
+# Logical immediate operations (1 reg and modified-immediate)
61
+
62
+# The cmode/op bits here decode VORR/VBIC/VMOV/VMVN, but
63
+# not in a way we can conveniently represent in decodetree without
64
+# a lot of repetition:
65
+# VORR: op=0, (cmode & 1) && cmode < 12
66
+# VBIC: op=1, (cmode & 1) && cmode < 12
67
+# VMOV: everything else
68
+# So we have a single decode line and check the cmode/op in the
69
+# trans function.
70
+Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
71
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/mve_helper.c
74
+++ b/target/arm/mve_helper.c
75
@@ -XXX,XX +XXX,XX @@ DO_1OP(vnegw, 4, int32_t, DO_NEG)
76
DO_1OP(vfnegh, 8, uint64_t, DO_FNEGH)
77
DO_1OP(vfnegs, 8, uint64_t, DO_FNEGS)
78
79
+/*
80
+ * 1 operand immediates: Vda is destination and possibly also one source.
81
+ * All these insns work at 64-bit widths.
82
+ */
83
+#define DO_1OP_IMM(OP, FN) \
84
+ void HELPER(mve_##OP)(CPUARMState *env, void *vda, uint64_t imm) \
85
+ { \
86
+ uint64_t *da = vda; \
87
+ uint16_t mask = mve_element_mask(env); \
88
+ unsigned e; \
89
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
90
+ mergemask(&da[H8(e)], FN(da[H8(e)], imm), mask); \
91
+ } \
92
+ mve_advance_vpt(env); \
51
+ }
93
+ }
52
+
94
+
53
if (kvm_enabled()) {
95
+#define DO_MOVI(N, I) (I)
54
if (!write_kvmstate_to_list(cpu)) {
96
+#define DO_ANDI(N, I) ((N) & (I))
55
/* This should never fail */
97
+#define DO_ORRI(N, I) ((N) | (I))
56
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
98
+
57
return 0;
99
+DO_1OP_IMM(vmovi, DO_MOVI)
100
+DO_1OP_IMM(vandi, DO_ANDI)
101
+DO_1OP_IMM(vorri, DO_ORRI)
102
+
103
#define DO_2OP(OP, ESIZE, TYPE, FN) \
104
void HELPER(glue(mve_, OP))(CPUARMState *env, \
105
void *vd, void *vn, void *vm) \
106
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate-mve.c
109
+++ b/target/arm/translate-mve.c
110
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
111
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
112
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
113
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
114
+typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
115
116
/* Return the offset of a Qn register (same semantics as aa32_vfp_qreg()) */
117
static inline long mve_qreg_offset(unsigned reg)
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
119
mve_update_eci(s);
120
return true;
58
}
121
}
59
122
+
60
+static int cpu_post_save(void *opaque)
123
+static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
61
+{
124
+{
62
+ ARMCPU *cpu = opaque;
125
+ TCGv_ptr qd;
126
+ uint64_t imm;
63
+
127
+
64
+ if (!kvm_enabled()) {
128
+ if (!dc_isar_feature(aa32_mve, s) ||
65
+ pmu_op_finish(&cpu->env);
129
+ !mve_check_qreg_bank(s, a->qd) ||
130
+ !fn) {
131
+ return false;
132
+ }
133
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
134
+ return true;
66
+ }
135
+ }
67
+
136
+
68
+ return 0;
137
+ imm = asimd_imm_const(a->imm, a->cmode, a->op);
138
+
139
+ qd = mve_qreg_ptr(a->qd);
140
+ fn(cpu_env, qd, tcg_constant_i64(imm));
141
+ tcg_temp_free_ptr(qd);
142
+ mve_update_eci(s);
143
+ return true;
69
+}
144
+}
70
+
145
+
71
static int cpu_pre_load(void *opaque)
146
+static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
72
{
147
+{
73
ARMCPU *cpu = opaque;
148
+ /* Handle decode of cmode/op here between VORR/VBIC/VMOV */
74
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_load(void *opaque)
149
+ MVEGenOneOpImmFn *fn;
75
*/
150
+
76
env->irq_line_state = UINT32_MAX;
151
+ if ((a->cmode & 1) && a->cmode < 12) {
77
152
+ if (a->op) {
78
+ if (!kvm_enabled()) {
153
+ /*
79
+ pmu_op_start(&cpu->env);
154
+ * For op=1, the immediate will be inverted by asimd_imm_const(),
155
+ * so the VBIC becomes a logical AND operation.
156
+ */
157
+ fn = gen_helper_mve_vandi;
158
+ } else {
159
+ fn = gen_helper_mve_vorri;
160
+ }
161
+ } else {
162
+ /* There is one unallocated cmode/op combination in this space */
163
+ if (a->cmode == 15 && a->op == 1) {
164
+ return false;
165
+ }
166
+ /* asimd_imm_const() sorts out VMVNI vs VMOVI for us */
167
+ fn = gen_helper_mve_vmovi;
80
+ }
168
+ }
81
+
169
+ return do_1imm(s, a, fn);
82
return 0;
170
+}
83
}
84
85
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
86
hw_breakpoint_update_all(cpu);
87
hw_watchpoint_update_all(cpu);
88
89
+ if (!kvm_enabled()) {
90
+ pmu_op_finish(&cpu->env);
91
+ }
92
+
93
return 0;
94
}
95
96
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_arm_cpu = {
97
.version_id = 22,
98
.minimum_version_id = 22,
99
.pre_save = cpu_pre_save,
100
+ .post_save = cpu_post_save,
101
.pre_load = cpu_pre_load,
102
.post_load = cpu_post_load,
103
.fields = (VMStateField[]) {
104
--
171
--
105
2.20.1
172
2.20.1
106
173
107
174
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE shift-vector-left-by-immediate insns VSHL, VQSHL
2
2
and VQSHLU.
3
Split out functions to extract the virtual address parameters.
3
4
Let the functions choose T0 or T1 address space half, if present.
4
The size-and-immediate encoding here is the same as Neon, and we
5
Extract (most of) the control bits that vary between EL or Tx.
5
handle it the same way neon-dp.decode does.
6
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20190108223129.5570-19-richard.henderson@linaro.org
10
[PMM: fixed minor checkpatch comment nits]
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210628135835.6690-8-peter.maydell@linaro.org
12
---
10
---
13
target/arm/internals.h | 14 +++
11
target/arm/helper-mve.h | 16 +++++++++++
14
target/arm/helper.c | 278 ++++++++++++++++++++++-------------------
12
target/arm/mve.decode | 23 +++++++++++++++
15
2 files changed, 164 insertions(+), 128 deletions(-)
13
target/arm/mve_helper.c | 57 ++++++++++++++++++++++++++++++++++++++
16
14
target/arm/translate-mve.c | 51 ++++++++++++++++++++++++++++++++++
17
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
4 files changed, 147 insertions(+)
18
index XXXXXXX..XXXXXXX 100644
16
19
--- a/target/arm/internals.h
17
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
20
+++ b/target/arm/internals.h
18
index XXXXXXX..XXXXXXX 100644
21
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
19
--- a/target/arm/helper-mve.h
22
ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env);
20
+++ b/target/arm/helper-mve.h
23
#endif
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
24
22
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
25
+/*
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
26
+ * Parameters of a given virtual address, as extracted from the
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
27
+ * translation control register (TCR) for a given regime.
25
+
28
+ */
26
+DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+typedef struct ARMVAParameters {
27
+DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+ unsigned tsz : 8;
28
+DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+ unsigned select : 1;
29
+
32
+ bool tbi : 1;
30
+DEF_HELPER_FLAGS_4(mve_vqshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+ bool epd : 1;
31
+DEF_HELPER_FLAGS_4(mve_vqshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
+ bool hpd : 1;
32
+DEF_HELPER_FLAGS_4(mve_vqshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
+ bool using16k : 1;
33
+
36
+ bool using64k : 1;
34
+DEF_HELPER_FLAGS_4(mve_vqshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+} ARMVAParameters;
35
+DEF_HELPER_FLAGS_4(mve_vqshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
+
36
+DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
#endif
37
+
40
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
+DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
index XXXXXXX..XXXXXXX 100644
39
+DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
42
--- a/target/arm/helper.c
40
+DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+++ b/target/arm/helper.c
41
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
44
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
42
index XXXXXXX..XXXXXXX 100644
45
return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
43
--- a/target/arm/mve.decode
44
+++ b/target/arm/mve.decode
45
@@ -XXX,XX +XXX,XX @@
46
&2op qd qm qn size
47
&2scalar qd qn rm size
48
&1imm qd imm cmode op
49
+&2shift qd qm shift size
50
51
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
52
# Note that both Rn and Qd are 3 bits only (no D bit)
53
@@ -XXX,XX +XXX,XX @@
54
@2scalar .... .... .. size:2 .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
55
@2scalar_nosz .... .... .... .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
56
57
+@2_shl_b .... .... .. 001 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
58
+@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
59
+@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
60
+
61
# Vector loads and stores
62
63
# Widening loads and narrowing stores:
64
@@ -XXX,XX +XXX,XX @@ VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
65
# So we have a single decode line and check the cmode/op in the
66
# trans function.
67
Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
68
+
69
+# Shifts by immediate
70
+
71
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
72
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
73
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
74
+
75
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
76
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
77
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
78
+
79
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
80
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
81
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
82
+
83
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
84
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
85
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
86
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/arm/mve_helper.c
89
+++ b/target/arm/mve_helper.c
90
@@ -XXX,XX +XXX,XX @@ DO_2OP_SAT(vqsubsw, 4, int32_t, DO_SQSUB_W)
91
WRAP_QRSHL_HELPER(do_sqrshl_bhs, N, M, true, satp)
92
#define DO_UQRSHL_OP(N, M, satp) \
93
WRAP_QRSHL_HELPER(do_uqrshl_bhs, N, M, true, satp)
94
+#define DO_SUQSHL_OP(N, M, satp) \
95
+ WRAP_QRSHL_HELPER(do_suqrshl_bhs, N, M, false, satp)
96
97
DO_2OP_SAT_S(vqshls, DO_SQSHL_OP)
98
DO_2OP_SAT_U(vqshlu, DO_UQSHL_OP)
99
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvsw, 4, uint32_t)
100
DO_VADDV(vaddvub, 1, uint8_t)
101
DO_VADDV(vaddvuh, 2, uint16_t)
102
DO_VADDV(vaddvuw, 4, uint32_t)
103
+
104
+/* Shifts by immediate */
105
+#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
106
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
107
+ void *vm, uint32_t shift) \
108
+ { \
109
+ TYPE *d = vd, *m = vm; \
110
+ uint16_t mask = mve_element_mask(env); \
111
+ unsigned e; \
112
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
113
+ mergemask(&d[H##ESIZE(e)], \
114
+ FN(m[H##ESIZE(e)], shift), mask); \
115
+ } \
116
+ mve_advance_vpt(env); \
117
+ }
118
+
119
+#define DO_2SHIFT_SAT(OP, ESIZE, TYPE, FN) \
120
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
121
+ void *vm, uint32_t shift) \
122
+ { \
123
+ TYPE *d = vd, *m = vm; \
124
+ uint16_t mask = mve_element_mask(env); \
125
+ unsigned e; \
126
+ bool qc = false; \
127
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
128
+ bool sat = false; \
129
+ mergemask(&d[H##ESIZE(e)], \
130
+ FN(m[H##ESIZE(e)], shift, &sat), mask); \
131
+ qc |= sat & mask & 1; \
132
+ } \
133
+ if (qc) { \
134
+ env->vfp.qc[0] = qc; \
135
+ } \
136
+ mve_advance_vpt(env); \
137
+ }
138
+
139
+/* provide unsigned 2-op shift helpers for all sizes */
140
+#define DO_2SHIFT_U(OP, FN) \
141
+ DO_2SHIFT(OP##b, 1, uint8_t, FN) \
142
+ DO_2SHIFT(OP##h, 2, uint16_t, FN) \
143
+ DO_2SHIFT(OP##w, 4, uint32_t, FN)
144
+
145
+#define DO_2SHIFT_SAT_U(OP, FN) \
146
+ DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
147
+ DO_2SHIFT_SAT(OP##h, 2, uint16_t, FN) \
148
+ DO_2SHIFT_SAT(OP##w, 4, uint32_t, FN)
149
+#define DO_2SHIFT_SAT_S(OP, FN) \
150
+ DO_2SHIFT_SAT(OP##b, 1, int8_t, FN) \
151
+ DO_2SHIFT_SAT(OP##h, 2, int16_t, FN) \
152
+ DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
153
+
154
+DO_2SHIFT_U(vshli_u, DO_VSHLU)
155
+DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
156
+DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
157
+DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
158
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/target/arm/translate-mve.c
161
+++ b/target/arm/translate-mve.c
162
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenLdStFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
163
typedef void MVEGenOneOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
164
typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
165
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
166
+typedef void MVEGenTwoOpShiftFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
167
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
168
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
169
typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
170
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
171
}
172
return do_1imm(s, a, fn);
46
}
173
}
47
174
+
48
+static ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
175
+static bool do_2shift(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
49
+ ARMMMUIdx mmu_idx, bool data)
176
+ bool negateshift)
50
+{
177
+{
51
+ uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
178
+ TCGv_ptr qd, qm;
52
+ uint32_t el = regime_el(env, mmu_idx);
179
+ int shift = a->shift;
53
+ bool tbi, epd, hpd, using16k, using64k;
180
+
54
+ int select, tsz;
181
+ if (!dc_isar_feature(aa32_mve, s) ||
182
+ !mve_check_qreg_bank(s, a->qd | a->qm) ||
183
+ !fn) {
184
+ return false;
185
+ }
186
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
187
+ return true;
188
+ }
55
+
189
+
56
+ /*
190
+ /*
57
+ * Bit 55 is always between the two regions, and is canonical for
191
+ * When we handle a right shift insn using a left-shift helper
58
+ * determining if address tagging is enabled.
192
+ * which permits a negative shift count to indicate a right-shift,
193
+ * we must negate the shift count.
59
+ */
194
+ */
60
+ select = extract64(va, 55, 1);
195
+ if (negateshift) {
61
+
196
+ shift = -shift;
62
+ if (el > 1) {
197
+ }
63
+ tsz = extract32(tcr, 0, 6);
198
+
64
+ using64k = extract32(tcr, 14, 1);
199
+ qd = mve_qreg_ptr(a->qd);
65
+ using16k = extract32(tcr, 15, 1);
200
+ qm = mve_qreg_ptr(a->qm);
66
+ if (mmu_idx == ARMMMUIdx_S2NS) {
201
+ fn(cpu_env, qd, qm, tcg_constant_i32(shift));
67
+ /* VTCR_EL2 */
202
+ tcg_temp_free_ptr(qd);
68
+ tbi = hpd = false;
203
+ tcg_temp_free_ptr(qm);
69
+ } else {
204
+ mve_update_eci(s);
70
+ tbi = extract32(tcr, 20, 1);
205
+ return true;
71
+ hpd = extract32(tcr, 24, 1);
72
+ }
73
+ epd = false;
74
+ } else if (!select) {
75
+ tsz = extract32(tcr, 0, 6);
76
+ epd = extract32(tcr, 7, 1);
77
+ using64k = extract32(tcr, 14, 1);
78
+ using16k = extract32(tcr, 15, 1);
79
+ tbi = extract64(tcr, 37, 1);
80
+ hpd = extract64(tcr, 41, 1);
81
+ } else {
82
+ int tg = extract32(tcr, 30, 2);
83
+ using16k = tg == 1;
84
+ using64k = tg == 3;
85
+ tsz = extract32(tcr, 16, 6);
86
+ epd = extract32(tcr, 23, 1);
87
+ tbi = extract64(tcr, 38, 1);
88
+ hpd = extract64(tcr, 42, 1);
89
+ }
90
+ tsz = MIN(tsz, 39); /* TODO: ARMv8.4-TTST */
91
+ tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
92
+
93
+ return (ARMVAParameters) {
94
+ .tsz = tsz,
95
+ .select = select,
96
+ .tbi = tbi,
97
+ .epd = epd,
98
+ .hpd = hpd,
99
+ .using16k = using16k,
100
+ .using64k = using64k,
101
+ };
102
+}
206
+}
103
+
207
+
104
+static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
208
+#define DO_2SHIFT(INSN, FN, NEGATESHIFT) \
105
+ ARMMMUIdx mmu_idx)
209
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
106
+{
210
+ { \
107
+ uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
211
+ static MVEGenTwoOpShiftFn * const fns[] = { \
108
+ uint32_t el = regime_el(env, mmu_idx);
212
+ gen_helper_mve_##FN##b, \
109
+ int select, tsz;
213
+ gen_helper_mve_##FN##h, \
110
+ bool epd, hpd;
214
+ gen_helper_mve_##FN##w, \
111
+
215
+ NULL, \
112
+ if (mmu_idx == ARMMMUIdx_S2NS) {
216
+ }; \
113
+ /* VTCR */
217
+ return do_2shift(s, a, fns[a->size], NEGATESHIFT); \
114
+ bool sext = extract32(tcr, 4, 1);
218
+ }
115
+ bool sign = extract32(tcr, 3, 1);
219
+
116
+
220
+DO_2SHIFT(VSHLI, vshli_u, false)
117
+ /*
221
+DO_2SHIFT(VQSHLI_S, vqshli_s, false)
118
+ * If the sign-extend bit is not the same as t0sz[3], the result
222
+DO_2SHIFT(VQSHLI_U, vqshli_u, false)
119
+ * is unpredictable. Flag this as a guest error.
223
+DO_2SHIFT(VQSHLUI, vqshlui_s, false)
120
+ */
121
+ if (sign != sext) {
122
+ qemu_log_mask(LOG_GUEST_ERROR,
123
+ "AArch32: VTCR.S / VTCR.T0SZ[3] mismatch\n");
124
+ }
125
+ tsz = sextract32(tcr, 0, 4) + 8;
126
+ select = 0;
127
+ hpd = false;
128
+ epd = false;
129
+ } else if (el == 2) {
130
+ /* HTCR */
131
+ tsz = extract32(tcr, 0, 3);
132
+ select = 0;
133
+ hpd = extract64(tcr, 24, 1);
134
+ epd = false;
135
+ } else {
136
+ int t0sz = extract32(tcr, 0, 3);
137
+ int t1sz = extract32(tcr, 16, 3);
138
+
139
+ if (t1sz == 0) {
140
+ select = va > (0xffffffffu >> t0sz);
141
+ } else {
142
+ /* Note that we will detect errors later. */
143
+ select = va >= ~(0xffffffffu >> t1sz);
144
+ }
145
+ if (!select) {
146
+ tsz = t0sz;
147
+ epd = extract32(tcr, 7, 1);
148
+ hpd = extract64(tcr, 41, 1);
149
+ } else {
150
+ tsz = t1sz;
151
+ epd = extract32(tcr, 23, 1);
152
+ hpd = extract64(tcr, 42, 1);
153
+ }
154
+ /* For aarch32, hpd0 is not enabled without t2e as well. */
155
+ hpd &= extract32(tcr, 6, 1);
156
+ }
157
+
158
+ return (ARMVAParameters) {
159
+ .tsz = tsz,
160
+ .select = select,
161
+ .epd = epd,
162
+ .hpd = hpd,
163
+ };
164
+}
165
+
166
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
167
MMUAccessType access_type, ARMMMUIdx mmu_idx,
168
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
169
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
170
/* Read an LPAE long-descriptor translation table. */
171
ARMFaultType fault_type = ARMFault_Translation;
172
uint32_t level;
173
- uint32_t epd = 0;
174
- int32_t t0sz, t1sz;
175
- uint32_t tg;
176
+ ARMVAParameters param;
177
uint64_t ttbr;
178
- int ttbr_select;
179
hwaddr descaddr, indexmask, indexmask_grainsize;
180
uint32_t tableattrs;
181
- target_ulong page_size;
182
+ target_ulong page_size, top_bits;
183
uint32_t attrs;
184
- int32_t stride = 9;
185
- int32_t addrsize;
186
- int inputsize;
187
- int32_t tbi = 0;
188
+ int32_t stride;
189
+ int addrsize, inputsize;
190
TCR *tcr = regime_tcr(env, mmu_idx);
191
int ap, ns, xn, pxn;
192
uint32_t el = regime_el(env, mmu_idx);
193
- bool ttbr1_valid = true;
194
+ bool ttbr1_valid;
195
uint64_t descaddrmask;
196
bool aarch64 = arm_el_is_aa64(env, el);
197
- bool hpd = false;
198
199
/* TODO:
200
* This code does not handle the different format TCR for VTCR_EL2.
201
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
202
* support for those page table walks.
203
*/
204
if (aarch64) {
205
+ param = aa64_va_parameters(env, address, mmu_idx,
206
+ access_type != MMU_INST_FETCH);
207
level = 0;
208
- addrsize = 64;
209
- if (el > 1) {
210
- if (mmu_idx != ARMMMUIdx_S2NS) {
211
- tbi = extract64(tcr->raw_tcr, 20, 1);
212
- }
213
- } else {
214
- if (extract64(address, 55, 1)) {
215
- tbi = extract64(tcr->raw_tcr, 38, 1);
216
- } else {
217
- tbi = extract64(tcr->raw_tcr, 37, 1);
218
- }
219
- }
220
- tbi *= 8;
221
-
222
/* If we are in 64-bit EL2 or EL3 then there is no TTBR1, so mark it
223
* invalid.
224
*/
225
- if (el > 1) {
226
- ttbr1_valid = false;
227
- }
228
+ ttbr1_valid = (el < 2);
229
+ addrsize = 64 - 8 * param.tbi;
230
+ inputsize = 64 - param.tsz;
231
} else {
232
+ param = aa32_va_parameters(env, address, mmu_idx);
233
level = 1;
234
- addrsize = 32;
235
/* There is no TTBR1 for EL2 */
236
- if (el == 2) {
237
- ttbr1_valid = false;
238
- }
239
+ ttbr1_valid = (el != 2);
240
+ addrsize = (mmu_idx == ARMMMUIdx_S2NS ? 40 : 32);
241
+ inputsize = addrsize - param.tsz;
242
}
243
244
- /* Determine whether this address is in the region controlled by
245
- * TTBR0 or TTBR1 (or if it is in neither region and should fault).
246
- * This is a Non-secure PL0/1 stage 1 translation, so controlled by
247
- * TTBCR/TTBR0/TTBR1 in accordance with ARM ARM DDI0406C table B-32:
248
+ /*
249
+ * We determined the region when collecting the parameters, but we
250
+ * have not yet validated that the address is valid for the region.
251
+ * Extract the top bits and verify that they all match select.
252
*/
253
- if (aarch64) {
254
- /* AArch64 translation. */
255
- t0sz = extract32(tcr->raw_tcr, 0, 6);
256
- t0sz = MIN(t0sz, 39);
257
- t0sz = MAX(t0sz, 16);
258
- } else if (mmu_idx != ARMMMUIdx_S2NS) {
259
- /* AArch32 stage 1 translation. */
260
- t0sz = extract32(tcr->raw_tcr, 0, 3);
261
- } else {
262
- /* AArch32 stage 2 translation. */
263
- bool sext = extract32(tcr->raw_tcr, 4, 1);
264
- bool sign = extract32(tcr->raw_tcr, 3, 1);
265
- /* Address size is 40-bit for a stage 2 translation,
266
- * and t0sz can be negative (from -8 to 7),
267
- * so we need to adjust it to use the TTBR selecting logic below.
268
- */
269
- addrsize = 40;
270
- t0sz = sextract32(tcr->raw_tcr, 0, 4) + 8;
271
-
272
- /* If the sign-extend bit is not the same as t0sz[3], the result
273
- * is unpredictable. Flag this as a guest error. */
274
- if (sign != sext) {
275
- qemu_log_mask(LOG_GUEST_ERROR,
276
- "AArch32: VTCR.S / VTCR.T0SZ[3] mismatch\n");
277
- }
278
- }
279
- t1sz = extract32(tcr->raw_tcr, 16, 6);
280
- if (aarch64) {
281
- t1sz = MIN(t1sz, 39);
282
- t1sz = MAX(t1sz, 16);
283
- }
284
- if (t0sz && !extract64(address, addrsize - t0sz, t0sz - tbi)) {
285
- /* there is a ttbr0 region and we are in it (high bits all zero) */
286
- ttbr_select = 0;
287
- } else if (ttbr1_valid && t1sz &&
288
- !extract64(~address, addrsize - t1sz, t1sz - tbi)) {
289
- /* there is a ttbr1 region and we are in it (high bits all one) */
290
- ttbr_select = 1;
291
- } else if (!t0sz) {
292
- /* ttbr0 region is "everything not in the ttbr1 region" */
293
- ttbr_select = 0;
294
- } else if (!t1sz && ttbr1_valid) {
295
- /* ttbr1 region is "everything not in the ttbr0 region" */
296
- ttbr_select = 1;
297
- } else {
298
- /* in the gap between the two regions, this is a Translation fault */
299
+ top_bits = sextract64(address, inputsize, addrsize - inputsize);
300
+ if (-top_bits != param.select || (param.select && !ttbr1_valid)) {
301
+ /* In the gap between the two regions, this is a Translation fault */
302
fault_type = ARMFault_Translation;
303
goto do_fault;
304
}
305
306
+ if (param.using64k) {
307
+ stride = 13;
308
+ } else if (param.using16k) {
309
+ stride = 11;
310
+ } else {
311
+ stride = 9;
312
+ }
313
+
314
/* Note that QEMU ignores shareability and cacheability attributes,
315
* so we don't need to do anything with the SH, ORGN, IRGN fields
316
* in the TTBCR. Similarly, TTBCR:A1 selects whether we get the
317
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
318
* implement any ASID-like capability so we can ignore it (instead
319
* we will always flush the TLB any time the ASID is changed).
320
*/
321
- if (ttbr_select == 0) {
322
- ttbr = regime_ttbr(env, mmu_idx, 0);
323
- if (el < 2) {
324
- epd = extract32(tcr->raw_tcr, 7, 1);
325
- }
326
- inputsize = addrsize - t0sz;
327
-
328
- tg = extract32(tcr->raw_tcr, 14, 2);
329
- if (tg == 1) { /* 64KB pages */
330
- stride = 13;
331
- }
332
- if (tg == 2) { /* 16KB pages */
333
- stride = 11;
334
- }
335
- if (aarch64 && el > 1) {
336
- hpd = extract64(tcr->raw_tcr, 24, 1);
337
- } else {
338
- hpd = extract64(tcr->raw_tcr, 41, 1);
339
- }
340
- if (!aarch64) {
341
- /* For aarch32, hpd0 is not enabled without t2e as well. */
342
- hpd &= extract64(tcr->raw_tcr, 6, 1);
343
- }
344
- } else {
345
- /* We should only be here if TTBR1 is valid */
346
- assert(ttbr1_valid);
347
-
348
- ttbr = regime_ttbr(env, mmu_idx, 1);
349
- epd = extract32(tcr->raw_tcr, 23, 1);
350
- inputsize = addrsize - t1sz;
351
-
352
- tg = extract32(tcr->raw_tcr, 30, 2);
353
- if (tg == 3) { /* 64KB pages */
354
- stride = 13;
355
- }
356
- if (tg == 1) { /* 16KB pages */
357
- stride = 11;
358
- }
359
- hpd = extract64(tcr->raw_tcr, 42, 1);
360
- if (!aarch64) {
361
- /* For aarch32, hpd1 is not enabled without t2e as well. */
362
- hpd &= extract64(tcr->raw_tcr, 6, 1);
363
- }
364
- }
365
+ ttbr = regime_ttbr(env, mmu_idx, param.select);
366
367
/* Here we should have set up all the parameters for the translation:
368
* inputsize, ttbr, epd, stride, tbi
369
*/
370
371
- if (epd) {
372
+ if (param.epd) {
373
/* Translation table walk disabled => Translation fault on TLB miss
374
* Note: This is always 0 on 64-bit EL2 and EL3.
375
*/
376
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
377
}
378
/* Merge in attributes from table descriptors */
379
attrs |= nstable << 3; /* NS */
380
- if (hpd) {
381
+ if (param.hpd) {
382
/* HPD disables all the table attributes except NSTable. */
383
break;
384
}
385
--
224
--
386
2.20.1
225
2.20.1
387
226
388
227
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
Implement the MVE vector shift right by immediate insns VSHRI and
2
VRSHRI. As with Neon, we implement these by using helper functions
3
which perform left shifts but allow negative shift counts to indicate
4
right shifts.
2
5
3
The instruction event is only enabled when icount is used, cycles are
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
always supported. Always defining get_cycle_count (but altering its
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
behavior depending on CONFIG_USER_ONLY) allows us to remove some
8
Message-id: 20210628135835.6690-9-peter.maydell@linaro.org
6
CONFIG_USER_ONLY #defines throughout the rest of the code.
9
---
10
target/arm/helper-mve.h | 12 ++++++++++++
11
target/arm/translate.h | 20 ++++++++++++++++++++
12
target/arm/mve.decode | 28 ++++++++++++++++++++++++++++
13
target/arm/mve_helper.c | 7 +++++++
14
target/arm/translate-mve.c | 5 +++++
15
target/arm/translate-neon.c | 18 ------------------
16
6 files changed, 72 insertions(+), 18 deletions(-)
7
17
8
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
9
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20181211151945.29137-12-aaron@os.amperecomputing.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/helper.c | 90 ++++++++++++++++++++++-----------------------
15
1 file changed, 44 insertions(+), 46 deletions(-)
16
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
20
--- a/target/arm/helper-mve.h
20
+++ b/target/arm/helper.c
21
+++ b/target/arm/helper-mve.h
21
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
22
#include "arm_ldst.h"
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
23
#include <zlib.h> /* For crc32 */
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
24
#include "exec/semihost.h"
25
25
+#include "sysemu/cpus.h"
26
+DEF_HELPER_FLAGS_4(mve_vshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
#include "sysemu/kvm.h"
27
+DEF_HELPER_FLAGS_4(mve_vshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
#include "fpu/softfloat.h"
28
+DEF_HELPER_FLAGS_4(mve_vshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
#include "qemu/range.h"
29
+
29
@@ -XXX,XX +XXX,XX @@ typedef struct pm_event {
30
DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
uint64_t (*get_count)(CPUARMState *);
31
DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
} pm_event;
32
DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
33
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
+static bool event_always_supported(CPUARMState *env)
34
DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+
38
+DEF_HELPER_FLAGS_4(mve_vrshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_4(mve_vrshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
+
42
+DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
diff --git a/target/arm/translate.h b/target/arm/translate.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/translate.h
48
+++ b/target/arm/translate.h
49
@@ -XXX,XX +XXX,XX @@ static inline int times_2_plus_1(DisasContext *s, int x)
50
return x * 2 + 1;
51
}
52
53
+static inline int rsub_64(DisasContext *s, int x)
34
+{
54
+{
35
+ return true;
55
+ return 64 - x;
36
+}
56
+}
37
+
57
+
38
+/*
58
+static inline int rsub_32(DisasContext *s, int x)
39
+ * Return the underlying cycle count for the PMU cycle counters. If we're in
40
+ * usermode, simply return 0.
41
+ */
42
+static uint64_t cycles_get_count(CPUARMState *env)
43
+{
59
+{
44
+#ifndef CONFIG_USER_ONLY
60
+ return 32 - x;
45
+ return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
46
+ ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
47
+#else
48
+ return cpu_get_host_ticks();
49
+#endif
50
+}
61
+}
51
+
62
+
52
+#ifndef CONFIG_USER_ONLY
63
+static inline int rsub_16(DisasContext *s, int x)
53
+static bool instructions_supported(CPUARMState *env)
54
+{
64
+{
55
+ return use_icount == 1 /* Precise instruction counting */;
65
+ return 16 - x;
56
+}
66
+}
57
+
67
+
58
+static uint64_t instructions_get_count(CPUARMState *env)
68
+static inline int rsub_8(DisasContext *s, int x)
59
+{
69
+{
60
+ return (uint64_t)cpu_get_icount_raw();
70
+ return 8 - x;
61
+}
71
+}
62
+#endif
63
+
72
+
64
static const pm_event pm_events[] = {
73
static inline int arm_dc_feature(DisasContext *dc, int feature)
65
+#ifndef CONFIG_USER_ONLY
74
{
66
+ { .number = 0x008, /* INST_RETIRED, Instruction architecturally executed */
75
return (dc->features & (1ULL << feature)) != 0;
67
+ .supported = instructions_supported,
76
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
68
+ .get_count = instructions_get_count,
77
index XXXXXXX..XXXXXXX 100644
69
+ },
78
--- a/target/arm/mve.decode
70
+ { .number = 0x011, /* CPU_CYCLES, Cycle */
79
+++ b/target/arm/mve.decode
71
+ .supported = event_always_supported,
80
@@ -XXX,XX +XXX,XX @@
72
+ .get_count = cycles_get_count,
81
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
73
+ }
82
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
74
+#endif
83
75
};
84
+# Right shifts are encoded as N - shift, where N is the element size in bits.
76
85
+%rshift_i5 16:5 !function=rsub_32
77
/*
86
+%rshift_i4 16:4 !function=rsub_16
78
@@ -XXX,XX +XXX,XX @@ static const pm_event pm_events[] = {
87
+%rshift_i3 16:3 !function=rsub_8
79
* should first be updated to something sparse instead of the current
88
+
80
* supported_event_map[] array.
89
+@2_shr_b .... .... .. 001 ... .... .... .... .... &2shift qd=%qd qm=%qm \
81
*/
90
+ size=0 shift=%rshift_i3
82
-#define MAX_EVENT_ID 0x0
91
+@2_shr_h .... .... .. 01 .... .... .... .... .... &2shift qd=%qd qm=%qm \
83
+#define MAX_EVENT_ID 0x11
92
+ size=1 shift=%rshift_i4
84
#define UNSUPPORTED_EVENT UINT16_MAX
93
+@2_shr_w .... .... .. 1 ..... .... .... .... .... &2shift qd=%qd qm=%qm \
85
static uint16_t supported_event_map[MAX_EVENT_ID + 1];
94
+ size=2 shift=%rshift_i5
86
95
+
87
@@ -XXX,XX +XXX,XX @@ static CPAccessResult pmreg_access_swinc(CPUARMState *env,
96
# Vector loads and stores
88
return pmreg_access(env, ri, isread);
97
98
# Widening loads and narrowing stores:
99
@@ -XXX,XX +XXX,XX @@ VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
100
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
101
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
102
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
103
+
104
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
105
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
106
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
107
+
108
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
109
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
110
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
111
+
112
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
113
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
114
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
115
+
116
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
117
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
118
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
119
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/mve_helper.c
122
+++ b/target/arm/mve_helper.c
123
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
124
DO_2SHIFT(OP##b, 1, uint8_t, FN) \
125
DO_2SHIFT(OP##h, 2, uint16_t, FN) \
126
DO_2SHIFT(OP##w, 4, uint32_t, FN)
127
+#define DO_2SHIFT_S(OP, FN) \
128
+ DO_2SHIFT(OP##b, 1, int8_t, FN) \
129
+ DO_2SHIFT(OP##h, 2, int16_t, FN) \
130
+ DO_2SHIFT(OP##w, 4, int32_t, FN)
131
132
#define DO_2SHIFT_SAT_U(OP, FN) \
133
DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
134
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
135
DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
136
137
DO_2SHIFT_U(vshli_u, DO_VSHLU)
138
+DO_2SHIFT_S(vshli_s, DO_VSHLS)
139
DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
140
DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
141
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
142
+DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
143
+DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
144
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/target/arm/translate-mve.c
147
+++ b/target/arm/translate-mve.c
148
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHLI, vshli_u, false)
149
DO_2SHIFT(VQSHLI_S, vqshli_s, false)
150
DO_2SHIFT(VQSHLI_U, vqshli_u, false)
151
DO_2SHIFT(VQSHLUI, vqshlui_s, false)
152
+/* These right shifts use a left-shift helper with negated shift count */
153
+DO_2SHIFT(VSHRI_S, vshli_s, true)
154
+DO_2SHIFT(VSHRI_U, vshli_u, true)
155
+DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
+DO_2SHIFT(VRSHRI_U, vrshli_u, true)
157
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/target/arm/translate-neon.c
160
+++ b/target/arm/translate-neon.c
161
@@ -XXX,XX +XXX,XX @@ static inline int plus1(DisasContext *s, int x)
162
return x + 1;
89
}
163
}
90
164
91
-#ifndef CONFIG_USER_ONLY
165
-static inline int rsub_64(DisasContext *s, int x)
92
-
93
static CPAccessResult pmreg_access_selr(CPUARMState *env,
94
const ARMCPRegInfo *ri,
95
bool isread)
96
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
97
*/
98
void pmccntr_op_start(CPUARMState *env)
99
{
100
- uint64_t cycles = 0;
101
- cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
102
- ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
103
+ uint64_t cycles = cycles_get_count(env);
104
105
if (pmu_counter_enabled(env, 31)) {
106
uint64_t eff_cycles = cycles;
107
@@ -XXX,XX +XXX,XX @@ static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
108
pmccntr_write(env, ri, deposit64(cur_val, 0, 32, value));
109
}
110
111
-#else /* CONFIG_USER_ONLY */
112
-
113
-void pmccntr_op_start(CPUARMState *env)
114
-{
166
-{
167
- return 64 - x;
115
-}
168
-}
116
-
169
-
117
-void pmccntr_op_finish(CPUARMState *env)
170
-static inline int rsub_32(DisasContext *s, int x)
118
-{
171
-{
172
- return 32 - x;
173
-}
174
-static inline int rsub_16(DisasContext *s, int x)
175
-{
176
- return 16 - x;
177
-}
178
-static inline int rsub_8(DisasContext *s, int x)
179
-{
180
- return 8 - x;
119
-}
181
-}
120
-
182
-
121
-void pmevcntr_op_start(CPUARMState *env, uint8_t i)
183
static inline int neon_3same_fp_size(DisasContext *s, int x)
122
-{
123
-}
124
-
125
-void pmevcntr_op_finish(CPUARMState *env, uint8_t i)
126
-{
127
-}
128
-
129
-void pmu_op_start(CPUARMState *env)
130
-{
131
-}
132
-
133
-void pmu_op_finish(CPUARMState *env)
134
-{
135
-}
136
-
137
-void pmu_pre_el_change(ARMCPU *cpu, void *ignored)
138
-{
139
-}
140
-
141
-void pmu_post_el_change(ARMCPU *cpu, void *ignored)
142
-{
143
-}
144
-
145
-#endif
146
-
147
static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
148
uint64_t value)
149
{
184
{
150
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
185
/* Convert 0==fp32, 1==fp16 into a MO_* value */
151
/* Unimplemented so WI. */
152
{ .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
153
.access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NOP },
154
-#ifndef CONFIG_USER_ONLY
155
{ .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
156
.access = PL0_RW, .type = ARM_CP_ALIAS,
157
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr),
158
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
159
.fieldoffset = offsetof(CPUARMState, cp15.c15_ccnt),
160
.readfn = pmccntr_read, .writefn = pmccntr_write,
161
.raw_readfn = raw_read, .raw_writefn = raw_write, },
162
-#endif
163
{ .name = "PMCCFILTR", .cp = 15, .opc1 = 0, .crn = 14, .crm = 15, .opc2 = 7,
164
.writefn = pmccfiltr_write_a32, .readfn = pmccfiltr_read_a32,
165
.access = PL0_RW, .accessfn = pmreg_access,
166
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
167
* count register.
168
*/
169
unsigned int i, pmcrn = 0;
170
-#ifndef CONFIG_USER_ONLY
171
ARMCPRegInfo pmcr = {
172
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
173
.access = PL0_RW,
174
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
175
g_free(pmevtyper_name);
176
g_free(pmevtyper_el0_name);
177
}
178
-#endif
179
ARMCPRegInfo clidr = {
180
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
181
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
182
--
186
--
183
2.20.1
187
2.20.1
184
188
185
189
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE VHLL (vector shift left long) insn. This has two
2
encodings: the T1 encoding is the usual shift-by-immediate format,
3
and the T2 encoding is a special case where the shift count is always
4
equal to the element size.
2
5
3
This is the main crypto routine, an implementation of QARMA.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
This matches, as much as possible, ARM pseudocode.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-10-peter.maydell@linaro.org
9
---
10
target/arm/helper-mve.h | 9 +++++++
11
target/arm/mve.decode | 53 +++++++++++++++++++++++++++++++++++---
12
target/arm/mve_helper.c | 32 +++++++++++++++++++++++
13
target/arm/translate-mve.c | 15 +++++++++++
14
4 files changed, 105 insertions(+), 4 deletions(-)
5
15
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20190108223129.5570-28-richard.henderson@linaro.org
9
[PMM: fixed minor checkpatch nits]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/pauth_helper.c | 242 +++++++++++++++++++++++++++++++++++++-
13
1 file changed, 241 insertions(+), 1 deletion(-)
14
15
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/pauth_helper.c
18
--- a/target/arm/helper-mve.h
18
+++ b/target/arm/pauth_helper.c
19
+++ b/target/arm/helper-mve.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
+
25
+DEF_HELPER_FLAGS_4(mve_vshllbsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(mve_vshllbsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(mve_vshllbub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vshllbuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
36
+++ b/target/arm/mve.decode
19
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
20
#include "tcg/tcg-gvec-desc.h"
38
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
21
39
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
22
40
23
+static uint64_t pac_cell_shuffle(uint64_t i)
41
+@2_shll_b .... .... ... 01 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
42
+@2_shll_h .... .... ... 1 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
43
+# VSHLL encoding T2 where shift == esize
44
+@2_shll_esize_b .... .... .... 00 .. .... .... .... .... &2shift \
45
+ qd=%qd qm=%qm size=0 shift=8
46
+@2_shll_esize_h .... .... .... 01 .. .... .... .... .... &2shift \
47
+ qd=%qd qm=%qm size=1 shift=16
48
+
49
# Right shifts are encoded as N - shift, where N is the element size in bits.
50
%rshift_i5 16:5 !function=rsub_32
51
%rshift_i4 16:4 !function=rsub_16
52
@@ -XXX,XX +XXX,XX @@ VADD 1110 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
53
VSUB 1111 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
54
VMUL 1110 1111 0 . .. ... 0 ... 0 1001 . 1 . 1 ... 0 @2op
55
56
-VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
57
-VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
58
+# The VSHLL T2 encoding is not a @2op pattern, but is here because it
59
+# overlaps what would be size=0b11 VMULH/VRMULH
24
+{
60
+{
25
+ uint64_t o = 0;
61
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
26
+
62
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
27
+ o |= extract64(i, 52, 4);
63
28
+ o |= extract64(i, 24, 4) << 4;
64
-VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
29
+ o |= extract64(i, 44, 4) << 8;
65
-VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
30
+ o |= extract64(i, 0, 4) << 12;
66
+ VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
31
+
32
+ o |= extract64(i, 28, 4) << 16;
33
+ o |= extract64(i, 48, 4) << 20;
34
+ o |= extract64(i, 4, 4) << 24;
35
+ o |= extract64(i, 40, 4) << 28;
36
+
37
+ o |= extract64(i, 32, 4) << 32;
38
+ o |= extract64(i, 12, 4) << 36;
39
+ o |= extract64(i, 56, 4) << 40;
40
+ o |= extract64(i, 20, 4) << 44;
41
+
42
+ o |= extract64(i, 8, 4) << 48;
43
+ o |= extract64(i, 36, 4) << 52;
44
+ o |= extract64(i, 16, 4) << 56;
45
+ o |= extract64(i, 60, 4) << 60;
46
+
47
+ return o;
48
+}
67
+}
49
+
68
+
50
+static uint64_t pac_cell_inv_shuffle(uint64_t i)
51
+{
69
+{
52
+ uint64_t o = 0;
70
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
71
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
53
+
72
+
54
+ o |= extract64(i, 12, 4);
73
+ VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
55
+ o |= extract64(i, 24, 4) << 4;
56
+ o |= extract64(i, 48, 4) << 8;
57
+ o |= extract64(i, 36, 4) << 12;
58
+
59
+ o |= extract64(i, 56, 4) << 16;
60
+ o |= extract64(i, 44, 4) << 20;
61
+ o |= extract64(i, 4, 4) << 24;
62
+ o |= extract64(i, 16, 4) << 28;
63
+
64
+ o |= i & MAKE_64BIT_MASK(32, 4);
65
+ o |= extract64(i, 52, 4) << 36;
66
+ o |= extract64(i, 28, 4) << 40;
67
+ o |= extract64(i, 8, 4) << 44;
68
+
69
+ o |= extract64(i, 20, 4) << 48;
70
+ o |= extract64(i, 0, 4) << 52;
71
+ o |= extract64(i, 40, 4) << 56;
72
+ o |= i & MAKE_64BIT_MASK(60, 4);
73
+
74
+ return o;
75
+}
74
+}
76
+
75
+
77
+static uint64_t pac_sub(uint64_t i)
78
+{
76
+{
79
+ static const uint8_t sub[16] = {
77
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
80
+ 0xb, 0x6, 0x8, 0xf, 0xc, 0x0, 0x9, 0xe,
78
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
81
+ 0x3, 0x7, 0x4, 0x5, 0xd, 0x2, 0x1, 0xa,
82
+ };
83
+ uint64_t o = 0;
84
+ int b;
85
+
79
+
86
+ for (b = 0; b < 64; b += 16) {
80
+ VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
87
+ o |= (uint64_t)sub[(i >> b) & 0xf] << b;
88
+ }
89
+ return o;
90
+}
81
+}
91
+
82
+
92
+static uint64_t pac_inv_sub(uint64_t i)
93
+{
83
+{
94
+ static const uint8_t inv_sub[16] = {
84
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
95
+ 0x5, 0xe, 0xd, 0x8, 0xa, 0xb, 0x1, 0x9,
85
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
96
+ 0x2, 0x6, 0xf, 0x0, 0x4, 0xc, 0x7, 0x3,
97
+ };
98
+ uint64_t o = 0;
99
+ int b;
100
+
86
+
101
+ for (b = 0; b < 64; b += 16) {
87
+ VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
102
+ o |= (uint64_t)inv_sub[(i >> b) & 0xf] << b;
88
+}
89
90
VMAX_S 111 0 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
91
VMAX_U 111 1 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
92
@@ -XXX,XX +XXX,XX @@ VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
93
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
94
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
95
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
96
+
97
+# VSHLL T1 encoding; the T2 VSHLL encoding is elsewhere in this file
98
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
99
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
100
+
101
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
102
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
103
+
104
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
105
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
106
+
107
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
108
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
109
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/mve_helper.c
112
+++ b/target/arm/mve_helper.c
113
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
114
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
115
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
116
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
117
+
118
+/*
119
+ * Long shifts taking half-sized inputs from top or bottom of the input
120
+ * vector and producing a double-width result. ESIZE, TYPE are for
121
+ * the input, and LESIZE, LTYPE for the output.
122
+ * Unlike the normal shift helpers, we do not handle negative shift counts,
123
+ * because the long shift is strictly left-only.
124
+ */
125
+#define DO_VSHLL(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE) \
126
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
127
+ void *vm, uint32_t shift) \
128
+ { \
129
+ LTYPE *d = vd; \
130
+ TYPE *m = vm; \
131
+ uint16_t mask = mve_element_mask(env); \
132
+ unsigned le; \
133
+ assert(shift <= 16); \
134
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
135
+ LTYPE r = (LTYPE)m[H##ESIZE(le * 2 + TOP)] << shift; \
136
+ mergemask(&d[H##LESIZE(le)], r, mask); \
137
+ } \
138
+ mve_advance_vpt(env); \
103
+ }
139
+ }
104
+ return o;
105
+}
106
+
140
+
107
+static int rot_cell(int cell, int n)
141
+#define DO_VSHLL_ALL(OP, TOP) \
108
+{
142
+ DO_VSHLL(OP##sb, TOP, 1, int8_t, 2, int16_t) \
109
+ /* 4-bit rotate left by n. */
143
+ DO_VSHLL(OP##ub, TOP, 1, uint8_t, 2, uint16_t) \
110
+ cell |= cell << 4;
144
+ DO_VSHLL(OP##sh, TOP, 2, int16_t, 4, int32_t) \
111
+ return extract32(cell, 4 - n, 4);
145
+ DO_VSHLL(OP##uh, TOP, 2, uint16_t, 4, uint32_t) \
112
+}
113
+
146
+
114
+static uint64_t pac_mult(uint64_t i)
147
+DO_VSHLL_ALL(vshllb, false)
115
+{
148
+DO_VSHLL_ALL(vshllt, true)
116
+ uint64_t o = 0;
149
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
117
+ int b;
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/translate-mve.c
152
+++ b/target/arm/translate-mve.c
153
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_S, vshli_s, true)
154
DO_2SHIFT(VSHRI_U, vshli_u, true)
155
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
118
+
157
+
119
+ for (b = 0; b < 4 * 4; b += 4) {
158
+#define DO_VSHLL(INSN, FN) \
120
+ int i0, i4, i8, ic, t0, t1, t2, t3;
159
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
160
+ { \
161
+ static MVEGenTwoOpShiftFn * const fns[] = { \
162
+ gen_helper_mve_##FN##b, \
163
+ gen_helper_mve_##FN##h, \
164
+ }; \
165
+ return do_2shift(s, a, fns[a->size], false); \
166
+ }
121
+
167
+
122
+ i0 = extract64(i, b, 4);
168
+DO_VSHLL(VSHLL_BS, vshllbs)
123
+ i4 = extract64(i, b + 4 * 4, 4);
169
+DO_VSHLL(VSHLL_BU, vshllbu)
124
+ i8 = extract64(i, b + 8 * 4, 4);
170
+DO_VSHLL(VSHLL_TS, vshllts)
125
+ ic = extract64(i, b + 12 * 4, 4);
171
+DO_VSHLL(VSHLL_TU, vshlltu)
126
+
127
+ t0 = rot_cell(i8, 1) ^ rot_cell(i4, 2) ^ rot_cell(i0, 1);
128
+ t1 = rot_cell(ic, 1) ^ rot_cell(i4, 1) ^ rot_cell(i0, 2);
129
+ t2 = rot_cell(ic, 2) ^ rot_cell(i8, 1) ^ rot_cell(i0, 1);
130
+ t3 = rot_cell(ic, 1) ^ rot_cell(i8, 2) ^ rot_cell(i4, 1);
131
+
132
+ o |= (uint64_t)t3 << b;
133
+ o |= (uint64_t)t2 << (b + 4 * 4);
134
+ o |= (uint64_t)t1 << (b + 8 * 4);
135
+ o |= (uint64_t)t0 << (b + 12 * 4);
136
+ }
137
+ return o;
138
+}
139
+
140
+static uint64_t tweak_cell_rot(uint64_t cell)
141
+{
142
+ return (cell >> 1) | (((cell ^ (cell >> 1)) & 1) << 3);
143
+}
144
+
145
+static uint64_t tweak_shuffle(uint64_t i)
146
+{
147
+ uint64_t o = 0;
148
+
149
+ o |= extract64(i, 16, 4) << 0;
150
+ o |= extract64(i, 20, 4) << 4;
151
+ o |= tweak_cell_rot(extract64(i, 24, 4)) << 8;
152
+ o |= extract64(i, 28, 4) << 12;
153
+
154
+ o |= tweak_cell_rot(extract64(i, 44, 4)) << 16;
155
+ o |= extract64(i, 8, 4) << 20;
156
+ o |= extract64(i, 12, 4) << 24;
157
+ o |= tweak_cell_rot(extract64(i, 32, 4)) << 28;
158
+
159
+ o |= extract64(i, 48, 4) << 32;
160
+ o |= extract64(i, 52, 4) << 36;
161
+ o |= extract64(i, 56, 4) << 40;
162
+ o |= tweak_cell_rot(extract64(i, 60, 4)) << 44;
163
+
164
+ o |= tweak_cell_rot(extract64(i, 0, 4)) << 48;
165
+ o |= extract64(i, 4, 4) << 52;
166
+ o |= tweak_cell_rot(extract64(i, 40, 4)) << 56;
167
+ o |= tweak_cell_rot(extract64(i, 36, 4)) << 60;
168
+
169
+ return o;
170
+}
171
+
172
+static uint64_t tweak_cell_inv_rot(uint64_t cell)
173
+{
174
+ return ((cell << 1) & 0xf) | ((cell & 1) ^ (cell >> 3));
175
+}
176
+
177
+static uint64_t tweak_inv_shuffle(uint64_t i)
178
+{
179
+ uint64_t o = 0;
180
+
181
+ o |= tweak_cell_inv_rot(extract64(i, 48, 4));
182
+ o |= extract64(i, 52, 4) << 4;
183
+ o |= extract64(i, 20, 4) << 8;
184
+ o |= extract64(i, 24, 4) << 12;
185
+
186
+ o |= extract64(i, 0, 4) << 16;
187
+ o |= extract64(i, 4, 4) << 20;
188
+ o |= tweak_cell_inv_rot(extract64(i, 8, 4)) << 24;
189
+ o |= extract64(i, 12, 4) << 28;
190
+
191
+ o |= tweak_cell_inv_rot(extract64(i, 28, 4)) << 32;
192
+ o |= tweak_cell_inv_rot(extract64(i, 60, 4)) << 36;
193
+ o |= tweak_cell_inv_rot(extract64(i, 56, 4)) << 40;
194
+ o |= tweak_cell_inv_rot(extract64(i, 16, 4)) << 44;
195
+
196
+ o |= extract64(i, 32, 4) << 48;
197
+ o |= extract64(i, 36, 4) << 52;
198
+ o |= extract64(i, 40, 4) << 56;
199
+ o |= tweak_cell_inv_rot(extract64(i, 44, 4)) << 60;
200
+
201
+ return o;
202
+}
203
+
204
static uint64_t pauth_computepac(uint64_t data, uint64_t modifier,
205
ARMPACKey key)
206
{
207
- g_assert_not_reached(); /* FIXME */
208
+ static const uint64_t RC[5] = {
209
+ 0x0000000000000000ull,
210
+ 0x13198A2E03707344ull,
211
+ 0xA4093822299F31D0ull,
212
+ 0x082EFA98EC4E6C89ull,
213
+ 0x452821E638D01377ull,
214
+ };
215
+ const uint64_t alpha = 0xC0AC29B7C97C50DDull;
216
+ /*
217
+ * Note that in the ARM pseudocode, key0 contains bits <127:64>
218
+ * and key1 contains bits <63:0> of the 128-bit key.
219
+ */
220
+ uint64_t key0 = key.hi, key1 = key.lo;
221
+ uint64_t workingval, runningmod, roundkey, modk0;
222
+ int i;
223
+
224
+ modk0 = (key0 << 63) | ((key0 >> 1) ^ (key0 >> 63));
225
+ runningmod = modifier;
226
+ workingval = data ^ key0;
227
+
228
+ for (i = 0; i <= 4; ++i) {
229
+ roundkey = key1 ^ runningmod;
230
+ workingval ^= roundkey;
231
+ workingval ^= RC[i];
232
+ if (i > 0) {
233
+ workingval = pac_cell_shuffle(workingval);
234
+ workingval = pac_mult(workingval);
235
+ }
236
+ workingval = pac_sub(workingval);
237
+ runningmod = tweak_shuffle(runningmod);
238
+ }
239
+ roundkey = modk0 ^ runningmod;
240
+ workingval ^= roundkey;
241
+ workingval = pac_cell_shuffle(workingval);
242
+ workingval = pac_mult(workingval);
243
+ workingval = pac_sub(workingval);
244
+ workingval = pac_cell_shuffle(workingval);
245
+ workingval = pac_mult(workingval);
246
+ workingval ^= key1;
247
+ workingval = pac_cell_inv_shuffle(workingval);
248
+ workingval = pac_inv_sub(workingval);
249
+ workingval = pac_mult(workingval);
250
+ workingval = pac_cell_inv_shuffle(workingval);
251
+ workingval ^= key0;
252
+ workingval ^= runningmod;
253
+ for (i = 0; i <= 4; ++i) {
254
+ workingval = pac_inv_sub(workingval);
255
+ if (i < 4) {
256
+ workingval = pac_mult(workingval);
257
+ workingval = pac_cell_inv_shuffle(workingval);
258
+ }
259
+ runningmod = tweak_inv_shuffle(runningmod);
260
+ roundkey = key1 ^ runningmod;
261
+ workingval ^= RC[4 - i];
262
+ workingval ^= roundkey;
263
+ workingval ^= alpha;
264
+ }
265
+ workingval ^= modk0;
266
+
267
+ return workingval;
268
}
269
270
static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
271
--
172
--
272
2.20.1
173
2.20.1
273
174
274
175
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE VSRI and VSLI insns, which perform a
2
shift-and-insert operation.
2
3
3
This function is only used by AArch64. Code movement only.
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210628135835.6690-11-peter.maydell@linaro.org
7
---
8
target/arm/helper-mve.h | 8 ++++++++
9
target/arm/mve.decode | 9 ++++++++
10
target/arm/mve_helper.c | 42 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-mve.c | 3 +++
12
4 files changed, 62 insertions(+)
4
13
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190108223129.5570-11-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper-a64.h | 2 +
11
target/arm/helper.h | 1 -
12
target/arm/helper-a64.c | 155 ++++++++++++++++++++++++++++++++++++++++
13
target/arm/op_helper.c | 155 ----------------------------------------
14
4 files changed, 157 insertions(+), 156 deletions(-)
15
16
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-a64.h
16
--- a/target/arm/helper-mve.h
19
+++ b/target/arm/helper-a64.h
17
+++ b/target/arm/helper-mve.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
19
DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
20
DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
21
DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
+DEF_HELPER_1(exception_return, void, env)
25
+
22
+
26
DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64)
23
+DEF_HELPER_FLAGS_4(mve_vsrib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64)
24
+DEF_HELPER_FLAGS_4(mve_vsrih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
DEF_HELPER_FLAGS_3(pacda, TCG_CALL_NO_WG, i64, env, i64, i64)
25
+DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
diff --git a/target/arm/helper.h b/target/arm/helper.h
26
+
27
+DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
30
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/helper.h
32
--- a/target/arm/mve.decode
32
+++ b/target/arm/helper.h
33
+++ b/target/arm/mve.decode
33
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
34
@@ -XXX,XX +XXX,XX @@ VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
34
35
35
DEF_HELPER_3(msr_i_pstate, void, env, i32, i32)
36
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
36
DEF_HELPER_1(clear_pstate_ss, void, env)
37
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
37
-DEF_HELPER_1(exception_return, void, env)
38
+
38
39
+# Shift-and-insert
39
DEF_HELPER_2(get_r13_banked, i32, env, i32)
40
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_b
40
DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
41
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_h
41
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
42
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
43
+
44
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
45
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
46
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
47
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
42
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/helper-a64.c
49
--- a/target/arm/mve_helper.c
44
+++ b/target/arm/helper-a64.c
50
+++ b/target/arm/mve_helper.c
45
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_f16touinth)(uint32_t a, void *fpstp)
51
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
46
return float16_to_uint16(a, fpst);
52
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
47
}
53
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
48
54
49
+static int el_from_spsr(uint32_t spsr)
55
+/* Shift-and-insert; we always work with 64 bits at a time */
50
+{
56
+#define DO_2SHIFT_INSERT(OP, ESIZE, SHIFTFN, MASKFN) \
51
+ /* Return the exception level that this SPSR is requesting a return to,
57
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
52
+ * or -1 if it is invalid (an illegal return)
58
+ void *vm, uint32_t shift) \
53
+ */
59
+ { \
54
+ if (spsr & PSTATE_nRW) {
60
+ uint64_t *d = vd, *m = vm; \
55
+ switch (spsr & CPSR_M) {
61
+ uint16_t mask; \
56
+ case ARM_CPU_MODE_USR:
62
+ uint64_t shiftmask; \
57
+ return 0;
63
+ unsigned e; \
58
+ case ARM_CPU_MODE_HYP:
64
+ if (shift == 0 || shift == ESIZE * 8) { \
59
+ return 2;
65
+ /* \
60
+ case ARM_CPU_MODE_FIQ:
66
+ * Only VSLI can shift by 0; only VSRI can shift by <dt>. \
61
+ case ARM_CPU_MODE_IRQ:
67
+ * The generic logic would give the right answer for 0 but \
62
+ case ARM_CPU_MODE_SVC:
68
+ * fails for <dt>. \
63
+ case ARM_CPU_MODE_ABT:
69
+ */ \
64
+ case ARM_CPU_MODE_UND:
70
+ goto done; \
65
+ case ARM_CPU_MODE_SYS:
71
+ } \
66
+ return 1;
72
+ assert(shift < ESIZE * 8); \
67
+ case ARM_CPU_MODE_MON:
73
+ mask = mve_element_mask(env); \
68
+ /* Returning to Mon from AArch64 is never possible,
74
+ /* ESIZE / 2 gives the MO_* value if ESIZE is in [1,2,4] */ \
69
+ * so this is an illegal return.
75
+ shiftmask = dup_const(ESIZE / 2, MASKFN(ESIZE * 8, shift)); \
70
+ */
76
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
71
+ default:
77
+ uint64_t r = (SHIFTFN(m[H8(e)], shift) & shiftmask) | \
72
+ return -1;
78
+ (d[H8(e)] & ~shiftmask); \
73
+ }
79
+ mergemask(&d[H8(e)], r, mask); \
74
+ } else {
80
+ } \
75
+ if (extract32(spsr, 1, 1)) {
81
+done: \
76
+ /* Return with reserved M[1] bit set */
82
+ mve_advance_vpt(env); \
77
+ return -1;
78
+ }
79
+ if (extract32(spsr, 0, 4) == 1) {
80
+ /* return to EL0 with M[0] bit set */
81
+ return -1;
82
+ }
83
+ return extract32(spsr, 2, 2);
84
+ }
85
+}
86
+
87
+void HELPER(exception_return)(CPUARMState *env)
88
+{
89
+ int cur_el = arm_current_el(env);
90
+ unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
91
+ uint32_t spsr = env->banked_spsr[spsr_idx];
92
+ int new_el;
93
+ bool return_to_aa64 = (spsr & PSTATE_nRW) == 0;
94
+
95
+ aarch64_save_sp(env, cur_el);
96
+
97
+ arm_clear_exclusive(env);
98
+
99
+ /* We must squash the PSTATE.SS bit to zero unless both of the
100
+ * following hold:
101
+ * 1. debug exceptions are currently disabled
102
+ * 2. singlestep will be active in the EL we return to
103
+ * We check 1 here and 2 after we've done the pstate/cpsr write() to
104
+ * transition to the EL we're going to.
105
+ */
106
+ if (arm_generate_debug_exceptions(env)) {
107
+ spsr &= ~PSTATE_SS;
108
+ }
83
+ }
109
+
84
+
110
+ new_el = el_from_spsr(spsr);
85
+#define DO_SHL(N, SHIFT) ((N) << (SHIFT))
111
+ if (new_el == -1) {
86
+#define DO_SHR(N, SHIFT) ((N) >> (SHIFT))
112
+ goto illegal_return;
87
+#define SHL_MASK(EBITS, SHIFT) MAKE_64BIT_MASK((SHIFT), (EBITS) - (SHIFT))
113
+ }
88
+#define SHR_MASK(EBITS, SHIFT) MAKE_64BIT_MASK(0, (EBITS) - (SHIFT))
114
+ if (new_el > cur_el
115
+ || (new_el == 2 && !arm_feature(env, ARM_FEATURE_EL2))) {
116
+ /* Disallow return to an EL which is unimplemented or higher
117
+ * than the current one.
118
+ */
119
+ goto illegal_return;
120
+ }
121
+
89
+
122
+ if (new_el != 0 && arm_el_is_aa64(env, new_el) != return_to_aa64) {
90
+DO_2SHIFT_INSERT(vsrib, 1, DO_SHR, SHR_MASK)
123
+ /* Return to an EL which is configured for a different register width */
91
+DO_2SHIFT_INSERT(vsrih, 2, DO_SHR, SHR_MASK)
124
+ goto illegal_return;
92
+DO_2SHIFT_INSERT(vsriw, 4, DO_SHR, SHR_MASK)
125
+ }
93
+DO_2SHIFT_INSERT(vslib, 1, DO_SHL, SHL_MASK)
126
+
94
+DO_2SHIFT_INSERT(vslih, 2, DO_SHL, SHL_MASK)
127
+ if (new_el == 2 && arm_is_secure_below_el3(env)) {
95
+DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
128
+ /* Return to the non-existent secure-EL2 */
129
+ goto illegal_return;
130
+ }
131
+
132
+ if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
133
+ goto illegal_return;
134
+ }
135
+
136
+ qemu_mutex_lock_iothread();
137
+ arm_call_pre_el_change_hook(arm_env_get_cpu(env));
138
+ qemu_mutex_unlock_iothread();
139
+
140
+ if (!return_to_aa64) {
141
+ env->aarch64 = 0;
142
+ /* We do a raw CPSR write because aarch64_sync_64_to_32()
143
+ * will sort the register banks out for us, and we've already
144
+ * caught all the bad-mode cases in el_from_spsr().
145
+ */
146
+ cpsr_write(env, spsr, ~0, CPSRWriteRaw);
147
+ if (!arm_singlestep_active(env)) {
148
+ env->uncached_cpsr &= ~PSTATE_SS;
149
+ }
150
+ aarch64_sync_64_to_32(env);
151
+
152
+ if (spsr & CPSR_T) {
153
+ env->regs[15] = env->elr_el[cur_el] & ~0x1;
154
+ } else {
155
+ env->regs[15] = env->elr_el[cur_el] & ~0x3;
156
+ }
157
+ qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
158
+ "AArch32 EL%d PC 0x%" PRIx32 "\n",
159
+ cur_el, new_el, env->regs[15]);
160
+ } else {
161
+ env->aarch64 = 1;
162
+ pstate_write(env, spsr);
163
+ if (!arm_singlestep_active(env)) {
164
+ env->pstate &= ~PSTATE_SS;
165
+ }
166
+ aarch64_restore_sp(env, new_el);
167
+ env->pc = env->elr_el[cur_el];
168
+ qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
169
+ "AArch64 EL%d PC 0x%" PRIx64 "\n",
170
+ cur_el, new_el, env->pc);
171
+ }
172
+ /*
173
+ * Note that cur_el can never be 0. If new_el is 0, then
174
+ * el0_a64 is return_to_aa64, else el0_a64 is ignored.
175
+ */
176
+ aarch64_sve_change_el(env, cur_el, new_el, return_to_aa64);
177
+
178
+ qemu_mutex_lock_iothread();
179
+ arm_call_el_change_hook(arm_env_get_cpu(env));
180
+ qemu_mutex_unlock_iothread();
181
+
182
+ return;
183
+
184
+illegal_return:
185
+ /* Illegal return events of various kinds have architecturally
186
+ * mandated behaviour:
187
+ * restore NZCV and DAIF from SPSR_ELx
188
+ * set PSTATE.IL
189
+ * restore PC from ELR_ELx
190
+ * no change to exception level, execution state or stack pointer
191
+ */
192
+ env->pstate |= PSTATE_IL;
193
+ env->pc = env->elr_el[cur_el];
194
+ spsr &= PSTATE_NZCV | PSTATE_DAIF;
195
+ spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF);
196
+ pstate_write(env, spsr);
197
+ if (!arm_singlestep_active(env)) {
198
+ env->pstate &= ~PSTATE_SS;
199
+ }
200
+ qemu_log_mask(LOG_GUEST_ERROR, "Illegal exception return at EL%d: "
201
+ "resuming execution at 0x%" PRIx64 "\n", cur_el, env->pc);
202
+}
203
+
96
+
204
/*
97
/*
205
* Square Root and Reciprocal square root
98
* Long shifts taking half-sized inputs from top or bottom of the input
206
*/
99
* vector and producing a double-width result. ESIZE, TYPE are for
207
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
208
index XXXXXXX..XXXXXXX 100644
101
index XXXXXXX..XXXXXXX 100644
209
--- a/target/arm/op_helper.c
102
--- a/target/arm/translate-mve.c
210
+++ b/target/arm/op_helper.c
103
+++ b/target/arm/translate-mve.c
211
@@ -XXX,XX +XXX,XX @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
104
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_U, vshli_u, true)
212
}
105
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
213
}
106
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
214
107
215
-static int el_from_spsr(uint32_t spsr)
108
+DO_2SHIFT(VSRI, vsri, false)
216
-{
109
+DO_2SHIFT(VSLI, vsli, false)
217
- /* Return the exception level that this SPSR is requesting a return to,
110
+
218
- * or -1 if it is invalid (an illegal return)
111
#define DO_VSHLL(INSN, FN) \
219
- */
112
static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
220
- if (spsr & PSTATE_nRW) {
113
{ \
221
- switch (spsr & CPSR_M) {
222
- case ARM_CPU_MODE_USR:
223
- return 0;
224
- case ARM_CPU_MODE_HYP:
225
- return 2;
226
- case ARM_CPU_MODE_FIQ:
227
- case ARM_CPU_MODE_IRQ:
228
- case ARM_CPU_MODE_SVC:
229
- case ARM_CPU_MODE_ABT:
230
- case ARM_CPU_MODE_UND:
231
- case ARM_CPU_MODE_SYS:
232
- return 1;
233
- case ARM_CPU_MODE_MON:
234
- /* Returning to Mon from AArch64 is never possible,
235
- * so this is an illegal return.
236
- */
237
- default:
238
- return -1;
239
- }
240
- } else {
241
- if (extract32(spsr, 1, 1)) {
242
- /* Return with reserved M[1] bit set */
243
- return -1;
244
- }
245
- if (extract32(spsr, 0, 4) == 1) {
246
- /* return to EL0 with M[0] bit set */
247
- return -1;
248
- }
249
- return extract32(spsr, 2, 2);
250
- }
251
-}
252
-
253
-void HELPER(exception_return)(CPUARMState *env)
254
-{
255
- int cur_el = arm_current_el(env);
256
- unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
257
- uint32_t spsr = env->banked_spsr[spsr_idx];
258
- int new_el;
259
- bool return_to_aa64 = (spsr & PSTATE_nRW) == 0;
260
-
261
- aarch64_save_sp(env, cur_el);
262
-
263
- arm_clear_exclusive(env);
264
-
265
- /* We must squash the PSTATE.SS bit to zero unless both of the
266
- * following hold:
267
- * 1. debug exceptions are currently disabled
268
- * 2. singlestep will be active in the EL we return to
269
- * We check 1 here and 2 after we've done the pstate/cpsr write() to
270
- * transition to the EL we're going to.
271
- */
272
- if (arm_generate_debug_exceptions(env)) {
273
- spsr &= ~PSTATE_SS;
274
- }
275
-
276
- new_el = el_from_spsr(spsr);
277
- if (new_el == -1) {
278
- goto illegal_return;
279
- }
280
- if (new_el > cur_el
281
- || (new_el == 2 && !arm_feature(env, ARM_FEATURE_EL2))) {
282
- /* Disallow return to an EL which is unimplemented or higher
283
- * than the current one.
284
- */
285
- goto illegal_return;
286
- }
287
-
288
- if (new_el != 0 && arm_el_is_aa64(env, new_el) != return_to_aa64) {
289
- /* Return to an EL which is configured for a different register width */
290
- goto illegal_return;
291
- }
292
-
293
- if (new_el == 2 && arm_is_secure_below_el3(env)) {
294
- /* Return to the non-existent secure-EL2 */
295
- goto illegal_return;
296
- }
297
-
298
- if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
299
- goto illegal_return;
300
- }
301
-
302
- qemu_mutex_lock_iothread();
303
- arm_call_pre_el_change_hook(arm_env_get_cpu(env));
304
- qemu_mutex_unlock_iothread();
305
-
306
- if (!return_to_aa64) {
307
- env->aarch64 = 0;
308
- /* We do a raw CPSR write because aarch64_sync_64_to_32()
309
- * will sort the register banks out for us, and we've already
310
- * caught all the bad-mode cases in el_from_spsr().
311
- */
312
- cpsr_write(env, spsr, ~0, CPSRWriteRaw);
313
- if (!arm_singlestep_active(env)) {
314
- env->uncached_cpsr &= ~PSTATE_SS;
315
- }
316
- aarch64_sync_64_to_32(env);
317
-
318
- if (spsr & CPSR_T) {
319
- env->regs[15] = env->elr_el[cur_el] & ~0x1;
320
- } else {
321
- env->regs[15] = env->elr_el[cur_el] & ~0x3;
322
- }
323
- qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
324
- "AArch32 EL%d PC 0x%" PRIx32 "\n",
325
- cur_el, new_el, env->regs[15]);
326
- } else {
327
- env->aarch64 = 1;
328
- pstate_write(env, spsr);
329
- if (!arm_singlestep_active(env)) {
330
- env->pstate &= ~PSTATE_SS;
331
- }
332
- aarch64_restore_sp(env, new_el);
333
- env->pc = env->elr_el[cur_el];
334
- qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
335
- "AArch64 EL%d PC 0x%" PRIx64 "\n",
336
- cur_el, new_el, env->pc);
337
- }
338
- /*
339
- * Note that cur_el can never be 0. If new_el is 0, then
340
- * el0_a64 is return_to_aa64, else el0_a64 is ignored.
341
- */
342
- aarch64_sve_change_el(env, cur_el, new_el, return_to_aa64);
343
-
344
- qemu_mutex_lock_iothread();
345
- arm_call_el_change_hook(arm_env_get_cpu(env));
346
- qemu_mutex_unlock_iothread();
347
-
348
- return;
349
-
350
-illegal_return:
351
- /* Illegal return events of various kinds have architecturally
352
- * mandated behaviour:
353
- * restore NZCV and DAIF from SPSR_ELx
354
- * set PSTATE.IL
355
- * restore PC from ELR_ELx
356
- * no change to exception level, execution state or stack pointer
357
- */
358
- env->pstate |= PSTATE_IL;
359
- env->pc = env->elr_el[cur_el];
360
- spsr &= PSTATE_NZCV | PSTATE_DAIF;
361
- spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF);
362
- pstate_write(env, spsr);
363
- if (!arm_singlestep_active(env)) {
364
- env->pstate &= ~PSTATE_SS;
365
- }
366
- qemu_log_mask(LOG_GUEST_ERROR, "Illegal exception return at EL%d: "
367
- "resuming execution at 0x%" PRIx64 "\n", cur_el, env->pc);
368
-}
369
-
370
/* Return true if the linked breakpoint entry lbn passes its checks */
371
static bool linked_bp_matches(ARMCPU *cpu, int lbn)
372
{
373
--
114
--
374
2.20.1
115
2.20.1
375
116
376
117
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
Implement the MVE shift-right-and-narrow insn VSHRN and VRSHRN.
2
2
3
pmccntr_read and pmccntr_write contained duplicate code that was already
3
do_urshr() is borrowed from sve_helper.c.
4
being handled by pmccntr_sync. Consolidate the duplicated code into two
5
functions: pmccntr_op_start and pmccntr_op_finish. Add a companion to
6
c15_ccnt in CPUARMState so that we can simultaneously save both the
7
architectural register value and the last underlying cycle count - this
8
ensures time isn't lost and will also allow us to access the 'old'
9
architectural register value in order to detect overflows in later
10
patches.
11
4
12
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
13
Signed-off-by: Aaron Lindsay <aclindsa@gmail.com>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Message-id: 20181211151945.29137-3-aaron@os.amperecomputing.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-12-peter.maydell@linaro.org
17
---
8
---
18
target/arm/cpu.h | 37 +++++++++++---
9
target/arm/helper-mve.h | 10 ++++++++++
19
target/arm/helper.c | 118 ++++++++++++++++++++++++++------------------
10
target/arm/mve.decode | 11 +++++++++++
20
2 files changed, 100 insertions(+), 55 deletions(-)
11
target/arm/mve_helper.c | 40 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate-mve.c | 15 ++++++++++++++
13
4 files changed, 76 insertions(+)
21
14
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
23
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
17
--- a/target/arm/helper-mve.h
25
+++ b/target/arm/cpu.h
18
+++ b/target/arm/helper-mve.h
26
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
uint64_t oslsr_el1; /* OS Lock Status */
20
DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
uint64_t mdcr_el2;
21
DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
uint64_t mdcr_el3;
22
DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
- /* If the counter is enabled, this stores the last time the counter
31
- * was reset. Otherwise it stores the counter value
32
+ /* Stores the architectural value of the counter *the last time it was
33
+ * updated* by pmccntr_op_start. Accesses should always be surrounded
34
+ * by pmccntr_op_start/pmccntr_op_finish to guarantee the latest
35
+ * architecturally-correct value is being read/set.
36
*/
37
uint64_t c15_ccnt;
38
+ /* Stores the delta between the architectural value and the underlying
39
+ * cycle count during normal operation. It is used to update c15_ccnt
40
+ * to be the correct architectural value before accesses. During
41
+ * accesses, c15_ccnt_delta contains the underlying count being used
42
+ * for the access, after which it reverts to the delta value in
43
+ * pmccntr_op_finish.
44
+ */
45
+ uint64_t c15_ccnt_delta;
46
uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */
47
uint64_t vpidr_el2; /* Virtualization Processor ID Register */
48
uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */
49
@@ -XXX,XX +XXX,XX @@ int cpu_arm_signal_handler(int host_signum, void *pinfo,
50
void *puc);
51
52
/**
53
- * pmccntr_sync
54
+ * pmccntr_op_start/finish
55
* @env: CPUARMState
56
*
57
- * Synchronises the counter in the PMCCNTR. This must always be called twice,
58
- * once before any action that might affect the timer and again afterwards.
59
- * The function is used to swap the state of the register if required.
60
- * This only happens when not in user mode (!CONFIG_USER_ONLY)
61
+ * Convert the counter in the PMCCNTR between its delta form (the typical mode
62
+ * when it's enabled) and the guest-visible value. These two calls must always
63
+ * surround any action which might affect the counter.
64
*/
65
-void pmccntr_sync(CPUARMState *env);
66
+void pmccntr_op_start(CPUARMState *env);
67
+void pmccntr_op_finish(CPUARMState *env);
68
+
23
+
69
+/**
24
+DEF_HELPER_FLAGS_4(mve_vshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
70
+ * pmu_op_start/finish
25
+DEF_HELPER_FLAGS_4(mve_vshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
71
+ * @env: CPUARMState
26
+DEF_HELPER_FLAGS_4(mve_vshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
72
+ *
27
+DEF_HELPER_FLAGS_4(mve_vshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
73
+ * Convert all PMU counters between their delta form (the typical mode when
28
+
74
+ * they are enabled) and the guest-visible values. These two calls must
29
+DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
75
+ * surround any action which might affect the counters.
30
+DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
76
+ */
31
+DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
77
+void pmu_op_start(CPUARMState *env);
32
+DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
78
+void pmu_op_finish(CPUARMState *env);
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
79
80
/* SCTLR bit meanings. Several bits have been reused in newer
81
* versions of the architecture; in that case we define constants
82
diff --git a/target/arm/helper.c b/target/arm/helper.c
83
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
84
--- a/target/arm/helper.c
35
--- a/target/arm/mve.decode
85
+++ b/target/arm/helper.c
36
+++ b/target/arm/mve.decode
86
@@ -XXX,XX +XXX,XX @@ static inline bool arm_ccnt_enabled(CPUARMState *env)
37
@@ -XXX,XX +XXX,XX @@ VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
87
38
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
88
return true;
39
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
89
}
40
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
90
-
91
-void pmccntr_sync(CPUARMState *env)
92
+/*
93
+ * Ensure c15_ccnt is the guest-visible count so that operations such as
94
+ * enabling/disabling the counter or filtering, modifying the count itself,
95
+ * etc. can be done logically. This is essentially a no-op if the counter is
96
+ * not enabled at the time of the call.
97
+ */
98
+void pmccntr_op_start(CPUARMState *env)
99
{
100
- uint64_t temp_ticks;
101
-
102
- temp_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
103
+ uint64_t cycles = 0;
104
+ cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
105
ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
106
107
- if (env->cp15.c9_pmcr & PMCRD) {
108
- /* Increment once every 64 processor clock cycles */
109
- temp_ticks /= 64;
110
- }
111
-
112
if (arm_ccnt_enabled(env)) {
113
- env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt;
114
+ uint64_t eff_cycles = cycles;
115
+ if (env->cp15.c9_pmcr & PMCRD) {
116
+ /* Increment once every 64 processor clock cycles */
117
+ eff_cycles /= 64;
118
+ }
119
+
41
+
120
+ env->cp15.c15_ccnt = eff_cycles - env->cp15.c15_ccnt_delta;
42
+# Narrowing shifts (which only support b and h sizes)
121
}
43
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
122
+ env->cp15.c15_ccnt_delta = cycles;
44
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
123
+}
45
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
46
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
47
+
48
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
49
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
50
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
51
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
52
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/mve_helper.c
55
+++ b/target/arm/mve_helper.c
56
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
57
58
DO_VSHLL_ALL(vshllb, false)
59
DO_VSHLL_ALL(vshllt, true)
124
+
60
+
125
+/*
61
+/*
126
+ * If PMCCNTR is enabled, recalculate the delta between the clock and the
62
+ * Narrowing right shifts, taking a double sized input, shifting it
127
+ * guest-visible count. A call to pmccntr_op_finish should follow every call to
63
+ * and putting the result in either the top or bottom half of the output.
128
+ * pmccntr_op_start.
64
+ * ESIZE, TYPE are the output, and LESIZE, LTYPE the input.
129
+ */
65
+ */
130
+void pmccntr_op_finish(CPUARMState *env)
66
+#define DO_VSHRN(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
67
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
68
+ void *vm, uint32_t shift) \
69
+ { \
70
+ LTYPE *m = vm; \
71
+ TYPE *d = vd; \
72
+ uint16_t mask = mve_element_mask(env); \
73
+ unsigned le; \
74
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
75
+ TYPE r = FN(m[H##LESIZE(le)], shift); \
76
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
77
+ } \
78
+ mve_advance_vpt(env); \
79
+ }
80
+
81
+#define DO_VSHRN_ALL(OP, FN) \
82
+ DO_VSHRN(OP##bb, false, 1, uint8_t, 2, uint16_t, FN) \
83
+ DO_VSHRN(OP##bh, false, 2, uint16_t, 4, uint32_t, FN) \
84
+ DO_VSHRN(OP##tb, true, 1, uint8_t, 2, uint16_t, FN) \
85
+ DO_VSHRN(OP##th, true, 2, uint16_t, 4, uint32_t, FN)
86
+
87
+static inline uint64_t do_urshr(uint64_t x, unsigned sh)
131
+{
88
+{
132
+ if (arm_ccnt_enabled(env)) {
89
+ if (likely(sh < 64)) {
133
+ uint64_t prev_cycles = env->cp15.c15_ccnt_delta;
90
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
134
+
91
+ } else if (sh == 64) {
135
+ if (env->cp15.c9_pmcr & PMCRD) {
92
+ return x >> 63;
136
+ /* Increment once every 64 processor clock cycles */
93
+ } else {
137
+ prev_cycles /= 64;
94
+ return 0;
138
+ }
139
+
140
+ env->cp15.c15_ccnt_delta = prev_cycles - env->cp15.c15_ccnt;
141
+ }
95
+ }
142
+}
96
+}
143
+
97
+
144
+void pmu_op_start(CPUARMState *env)
98
+DO_VSHRN_ALL(vshrn, DO_SHR)
145
+{
99
+DO_VSHRN_ALL(vrshrn, do_urshr)
146
+ pmccntr_op_start(env);
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
147
+}
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/translate-mve.c
103
+++ b/target/arm/translate-mve.c
104
@@ -XXX,XX +XXX,XX @@ DO_VSHLL(VSHLL_BS, vshllbs)
105
DO_VSHLL(VSHLL_BU, vshllbu)
106
DO_VSHLL(VSHLL_TS, vshllts)
107
DO_VSHLL(VSHLL_TU, vshlltu)
148
+
108
+
149
+void pmu_op_finish(CPUARMState *env)
109
+#define DO_2SHIFT_N(INSN, FN) \
150
+{
110
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
151
+ pmccntr_op_finish(env);
111
+ { \
152
}
112
+ static MVEGenTwoOpShiftFn * const fns[] = { \
153
113
+ gen_helper_mve_##FN##b, \
154
static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
114
+ gen_helper_mve_##FN##h, \
155
uint64_t value)
115
+ }; \
156
{
116
+ return do_2shift(s, a, fns[a->size], false); \
157
- pmccntr_sync(env);
117
+ }
158
+ pmu_op_start(env);
159
160
if (value & PMCRC) {
161
/* The counter has been reset */
162
@@ -XXX,XX +XXX,XX @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
163
env->cp15.c9_pmcr &= ~0x39;
164
env->cp15.c9_pmcr |= (value & 0x39);
165
166
- pmccntr_sync(env);
167
+ pmu_op_finish(env);
168
}
169
170
static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
171
{
172
- uint64_t total_ticks;
173
-
174
- if (!arm_ccnt_enabled(env)) {
175
- /* Counter is disabled, do not change value */
176
- return env->cp15.c15_ccnt;
177
- }
178
-
179
- total_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
180
- ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
181
-
182
- if (env->cp15.c9_pmcr & PMCRD) {
183
- /* Increment once every 64 processor clock cycles */
184
- total_ticks /= 64;
185
- }
186
- return total_ticks - env->cp15.c15_ccnt;
187
+ uint64_t ret;
188
+ pmccntr_op_start(env);
189
+ ret = env->cp15.c15_ccnt;
190
+ pmccntr_op_finish(env);
191
+ return ret;
192
}
193
194
static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
195
@@ -XXX,XX +XXX,XX @@ static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
196
static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
197
uint64_t value)
198
{
199
- uint64_t total_ticks;
200
-
201
- if (!arm_ccnt_enabled(env)) {
202
- /* Counter is disabled, set the absolute value */
203
- env->cp15.c15_ccnt = value;
204
- return;
205
- }
206
-
207
- total_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
208
- ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
209
-
210
- if (env->cp15.c9_pmcr & PMCRD) {
211
- /* Increment once every 64 processor clock cycles */
212
- total_ticks /= 64;
213
- }
214
- env->cp15.c15_ccnt = total_ticks - value;
215
+ pmccntr_op_start(env);
216
+ env->cp15.c15_ccnt = value;
217
+ pmccntr_op_finish(env);
218
}
219
220
static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
221
@@ -XXX,XX +XXX,XX @@ static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
222
223
#else /* CONFIG_USER_ONLY */
224
225
-void pmccntr_sync(CPUARMState *env)
226
+void pmccntr_op_start(CPUARMState *env)
227
+{
228
+}
229
+
118
+
230
+void pmccntr_op_finish(CPUARMState *env)
119
+DO_2SHIFT_N(VSHRNB, vshrnb)
231
+{
120
+DO_2SHIFT_N(VSHRNT, vshrnt)
232
+}
121
+DO_2SHIFT_N(VRSHRNB, vrshrnb)
233
+
122
+DO_2SHIFT_N(VRSHRNT, vrshrnt)
234
+void pmu_op_start(CPUARMState *env)
235
+{
236
+}
237
+
238
+void pmu_op_finish(CPUARMState *env)
239
{
240
}
241
242
@@ -XXX,XX +XXX,XX @@ void pmccntr_sync(CPUARMState *env)
243
static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
244
uint64_t value)
245
{
246
- pmccntr_sync(env);
247
+ pmccntr_op_start(env);
248
env->cp15.pmccfiltr_el0 = value & 0xfc000000;
249
- pmccntr_sync(env);
250
+ pmccntr_op_finish(env);
251
}
252
253
static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
254
--
123
--
255
2.20.1
124
2.20.1
256
125
257
126
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
Implement the MVE saturating shift-right-and-narrow insns
2
2
VQSHRN, VQSHRUN, VQRSHRN and VQRSHRUN.
3
Add arrays to hold the registers, the definitions themselves, access
3
4
functions, and logic to reset counters when PMCR.P is set. Update
4
do_srshr() is borrowed from sve_helper.c.
5
filtering code to support counters other than PMCCNTR. Support migration
5
6
with raw read/write functions.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
8
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
9
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20181211151945.29137-11-aaron@os.amperecomputing.com
8
Message-id: 20210628135835.6690-13-peter.maydell@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
9
---
14
target/arm/cpu.h | 3 +
10
target/arm/helper-mve.h | 30 +++++++++++
15
target/arm/helper.c | 296 +++++++++++++++++++++++++++++++++++++++++---
11
target/arm/mve.decode | 28 ++++++++++
16
2 files changed, 282 insertions(+), 17 deletions(-)
12
target/arm/mve_helper.c | 104 +++++++++++++++++++++++++++++++++++++
17
13
target/arm/translate-mve.c | 12 +++++
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
4 files changed, 174 insertions(+)
19
index XXXXXXX..XXXXXXX 100644
15
20
--- a/target/arm/cpu.h
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
21
+++ b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
22
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
18
--- a/target/arm/helper-mve.h
23
* pmccntr_op_finish.
19
+++ b/target/arm/helper-mve.h
24
*/
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
uint64_t c15_ccnt_delta;
21
DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+ uint64_t c14_pmevcntr[31];
22
DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+ uint64_t c14_pmevcntr_delta[31];
23
DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+ uint64_t c14_pmevtyper[31];
24
+
29
uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */
25
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
uint64_t vpidr_el2; /* Virtualization Processor ID Register */
26
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */
27
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
index XXXXXXX..XXXXXXX 100644
29
+
34
--- a/target/arm/helper.c
30
+DEF_HELPER_FLAGS_4(mve_vqshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
+++ b/target/arm/helper.c
31
+DEF_HELPER_FLAGS_4(mve_vqshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
32
+DEF_HELPER_FLAGS_4(mve_vqshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
#define PMCRDP 0x10
33
+DEF_HELPER_FLAGS_4(mve_vqshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
#define PMCRD 0x8
34
+
39
#define PMCRC 0x4
35
+DEF_HELPER_FLAGS_4(mve_vqshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+#define PMCRP 0x2
36
+DEF_HELPER_FLAGS_4(mve_vqshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
#define PMCRE 0x1
37
+DEF_HELPER_FLAGS_4(mve_vqshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
42
38
+DEF_HELPER_FLAGS_4(mve_vqshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
#define PMXEVTYPER_P 0x80000000
39
+
44
@@ -XXX,XX +XXX,XX @@ uint64_t get_pmceid(CPUARMState *env, unsigned which)
40
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
return pmceid;
41
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
}
42
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
43
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
+/*
44
+
49
+ * Check at runtime whether a PMU event is supported for the current machine
45
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
50
+ */
46
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
51
+static bool event_supported(uint16_t number)
47
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
52
+{
48
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
53
+ if (number > MAX_EVENT_ID) {
49
+
54
+ return false;
50
+DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
55
+ }
51
+DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
56
+ return supported_event_map[number] != UNSUPPORTED_EVENT;
52
+DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
57
+}
53
+DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
58
+
54
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
59
static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
55
index XXXXXXX..XXXXXXX 100644
60
bool isread)
56
--- a/target/arm/mve.decode
61
{
57
+++ b/target/arm/mve.decode
62
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
58
@@ -XXX,XX +XXX,XX @@ VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
63
prohibited = env->cp15.c9_pmcr & PMCRDP;
59
VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
64
}
60
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
65
61
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
66
- /* TODO Remove assert, set filter to correct PMEVTYPER */
62
+
67
- assert(counter == 31);
63
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
68
- filter = env->cp15.pmccfiltr_el0;
64
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
69
+ if (counter == 31) {
65
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
70
+ filter = env->cp15.pmccfiltr_el0;
66
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
71
+ } else {
67
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
72
+ filter = env->cp15.c14_pmevtyper[counter];
68
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
73
+ }
69
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
74
70
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
75
p = filter & PMXEVTYPER_P;
71
+
76
u = filter & PMXEVTYPER_U;
72
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
77
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
73
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
78
filtered = m != p;
74
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
79
}
75
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
80
76
+
81
+ if (counter != 31) {
77
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
82
+ /*
78
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
83
+ * If not checking PMCCNTR, ensure the counter is setup to an event we
79
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
84
+ * support
80
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
85
+ */
81
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
86
+ uint16_t event = filter & PMXEVTYPER_EVTCOUNT;
82
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
87
+ if (!event_supported(event)) {
83
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
88
+ return false;
84
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
89
+ }
85
+
90
+ }
86
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
91
+
87
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
92
return enabled && !prohibited && !filtered;
88
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
93
}
89
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
94
90
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
95
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_finish(CPUARMState *env)
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/mve_helper.c
93
+++ b/target/arm/mve_helper.c
94
@@ -XXX,XX +XXX,XX @@ static inline uint64_t do_urshr(uint64_t x, unsigned sh)
96
}
95
}
97
}
96
}
98
97
99
+static void pmevcntr_op_start(CPUARMState *env, uint8_t counter)
98
+static inline int64_t do_srshr(int64_t x, unsigned sh)
100
+{
99
+{
101
+
100
+ if (likely(sh < 64)) {
102
+ uint16_t event = env->cp15.c14_pmevtyper[counter] & PMXEVTYPER_EVTCOUNT;
101
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
103
+ uint64_t count = 0;
102
+ } else {
104
+ if (event_supported(event)) {
103
+ /* Rounding the sign bit always produces 0. */
105
+ uint16_t event_idx = supported_event_map[event];
104
+ return 0;
106
+ count = pm_events[event_idx].get_count(env);
107
+ }
108
+
109
+ if (pmu_counter_enabled(env, counter)) {
110
+ env->cp15.c14_pmevcntr[counter] =
111
+ count - env->cp15.c14_pmevcntr_delta[counter];
112
+ }
113
+ env->cp15.c14_pmevcntr_delta[counter] = count;
114
+}
115
+
116
+static void pmevcntr_op_finish(CPUARMState *env, uint8_t counter)
117
+{
118
+ if (pmu_counter_enabled(env, counter)) {
119
+ env->cp15.c14_pmevcntr_delta[counter] -=
120
+ env->cp15.c14_pmevcntr[counter];
121
+ }
105
+ }
122
+}
106
+}
123
+
107
+
124
void pmu_op_start(CPUARMState *env)
108
DO_VSHRN_ALL(vshrn, DO_SHR)
125
{
109
DO_VSHRN_ALL(vrshrn, do_urshr)
126
+ unsigned int i;
110
+
127
pmccntr_op_start(env);
111
+static inline int32_t do_sat_bhs(int64_t val, int64_t min, int64_t max,
128
+ for (i = 0; i < pmu_num_counters(env); i++) {
112
+ bool *satp)
129
+ pmevcntr_op_start(env, i);
130
+ }
131
}
132
133
void pmu_op_finish(CPUARMState *env)
134
{
135
+ unsigned int i;
136
pmccntr_op_finish(env);
137
+ for (i = 0; i < pmu_num_counters(env); i++) {
138
+ pmevcntr_op_finish(env, i);
139
+ }
140
}
141
142
void pmu_pre_el_change(ARMCPU *cpu, void *ignored)
143
@@ -XXX,XX +XXX,XX @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
144
env->cp15.c15_ccnt = 0;
145
}
146
147
+ if (value & PMCRP) {
148
+ unsigned int i;
149
+ for (i = 0; i < pmu_num_counters(env); i++) {
150
+ env->cp15.c14_pmevcntr[i] = 0;
151
+ }
152
+ }
153
+
154
/* only the DP, X, D and E bits are writable */
155
env->cp15.c9_pmcr &= ~0x39;
156
env->cp15.c9_pmcr |= (value & 0x39);
157
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_finish(CPUARMState *env)
158
{
159
}
160
161
+void pmevcntr_op_start(CPUARMState *env, uint8_t i)
162
+{
113
+{
163
+}
114
+ if (val > max) {
164
+
115
+ *satp = true;
165
+void pmevcntr_op_finish(CPUARMState *env, uint8_t i)
116
+ return max;
166
+{
117
+ } else if (val < min) {
167
+}
118
+ *satp = true;
168
+
119
+ return min;
169
void pmu_op_start(CPUARMState *env)
170
{
171
}
172
@@ -XXX,XX +XXX,XX @@ static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
173
env->cp15.c9_pmovsr |= value;
174
}
175
176
-static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
177
- uint64_t value)
178
+static void pmevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
179
+ uint64_t value, const uint8_t counter)
180
{
181
+ if (counter == 31) {
182
+ pmccfiltr_write(env, ri, value);
183
+ } else if (counter < pmu_num_counters(env)) {
184
+ pmevcntr_op_start(env, counter);
185
+
186
+ /*
187
+ * If this counter's event type is changing, store the current
188
+ * underlying count for the new type in c14_pmevcntr_delta[counter] so
189
+ * pmevcntr_op_finish has the correct baseline when it converts back to
190
+ * a delta.
191
+ */
192
+ uint16_t old_event = env->cp15.c14_pmevtyper[counter] &
193
+ PMXEVTYPER_EVTCOUNT;
194
+ uint16_t new_event = value & PMXEVTYPER_EVTCOUNT;
195
+ if (old_event != new_event) {
196
+ uint64_t count = 0;
197
+ if (event_supported(new_event)) {
198
+ uint16_t event_idx = supported_event_map[new_event];
199
+ count = pm_events[event_idx].get_count(env);
200
+ }
201
+ env->cp15.c14_pmevcntr_delta[counter] = count;
202
+ }
203
+
204
+ env->cp15.c14_pmevtyper[counter] = value & PMXEVTYPER_MASK;
205
+ pmevcntr_op_finish(env, counter);
206
+ }
207
/* Attempts to access PMXEVTYPER are CONSTRAINED UNPREDICTABLE when
208
* PMSELR value is equal to or greater than the number of implemented
209
* counters, but not equal to 0x1f. We opt to behave as a RAZ/WI.
210
*/
211
- if (env->cp15.c9_pmselr == 0x1f) {
212
- pmccfiltr_write(env, ri, value);
213
+}
214
+
215
+static uint64_t pmevtyper_read(CPUARMState *env, const ARMCPRegInfo *ri,
216
+ const uint8_t counter)
217
+{
218
+ if (counter == 31) {
219
+ return env->cp15.pmccfiltr_el0;
220
+ } else if (counter < pmu_num_counters(env)) {
221
+ return env->cp15.c14_pmevtyper[counter];
222
+ } else {
120
+ } else {
223
+ /*
121
+ return val;
224
+ * We opt to behave as a RAZ/WI when attempts to access PMXEVTYPER
225
+ * are CONSTRAINED UNPREDICTABLE. See comments in pmevtyper_write().
226
+ */
227
+ return 0;
228
}
229
}
230
231
+static void pmevtyper_writefn(CPUARMState *env, const ARMCPRegInfo *ri,
232
+ uint64_t value)
233
+{
234
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
235
+ pmevtyper_write(env, ri, value, counter);
236
+}
237
+
238
+static void pmevtyper_rawwrite(CPUARMState *env, const ARMCPRegInfo *ri,
239
+ uint64_t value)
240
+{
241
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
242
+ env->cp15.c14_pmevtyper[counter] = value;
243
+
244
+ /*
245
+ * pmevtyper_rawwrite is called between a pair of pmu_op_start and
246
+ * pmu_op_finish calls when loading saved state for a migration. Because
247
+ * we're potentially updating the type of event here, the value written to
248
+ * c14_pmevcntr_delta by the preceeding pmu_op_start call may be for a
249
+ * different counter type. Therefore, we need to set this value to the
250
+ * current count for the counter type we're writing so that pmu_op_finish
251
+ * has the correct count for its calculation.
252
+ */
253
+ uint16_t event = value & PMXEVTYPER_EVTCOUNT;
254
+ if (event_supported(event)) {
255
+ uint16_t event_idx = supported_event_map[event];
256
+ env->cp15.c14_pmevcntr_delta[counter] =
257
+ pm_events[event_idx].get_count(env);
258
+ }
122
+ }
259
+}
123
+}
260
+
124
+
261
+static uint64_t pmevtyper_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
125
+/* Saturating narrowing right shifts */
262
+{
126
+#define DO_VSHRN_SAT(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
263
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
127
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
264
+ return pmevtyper_read(env, ri, counter);
128
+ void *vm, uint32_t shift) \
265
+}
129
+ { \
266
+
130
+ LTYPE *m = vm; \
267
+static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
131
+ TYPE *d = vd; \
268
+ uint64_t value)
132
+ uint16_t mask = mve_element_mask(env); \
269
+{
133
+ bool qc = false; \
270
+ pmevtyper_write(env, ri, value, env->cp15.c9_pmselr & 31);
134
+ unsigned le; \
271
+}
135
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
272
+
136
+ bool sat = false; \
273
static uint64_t pmxevtyper_read(CPUARMState *env, const ARMCPRegInfo *ri)
137
+ TYPE r = FN(m[H##LESIZE(le)], shift, &sat); \
274
{
138
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
275
- /* We opt to behave as a RAZ/WI when attempts to access PMXEVTYPER
139
+ qc |= sat && (mask & 1 << (TOP * ESIZE)); \
276
- * are CONSTRAINED UNPREDICTABLE. See comments in pmxevtyper_write().
140
+ } \
277
+ return pmevtyper_read(env, ri, env->cp15.c9_pmselr & 31);
141
+ if (qc) { \
278
+}
142
+ env->vfp.qc[0] = qc; \
279
+
143
+ } \
280
+static void pmevcntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
144
+ mve_advance_vpt(env); \
281
+ uint64_t value, uint8_t counter)
282
+{
283
+ if (counter < pmu_num_counters(env)) {
284
+ pmevcntr_op_start(env, counter);
285
+ env->cp15.c14_pmevcntr[counter] = value;
286
+ pmevcntr_op_finish(env, counter);
287
+ }
145
+ }
288
+ /*
146
+
289
+ * We opt to behave as a RAZ/WI when attempts to access PM[X]EVCNTR
147
+#define DO_VSHRN_SAT_UB(BOP, TOP, FN) \
290
+ * are CONSTRAINED UNPREDICTABLE.
148
+ DO_VSHRN_SAT(BOP, false, 1, uint8_t, 2, uint16_t, FN) \
291
*/
149
+ DO_VSHRN_SAT(TOP, true, 1, uint8_t, 2, uint16_t, FN)
292
- if (env->cp15.c9_pmselr == 0x1f) {
150
+
293
- return env->cp15.pmccfiltr_el0;
151
+#define DO_VSHRN_SAT_UH(BOP, TOP, FN) \
294
+}
152
+ DO_VSHRN_SAT(BOP, false, 2, uint16_t, 4, uint32_t, FN) \
295
+
153
+ DO_VSHRN_SAT(TOP, true, 2, uint16_t, 4, uint32_t, FN)
296
+static uint64_t pmevcntr_read(CPUARMState *env, const ARMCPRegInfo *ri,
154
+
297
+ uint8_t counter)
155
+#define DO_VSHRN_SAT_SB(BOP, TOP, FN) \
298
+{
156
+ DO_VSHRN_SAT(BOP, false, 1, int8_t, 2, int16_t, FN) \
299
+ if (counter < pmu_num_counters(env)) {
157
+ DO_VSHRN_SAT(TOP, true, 1, int8_t, 2, int16_t, FN)
300
+ uint64_t ret;
158
+
301
+ pmevcntr_op_start(env, counter);
159
+#define DO_VSHRN_SAT_SH(BOP, TOP, FN) \
302
+ ret = env->cp15.c14_pmevcntr[counter];
160
+ DO_VSHRN_SAT(BOP, false, 2, int16_t, 4, int32_t, FN) \
303
+ pmevcntr_op_finish(env, counter);
161
+ DO_VSHRN_SAT(TOP, true, 2, int16_t, 4, int32_t, FN)
304
+ return ret;
162
+
305
} else {
163
+#define DO_SHRN_SB(N, M, SATP) \
306
+ /* We opt to behave as a RAZ/WI when attempts to access PM[X]EVCNTR
164
+ do_sat_bhs((int64_t)(N) >> (M), INT8_MIN, INT8_MAX, SATP)
307
+ * are CONSTRAINED UNPREDICTABLE. */
165
+#define DO_SHRN_UB(N, M, SATP) \
308
return 0;
166
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT8_MAX, SATP)
309
}
167
+#define DO_SHRUN_B(N, M, SATP) \
310
}
168
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT8_MAX, SATP)
311
169
+
312
+static void pmevcntr_writefn(CPUARMState *env, const ARMCPRegInfo *ri,
170
+#define DO_SHRN_SH(N, M, SATP) \
313
+ uint64_t value)
171
+ do_sat_bhs((int64_t)(N) >> (M), INT16_MIN, INT16_MAX, SATP)
314
+{
172
+#define DO_SHRN_UH(N, M, SATP) \
315
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
173
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT16_MAX, SATP)
316
+ pmevcntr_write(env, ri, value, counter);
174
+#define DO_SHRUN_H(N, M, SATP) \
317
+}
175
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT16_MAX, SATP)
318
+
176
+
319
+static uint64_t pmevcntr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
177
+#define DO_RSHRN_SB(N, M, SATP) \
320
+{
178
+ do_sat_bhs(do_srshr(N, M), INT8_MIN, INT8_MAX, SATP)
321
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
179
+#define DO_RSHRN_UB(N, M, SATP) \
322
+ return pmevcntr_read(env, ri, counter);
180
+ do_sat_bhs(do_urshr(N, M), 0, UINT8_MAX, SATP)
323
+}
181
+#define DO_RSHRUN_B(N, M, SATP) \
324
+
182
+ do_sat_bhs(do_srshr(N, M), 0, UINT8_MAX, SATP)
325
+static void pmevcntr_rawwrite(CPUARMState *env, const ARMCPRegInfo *ri,
183
+
326
+ uint64_t value)
184
+#define DO_RSHRN_SH(N, M, SATP) \
327
+{
185
+ do_sat_bhs(do_srshr(N, M), INT16_MIN, INT16_MAX, SATP)
328
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
186
+#define DO_RSHRN_UH(N, M, SATP) \
329
+ assert(counter < pmu_num_counters(env));
187
+ do_sat_bhs(do_urshr(N, M), 0, UINT16_MAX, SATP)
330
+ env->cp15.c14_pmevcntr[counter] = value;
188
+#define DO_RSHRUN_H(N, M, SATP) \
331
+ pmevcntr_write(env, ri, value, counter);
189
+ do_sat_bhs(do_srshr(N, M), 0, UINT16_MAX, SATP)
332
+}
190
+
333
+
191
+DO_VSHRN_SAT_SB(vqshrnb_sb, vqshrnt_sb, DO_SHRN_SB)
334
+static uint64_t pmevcntr_rawread(CPUARMState *env, const ARMCPRegInfo *ri)
192
+DO_VSHRN_SAT_SH(vqshrnb_sh, vqshrnt_sh, DO_SHRN_SH)
335
+{
193
+DO_VSHRN_SAT_UB(vqshrnb_ub, vqshrnt_ub, DO_SHRN_UB)
336
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
194
+DO_VSHRN_SAT_UH(vqshrnb_uh, vqshrnt_uh, DO_SHRN_UH)
337
+ assert(counter < pmu_num_counters(env));
195
+DO_VSHRN_SAT_SB(vqshrunbb, vqshruntb, DO_SHRUN_B)
338
+ return env->cp15.c14_pmevcntr[counter];
196
+DO_VSHRN_SAT_SH(vqshrunbh, vqshrunth, DO_SHRUN_H)
339
+}
197
+
340
+
198
+DO_VSHRN_SAT_SB(vqrshrnb_sb, vqrshrnt_sb, DO_RSHRN_SB)
341
+static void pmxevcntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
199
+DO_VSHRN_SAT_SH(vqrshrnb_sh, vqrshrnt_sh, DO_RSHRN_SH)
342
+ uint64_t value)
200
+DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
343
+{
201
+DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
344
+ pmevcntr_write(env, ri, value, env->cp15.c9_pmselr & 31);
202
+DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
345
+}
203
+DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
346
+
204
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
347
+static uint64_t pmxevcntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
205
index XXXXXXX..XXXXXXX 100644
348
+{
206
--- a/target/arm/translate-mve.c
349
+ return pmevcntr_read(env, ri, env->cp15.c9_pmselr & 31);
207
+++ b/target/arm/translate-mve.c
350
+}
208
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VSHRNB, vshrnb)
351
+
209
DO_2SHIFT_N(VSHRNT, vshrnt)
352
static void pmuserenr_write(CPUARMState *env, const ARMCPRegInfo *ri,
210
DO_2SHIFT_N(VRSHRNB, vrshrnb)
353
uint64_t value)
211
DO_2SHIFT_N(VRSHRNT, vrshrnt)
354
{
212
+DO_2SHIFT_N(VQSHRNB_S, vqshrnb_s)
355
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
213
+DO_2SHIFT_N(VQSHRNT_S, vqshrnt_s)
356
.fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0),
214
+DO_2SHIFT_N(VQSHRNB_U, vqshrnb_u)
357
.resetvalue = 0, },
215
+DO_2SHIFT_N(VQSHRNT_U, vqshrnt_u)
358
{ .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1,
216
+DO_2SHIFT_N(VQSHRUNB, vqshrunb)
359
- .access = PL0_RW, .type = ARM_CP_NO_RAW, .accessfn = pmreg_access,
217
+DO_2SHIFT_N(VQSHRUNT, vqshrunt)
360
+ .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
218
+DO_2SHIFT_N(VQRSHRNB_S, vqrshrnb_s)
361
+ .accessfn = pmreg_access,
219
+DO_2SHIFT_N(VQRSHRNT_S, vqrshrnt_s)
362
.writefn = pmxevtyper_write, .readfn = pmxevtyper_read },
220
+DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
363
{ .name = "PMXEVTYPER_EL0", .state = ARM_CP_STATE_AA64,
221
+DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
364
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 1,
222
+DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
365
- .access = PL0_RW, .type = ARM_CP_NO_RAW, .accessfn = pmreg_access,
223
+DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
366
+ .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
367
+ .accessfn = pmreg_access,
368
.writefn = pmxevtyper_write, .readfn = pmxevtyper_read },
369
- /* Unimplemented, RAZ/WI. */
370
{ .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2,
371
- .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0,
372
- .accessfn = pmreg_access_xevcntr },
373
+ .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
374
+ .accessfn = pmreg_access_xevcntr,
375
+ .writefn = pmxevcntr_write, .readfn = pmxevcntr_read },
376
+ { .name = "PMXEVCNTR_EL0", .state = ARM_CP_STATE_AA64,
377
+ .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 2,
378
+ .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
379
+ .accessfn = pmreg_access_xevcntr,
380
+ .writefn = pmxevcntr_write, .readfn = pmxevcntr_read },
381
{ .name = "PMUSERENR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 0,
382
.access = PL0_R | PL1_RW, .accessfn = access_tpm,
383
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmuserenr),
384
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
385
#endif
386
/* The only field of MDCR_EL2 that has a defined architectural reset value
387
* is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N; but we
388
- * don't impelment any PMU event counters, so using zero as a reset
389
+ * don't implement any PMU event counters, so using zero as a reset
390
* value for MDCR_EL2 is okay
391
*/
392
{ .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
393
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
394
* field as main ID register, and we implement only the cycle
395
* count register.
396
*/
397
+ unsigned int i, pmcrn = 0;
398
#ifndef CONFIG_USER_ONLY
399
ARMCPRegInfo pmcr = {
400
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
401
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
402
};
403
define_one_arm_cp_reg(cpu, &pmcr);
404
define_one_arm_cp_reg(cpu, &pmcr64);
405
+ for (i = 0; i < pmcrn; i++) {
406
+ char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
407
+ char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
408
+ char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
409
+ char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
410
+ ARMCPRegInfo pmev_regs[] = {
411
+ { .name = pmevcntr_name, .cp = 15, .crn = 15,
412
+ .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
413
+ .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
414
+ .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
415
+ .accessfn = pmreg_access },
416
+ { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
417
+ .opc0 = 3, .opc1 = 3, .crn = 15, .crm = 8 | (3 & (i >> 3)),
418
+ .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
419
+ .type = ARM_CP_IO,
420
+ .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
421
+ .raw_readfn = pmevcntr_rawread,
422
+ .raw_writefn = pmevcntr_rawwrite },
423
+ { .name = pmevtyper_name, .cp = 15, .crn = 15,
424
+ .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
425
+ .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
426
+ .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
427
+ .accessfn = pmreg_access },
428
+ { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
429
+ .opc0 = 3, .opc1 = 3, .crn = 15, .crm = 12 | (3 & (i >> 3)),
430
+ .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
431
+ .type = ARM_CP_IO,
432
+ .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
433
+ .raw_writefn = pmevtyper_rawwrite },
434
+ REGINFO_SENTINEL
435
+ };
436
+ define_arm_cp_regs(cpu, pmev_regs);
437
+ g_free(pmevcntr_name);
438
+ g_free(pmevcntr_el0_name);
439
+ g_free(pmevtyper_name);
440
+ g_free(pmevtyper_el0_name);
441
+ }
442
#endif
443
ARMCPRegInfo clidr = {
444
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
445
--
224
--
446
2.20.1
225
2.20.1
447
226
448
227
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE VSHLC insn, which performs a shift left of the
2
entire vector with carry in bits provided from a general purpose
3
register and carry out bits written back to that register.
2
4
3
The cryptographic internals are stubbed out for now,
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
but the enable and trap bits are checked.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-14-peter.maydell@linaro.org
8
---
9
target/arm/helper-mve.h | 2 ++
10
target/arm/mve.decode | 2 ++
11
target/arm/mve_helper.c | 38 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate-mve.c | 30 ++++++++++++++++++++++++++++++
13
4 files changed, 72 insertions(+)
5
14
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20190108223129.5570-6-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/Makefile.objs | 1 +
12
target/arm/helper-a64.h | 12 +++
13
target/arm/internals.h | 6 ++
14
target/arm/pauth_helper.c | 186 ++++++++++++++++++++++++++++++++++++++
15
4 files changed, 205 insertions(+)
16
create mode 100644 target/arm/pauth_helper.c
17
18
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/Makefile.objs
17
--- a/target/arm/helper-mve.h
21
+++ b/target/arm/Makefile.objs
18
+++ b/target/arm/helper-mve.h
22
@@ -XXX,XX +XXX,XX @@ obj-y += translate.o op_helper.o helper.o cpu.o
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
23
obj-y += neon_helper.o iwmmxt_helper.o vec_helper.o
20
DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
obj-y += gdbstub.o
21
DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o
22
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
+obj-$(TARGET_AARCH64) += pauth_helper.o
23
+
27
obj-y += crypto_helper.o
24
+DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
28
obj-$(CONFIG_SOFTMMU) += arm-powerctl.o
25
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
29
30
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
31
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper-a64.h
27
--- a/target/arm/mve.decode
33
+++ b/target/arm/helper-a64.h
28
+++ b/target/arm/mve.decode
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(advsimd_rinth, f16, f16, ptr)
29
@@ -XXX,XX +XXX,XX @@ VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
35
DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
30
VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
36
DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
31
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
37
DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
32
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
38
+
33
+
39
+DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64)
34
+VSHLC 111 0 1110 1 . 1 imm:5 ... 0 1111 1100 rdm:4 qd=%qd
40
+DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64)
35
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
41
+DEF_HELPER_FLAGS_3(pacda, TCG_CALL_NO_WG, i64, env, i64, i64)
42
+DEF_HELPER_FLAGS_3(pacdb, TCG_CALL_NO_WG, i64, env, i64, i64)
43
+DEF_HELPER_FLAGS_3(pacga, TCG_CALL_NO_WG, i64, env, i64, i64)
44
+DEF_HELPER_FLAGS_3(autia, TCG_CALL_NO_WG, i64, env, i64, i64)
45
+DEF_HELPER_FLAGS_3(autib, TCG_CALL_NO_WG, i64, env, i64, i64)
46
+DEF_HELPER_FLAGS_3(autda, TCG_CALL_NO_WG, i64, env, i64, i64)
47
+DEF_HELPER_FLAGS_3(autdb, TCG_CALL_NO_WG, i64, env, i64, i64)
48
+DEF_HELPER_FLAGS_2(xpaci, TCG_CALL_NO_RWG_SE, i64, env, i64)
49
+DEF_HELPER_FLAGS_2(xpacd, TCG_CALL_NO_RWG_SE, i64, env, i64)
50
diff --git a/target/arm/internals.h b/target/arm/internals.h
51
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/internals.h
37
--- a/target/arm/mve_helper.c
53
+++ b/target/arm/internals.h
38
+++ b/target/arm/mve_helper.c
54
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
39
@@ -XXX,XX +XXX,XX @@ DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
55
EC_CP14DTTRAP = 0x06,
40
DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
56
EC_ADVSIMDFPACCESSTRAP = 0x07,
41
DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
57
EC_FPIDTRAP = 0x08,
42
DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
58
+ EC_PACTRAP = 0x09,
43
+
59
EC_CP14RRTTRAP = 0x0c,
44
+uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
60
EC_ILLEGALSTATE = 0x0e,
45
+ uint32_t shift)
61
EC_AA32_SVC = 0x11,
62
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_sve_access_trap(void)
63
return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
64
}
65
66
+static inline uint32_t syn_pactrap(void)
67
+{
46
+{
68
+ return EC_PACTRAP << ARM_EL_EC_SHIFT;
47
+ uint32_t *d = vd;
69
+}
48
+ uint16_t mask = mve_element_mask(env);
49
+ unsigned e;
50
+ uint32_t r;
70
+
51
+
71
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
52
+ /*
72
{
53
+ * For each 32-bit element, we shift it left, bringing in the
73
return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
54
+ * low 'shift' bits of rdm at the bottom. Bits shifted out at
74
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
55
+ * the top become the new rdm, if the predicate mask permits.
75
new file mode 100644
56
+ * The final rdm value is returned to update the register.
76
index XXXXXXX..XXXXXXX
57
+ * shift == 0 here means "shift by 32 bits".
77
--- /dev/null
58
+ */
78
+++ b/target/arm/pauth_helper.c
59
+ if (shift == 0) {
79
@@ -XXX,XX +XXX,XX @@
60
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
80
+/*
61
+ r = rdm;
81
+ * ARM v8.3-PAuth Operations
62
+ if (mask & 1) {
82
+ *
63
+ rdm = d[H4(e)];
83
+ * Copyright (c) 2019 Linaro, Ltd.
64
+ }
84
+ *
65
+ mergemask(&d[H4(e)], r, mask);
85
+ * This library is free software; you can redistribute it and/or
66
+ }
86
+ * modify it under the terms of the GNU Lesser General Public
67
+ } else {
87
+ * License as published by the Free Software Foundation; either
68
+ uint32_t shiftmask = MAKE_64BIT_MASK(0, shift);
88
+ * version 2 of the License, or (at your option) any later version.
89
+ *
90
+ * This library is distributed in the hope that it will be useful,
91
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
92
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
93
+ * Lesser General Public License for more details.
94
+ *
95
+ * You should have received a copy of the GNU Lesser General Public
96
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
97
+ */
98
+
69
+
99
+#include "qemu/osdep.h"
70
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
100
+#include "cpu.h"
71
+ r = (d[H4(e)] << shift) | (rdm & shiftmask);
101
+#include "internals.h"
72
+ if (mask & 1) {
102
+#include "exec/exec-all.h"
73
+ rdm = d[H4(e)] >> (32 - shift);
103
+#include "exec/cpu_ldst.h"
74
+ }
104
+#include "exec/helper-proto.h"
75
+ mergemask(&d[H4(e)], r, mask);
105
+#include "tcg/tcg-gvec-desc.h"
106
+
107
+
108
+static uint64_t pauth_computepac(uint64_t data, uint64_t modifier,
109
+ ARMPACKey key)
110
+{
111
+ g_assert_not_reached(); /* FIXME */
112
+}
113
+
114
+static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
115
+ ARMPACKey *key, bool data)
116
+{
117
+ g_assert_not_reached(); /* FIXME */
118
+}
119
+
120
+static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
121
+ ARMPACKey *key, bool data, int keynumber)
122
+{
123
+ g_assert_not_reached(); /* FIXME */
124
+}
125
+
126
+static uint64_t pauth_strip(CPUARMState *env, uint64_t ptr, bool data)
127
+{
128
+ g_assert_not_reached(); /* FIXME */
129
+}
130
+
131
+static void QEMU_NORETURN pauth_trap(CPUARMState *env, int target_el,
132
+ uintptr_t ra)
133
+{
134
+ raise_exception_ra(env, EXCP_UDEF, syn_pactrap(), target_el, ra);
135
+}
136
+
137
+static void pauth_check_trap(CPUARMState *env, int el, uintptr_t ra)
138
+{
139
+ if (el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
140
+ uint64_t hcr = arm_hcr_el2_eff(env);
141
+ bool trap = !(hcr & HCR_API);
142
+ /* FIXME: ARMv8.1-VHE: trap only applies to EL1&0 regime. */
143
+ /* FIXME: ARMv8.3-NV: HCR_NV trap takes precedence for ERETA[AB]. */
144
+ if (trap) {
145
+ pauth_trap(env, 2, ra);
146
+ }
76
+ }
147
+ }
77
+ }
148
+ if (el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
78
+ mve_advance_vpt(env);
149
+ if (!(env->cp15.scr_el3 & SCR_API)) {
79
+ return rdm;
150
+ pauth_trap(env, 3, ra);
80
+}
151
+ }
81
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/translate-mve.c
84
+++ b/target/arm/translate-mve.c
85
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
86
DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
87
DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
88
DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
89
+
90
+static bool trans_VSHLC(DisasContext *s, arg_VSHLC *a)
91
+{
92
+ /*
93
+ * Whole Vector Left Shift with Carry. The carry is taken
94
+ * from a general purpose register and written back there.
95
+ * An imm of 0 means "shift by 32".
96
+ */
97
+ TCGv_ptr qd;
98
+ TCGv_i32 rdm;
99
+
100
+ if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd)) {
101
+ return false;
152
+ }
102
+ }
153
+}
103
+ if (a->rdm == 13 || a->rdm == 15) {
104
+ /* CONSTRAINED UNPREDICTABLE: we UNDEF */
105
+ return false;
106
+ }
107
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
108
+ return true;
109
+ }
154
+
110
+
155
+static bool pauth_key_enabled(CPUARMState *env, int el, uint32_t bit)
111
+ qd = mve_qreg_ptr(a->qd);
156
+{
112
+ rdm = load_reg(s, a->rdm);
157
+ uint32_t sctlr;
113
+ gen_helper_mve_vshlc(rdm, cpu_env, qd, rdm, tcg_constant_i32(a->imm));
158
+ if (el == 0) {
114
+ store_reg(s, a->rdm, rdm);
159
+ /* FIXME: ARMv8.1-VHE S2 translation regime. */
115
+ tcg_temp_free_ptr(qd);
160
+ sctlr = env->cp15.sctlr_el[1];
116
+ mve_update_eci(s);
161
+ } else {
117
+ return true;
162
+ sctlr = env->cp15.sctlr_el[el];
163
+ }
164
+ return (sctlr & bit) != 0;
165
+}
166
+
167
+uint64_t HELPER(pacia)(CPUARMState *env, uint64_t x, uint64_t y)
168
+{
169
+ int el = arm_current_el(env);
170
+ if (!pauth_key_enabled(env, el, SCTLR_EnIA)) {
171
+ return x;
172
+ }
173
+ pauth_check_trap(env, el, GETPC());
174
+ return pauth_addpac(env, x, y, &env->apia_key, false);
175
+}
176
+
177
+uint64_t HELPER(pacib)(CPUARMState *env, uint64_t x, uint64_t y)
178
+{
179
+ int el = arm_current_el(env);
180
+ if (!pauth_key_enabled(env, el, SCTLR_EnIB)) {
181
+ return x;
182
+ }
183
+ pauth_check_trap(env, el, GETPC());
184
+ return pauth_addpac(env, x, y, &env->apib_key, false);
185
+}
186
+
187
+uint64_t HELPER(pacda)(CPUARMState *env, uint64_t x, uint64_t y)
188
+{
189
+ int el = arm_current_el(env);
190
+ if (!pauth_key_enabled(env, el, SCTLR_EnDA)) {
191
+ return x;
192
+ }
193
+ pauth_check_trap(env, el, GETPC());
194
+ return pauth_addpac(env, x, y, &env->apda_key, true);
195
+}
196
+
197
+uint64_t HELPER(pacdb)(CPUARMState *env, uint64_t x, uint64_t y)
198
+{
199
+ int el = arm_current_el(env);
200
+ if (!pauth_key_enabled(env, el, SCTLR_EnDB)) {
201
+ return x;
202
+ }
203
+ pauth_check_trap(env, el, GETPC());
204
+ return pauth_addpac(env, x, y, &env->apdb_key, true);
205
+}
206
+
207
+uint64_t HELPER(pacga)(CPUARMState *env, uint64_t x, uint64_t y)
208
+{
209
+ uint64_t pac;
210
+
211
+ pauth_check_trap(env, arm_current_el(env), GETPC());
212
+ pac = pauth_computepac(x, y, env->apga_key);
213
+
214
+ return pac & 0xffffffff00000000ull;
215
+}
216
+
217
+uint64_t HELPER(autia)(CPUARMState *env, uint64_t x, uint64_t y)
218
+{
219
+ int el = arm_current_el(env);
220
+ if (!pauth_key_enabled(env, el, SCTLR_EnIA)) {
221
+ return x;
222
+ }
223
+ pauth_check_trap(env, el, GETPC());
224
+ return pauth_auth(env, x, y, &env->apia_key, false, 0);
225
+}
226
+
227
+uint64_t HELPER(autib)(CPUARMState *env, uint64_t x, uint64_t y)
228
+{
229
+ int el = arm_current_el(env);
230
+ if (!pauth_key_enabled(env, el, SCTLR_EnIB)) {
231
+ return x;
232
+ }
233
+ pauth_check_trap(env, el, GETPC());
234
+ return pauth_auth(env, x, y, &env->apib_key, false, 1);
235
+}
236
+
237
+uint64_t HELPER(autda)(CPUARMState *env, uint64_t x, uint64_t y)
238
+{
239
+ int el = arm_current_el(env);
240
+ if (!pauth_key_enabled(env, el, SCTLR_EnDA)) {
241
+ return x;
242
+ }
243
+ pauth_check_trap(env, el, GETPC());
244
+ return pauth_auth(env, x, y, &env->apda_key, true, 0);
245
+}
246
+
247
+uint64_t HELPER(autdb)(CPUARMState *env, uint64_t x, uint64_t y)
248
+{
249
+ int el = arm_current_el(env);
250
+ if (!pauth_key_enabled(env, el, SCTLR_EnDB)) {
251
+ return x;
252
+ }
253
+ pauth_check_trap(env, el, GETPC());
254
+ return pauth_auth(env, x, y, &env->apdb_key, true, 1);
255
+}
256
+
257
+uint64_t HELPER(xpaci)(CPUARMState *env, uint64_t a)
258
+{
259
+ return pauth_strip(env, a, false);
260
+}
261
+
262
+uint64_t HELPER(xpacd)(CPUARMState *env, uint64_t a)
263
+{
264
+ return pauth_strip(env, a, true);
265
+}
118
+}
266
--
119
--
267
2.20.1
120
2.20.1
268
121
269
122
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE VADDLV insn; this is similar to VADDV, except
2
that it accumulates 32-bit elements into a 64-bit accumulator
3
stored in a pair of general-purpose registers.
2
4
3
Not that there are any stores involved, but why argue with ARM's
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
naming convention.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-15-peter.maydell@linaro.org
8
---
9
target/arm/helper-mve.h | 3 ++
10
target/arm/mve.decode | 6 +++-
11
target/arm/mve_helper.c | 19 ++++++++++++
12
target/arm/translate-mve.c | 63 ++++++++++++++++++++++++++++++++++++++
13
4 files changed, 90 insertions(+), 1 deletion(-)
5
14
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20190108223129.5570-15-richard.henderson@linaro.org
9
[fixed trivial comment nit]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-a64.c | 61 ++++++++++++++++++++++++++++++++++++++
13
1 file changed, 61 insertions(+)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
17
--- a/target/arm/helper-mve.h
18
+++ b/target/arm/translate-a64.c
18
+++ b/target/arm/helper-mve.h
19
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
20
s->be_data | size | MO_ALIGN);
20
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
21
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
22
23
+DEF_HELPER_FLAGS_3(mve_vaddlv_s, TCG_CALL_NO_WG, i64, env, ptr, i64)
24
+DEF_HELPER_FLAGS_3(mve_vaddlv_u, TCG_CALL_NO_WG, i64, env, ptr, i64)
25
+
26
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
27
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
28
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
29
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/mve.decode
32
+++ b/target/arm/mve.decode
33
@@ -XXX,XX +XXX,XX @@ VQDMULH_scalar 1110 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
34
VQRDMULH_scalar 1111 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
35
36
# Vector add across vector
37
-VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
38
+{
39
+ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
40
+ VADDLV 111 u:1 1110 1 ... 1001 ... 0 1111 00 a:1 0 qm:3 0 \
41
+ rdahi=%rdahi rdalo=%rdalo
42
+}
43
44
# Predicate operations
45
%mask_22_13 22:1 13:3
46
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/mve_helper.c
49
+++ b/target/arm/mve_helper.c
50
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvub, 1, uint8_t)
51
DO_VADDV(vaddvuh, 2, uint16_t)
52
DO_VADDV(vaddvuw, 4, uint32_t)
53
54
+#define DO_VADDLV(OP, TYPE, LTYPE) \
55
+ uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vm, \
56
+ uint64_t ra) \
57
+ { \
58
+ uint16_t mask = mve_element_mask(env); \
59
+ unsigned e; \
60
+ TYPE *m = vm; \
61
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
62
+ if (mask & 1) { \
63
+ ra += (LTYPE)m[H4(e)]; \
64
+ } \
65
+ } \
66
+ mve_advance_vpt(env); \
67
+ return ra; \
68
+ } \
69
+
70
+DO_VADDLV(vaddlv_s, int32_t, int64_t)
71
+DO_VADDLV(vaddlv_u, uint32_t, uint64_t)
72
+
73
/* Shifts by immediate */
74
#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
75
void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
76
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/translate-mve.c
79
+++ b/target/arm/translate-mve.c
80
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
81
return true;
21
}
82
}
22
83
23
+/*
84
+static bool trans_VADDLV(DisasContext *s, arg_VADDLV *a)
24
+ * PAC memory operations
25
+ *
26
+ * 31 30 27 26 24 22 21 12 11 10 5 0
27
+ * +------+-------+---+-----+-----+---+--------+---+---+----+-----+
28
+ * | size | 1 1 1 | V | 0 0 | M S | 1 | imm9 | W | 1 | Rn | Rt |
29
+ * +------+-------+---+-----+-----+---+--------+---+---+----+-----+
30
+ *
31
+ * Rt: the result register
32
+ * Rn: base address or SP
33
+ * V: vector flag (always 0 as of v8.3)
34
+ * M: clear for key DA, set for key DB
35
+ * W: pre-indexing flag
36
+ * S: sign for imm9.
37
+ */
38
+static void disas_ldst_pac(DisasContext *s, uint32_t insn,
39
+ int size, int rt, bool is_vector)
40
+{
85
+{
41
+ int rn = extract32(insn, 5, 5);
86
+ /*
42
+ bool is_wback = extract32(insn, 11, 1);
87
+ * Vector Add Long Across Vector: accumulate the 32-bit
43
+ bool use_key_a = !extract32(insn, 23, 1);
88
+ * elements of the vector into a 64-bit result stored in
44
+ int offset;
89
+ * a pair of general-purpose registers.
45
+ TCGv_i64 tcg_addr, tcg_rt;
90
+ * No need to check Qm's bank: it is only 3 bits in decode.
91
+ */
92
+ TCGv_ptr qm;
93
+ TCGv_i64 rda;
94
+ TCGv_i32 rdalo, rdahi;
46
+
95
+
47
+ if (size != 3 || is_vector || !dc_isar_feature(aa64_pauth, s)) {
96
+ if (!dc_isar_feature(aa32_mve, s)) {
48
+ unallocated_encoding(s);
97
+ return false;
49
+ return;
98
+ }
99
+ /*
100
+ * rdahi == 13 is UNPREDICTABLE; rdahi == 15 is a related
101
+ * encoding; rdalo always has bit 0 clear so cannot be 13 or 15.
102
+ */
103
+ if (a->rdahi == 13 || a->rdahi == 15) {
104
+ return false;
105
+ }
106
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
107
+ return true;
50
+ }
108
+ }
51
+
109
+
52
+ if (rn == 31) {
110
+ /*
53
+ gen_check_sp_alignment(s);
111
+ * This insn is subject to beat-wise execution. Partial execution
54
+ }
112
+ * of an A=0 (no-accumulate) insn which does not execute the first
55
+ tcg_addr = read_cpu_reg_sp(s, rn, 1);
113
+ * beat must start with the current value of RdaHi:RdaLo, not zero.
56
+
114
+ */
57
+ if (s->pauth_active) {
115
+ if (a->a || mve_skip_first_beat(s)) {
58
+ if (use_key_a) {
116
+ /* Accumulate input from RdaHi:RdaLo */
59
+ gen_helper_autda(tcg_addr, cpu_env, tcg_addr, cpu_X[31]);
117
+ rda = tcg_temp_new_i64();
60
+ } else {
118
+ rdalo = load_reg(s, a->rdalo);
61
+ gen_helper_autdb(tcg_addr, cpu_env, tcg_addr, cpu_X[31]);
119
+ rdahi = load_reg(s, a->rdahi);
62
+ }
120
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
121
+ tcg_temp_free_i32(rdalo);
122
+ tcg_temp_free_i32(rdahi);
123
+ } else {
124
+ /* Accumulate starting at zero */
125
+ rda = tcg_const_i64(0);
63
+ }
126
+ }
64
+
127
+
65
+ /* Form the 10-bit signed, scaled offset. */
128
+ qm = mve_qreg_ptr(a->qm);
66
+ offset = (extract32(insn, 22, 1) << 9) | extract32(insn, 12, 9);
129
+ if (a->u) {
67
+ offset = sextract32(offset << size, 0, 10 + size);
130
+ gen_helper_mve_vaddlv_u(rda, cpu_env, qm, rda);
68
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
131
+ } else {
132
+ gen_helper_mve_vaddlv_s(rda, cpu_env, qm, rda);
133
+ }
134
+ tcg_temp_free_ptr(qm);
69
+
135
+
70
+ tcg_rt = cpu_reg(s, rt);
136
+ rdalo = tcg_temp_new_i32();
71
+
137
+ rdahi = tcg_temp_new_i32();
72
+ do_gpr_ld(s, tcg_rt, tcg_addr, size, /* is_signed */ false,
138
+ tcg_gen_extrl_i64_i32(rdalo, rda);
73
+ /* extend */ false, /* iss_valid */ !is_wback,
139
+ tcg_gen_extrh_i64_i32(rdahi, rda);
74
+ /* iss_srt */ rt, /* iss_sf */ true, /* iss_ar */ false);
140
+ store_reg(s, a->rdalo, rdalo);
75
+
141
+ store_reg(s, a->rdahi, rdahi);
76
+ if (is_wback) {
142
+ tcg_temp_free_i64(rda);
77
+ tcg_gen_mov_i64(cpu_reg_sp(s, rn), tcg_addr);
143
+ mve_update_eci(s);
78
+ }
144
+ return true;
79
+}
145
+}
80
+
146
+
81
/* Load/store register (all forms) */
147
static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
82
static void disas_ldst_reg(DisasContext *s, uint32_t insn)
83
{
148
{
84
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg(DisasContext *s, uint32_t insn)
149
TCGv_ptr qd;
85
case 2:
86
disas_ldst_reg_roffset(s, insn, opc, size, rt, is_vector);
87
return;
88
+ default:
89
+ disas_ldst_pac(s, insn, size, rt, is_vector);
90
+ return;
91
}
92
break;
93
case 1:
94
--
150
--
95
2.20.1
151
2.20.1
96
152
97
153
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
The MVE extension to v8.1M includes some new shift instructions which
2
2
sit entirely within the non-coprocessor part of the encoding space
3
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
3
and which operate only on general-purpose registers. They take up
4
the space which was previously UNPREDICTABLE MOVS and ORRS encodings
5
with Rm == 13 or 15.
6
7
Implement the long shifts by immediate, which perform shifts on a
8
pair of general-purpose registers treated as a 64-bit quantity, with
9
an immediate shift count between 1 and 32.
10
11
Awkwardly, because the MOVS and ORRS trans functions do not UNDEF for
12
the Rm==13,15 case, we need to explicitly emit code to UNDEF for the
13
cases where v8.1M now requires that. (Trying to change MOVS and ORRS
14
is too difficult, because the functions that generate the code are
15
shared between a dozen different kinds of arithmetic or logical
16
instruction for all A32, T16 and T32 encodings, and for some insns
17
and some encodings Rm==13,15 are valid.)
18
19
We make the helper functions we need for UQSHLL and SQSHLL take
20
a 32-bit value which the helper casts to int8_t because we'll need
21
these helpers also for the shift-by-register insns, where the shift
22
count might be < 0 or > 32.
23
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20181211151945.29137-14-aaron@os.amperecomputing.com
26
Message-id: 20210628135835.6690-16-peter.maydell@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
27
---
8
target/arm/helper.c | 39 +++++++++++++++++++++++++++++++++++++--
28
target/arm/helper-mve.h | 3 ++
9
1 file changed, 37 insertions(+), 2 deletions(-)
29
target/arm/translate.h | 1 +
10
30
target/arm/t32.decode | 28 +++++++++++++
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
target/arm/mve_helper.c | 10 +++++
12
index XXXXXXX..XXXXXXX 100644
32
target/arm/translate.c | 90 +++++++++++++++++++++++++++++++++++++++++
13
--- a/target/arm/helper.c
33
5 files changed, 132 insertions(+)
14
+++ b/target/arm/helper.c
34
15
@@ -XXX,XX +XXX,XX @@ static bool event_always_supported(CPUARMState *env)
35
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper-mve.h
38
+++ b/target/arm/helper-mve.h
39
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
42
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
43
+
44
+DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
45
+DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
46
diff --git a/target/arm/translate.h b/target/arm/translate.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate.h
49
+++ b/target/arm/translate.h
50
@@ -XXX,XX +XXX,XX @@ typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
51
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
52
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
53
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
54
+typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
55
56
/**
57
* arm_tbflags_from_tb:
58
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/t32.decode
61
+++ b/target/arm/t32.decode
62
@@ -XXX,XX +XXX,XX @@
63
&mcr !extern cp opc1 crn crm opc2 rt
64
&mcrr !extern cp opc1 crm rt rt2
65
66
+&mve_shl_ri rdalo rdahi shim
67
+
68
+# rdahi: bits [3:1] from insn, bit 0 is 1
69
+# rdalo: bits [3:1] from insn, bit 0 is 0
70
+%rdahi_9 9:3 !function=times_2_plus_1
71
+%rdalo_17 17:3 !function=times_2
72
+
73
# Data-processing (register)
74
75
%imm5_12_6 12:3 6:2
76
@@ -XXX,XX +XXX,XX @@
77
@S_xrr_shi ....... .... . rn:4 .... .... .. shty:2 rm:4 \
78
&s_rrr_shi shim=%imm5_12_6 s=1 rd=0
79
80
+@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
81
+ &mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
82
+
83
{
84
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
85
AND_rrri 1110101 0000 . .... 0 ... .... .... .... @s_rrr_shi
86
}
87
BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
88
{
89
+ # The v8.1M MVE shift insns overlap in encoding with MOVS/ORRS
90
+ # and are distinguished by having Rm==13 or 15. Those are UNPREDICTABLE
91
+ # cases for MOVS/ORRS. We decode the MVE cases first, ensuring that
92
+ # they explicitly call unallocated_encoding() for cases that must UNDEF
93
+ # (eg "using a new shift insn on a v8.1M CPU without MVE"), and letting
94
+ # the rest fall through (where ORR_rrri and MOV_rxri will end up
95
+ # handling them as r13 and r15 accesses with the same semantics as A32).
96
+ [
97
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
98
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
99
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
100
+
101
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
102
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
103
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
104
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
105
+ ]
106
+
107
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
108
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
109
}
110
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/target/arm/mve_helper.c
113
+++ b/target/arm/mve_helper.c
114
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
115
mve_advance_vpt(env);
116
return rdm;
117
}
118
+
119
+uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
120
+{
121
+ return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
122
+}
123
+
124
+uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
125
+{
126
+ return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
127
+}
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/target/arm/translate.c
131
+++ b/target/arm/translate.c
132
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
16
return true;
133
return true;
17
}
134
}
18
135
19
+static uint64_t swinc_get_count(CPUARMState *env)
136
+/*
20
+{
137
+ * v8.1M MVE wide-shifts
21
+ /*
138
+ */
22
+ * SW_INCR events are written directly to the pmevcntr's by writes to
139
+static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
23
+ * PMSWINC, so there is no underlying count maintained by the PMU itself
140
+ WideShiftImmFn *fn)
24
+ */
141
+{
25
+ return 0;
142
+ TCGv_i64 rda;
143
+ TCGv_i32 rdalo, rdahi;
144
+
145
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
146
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
147
+ return false;
148
+ }
149
+ if (a->rdahi == 15) {
150
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
151
+ return false;
152
+ }
153
+ if (!dc_isar_feature(aa32_mve, s) ||
154
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
155
+ a->rdahi == 13) {
156
+ /* RdaHi == 13 is UNPREDICTABLE; we choose to UNDEF */
157
+ unallocated_encoding(s);
158
+ return true;
159
+ }
160
+
161
+ if (a->shim == 0) {
162
+ a->shim = 32;
163
+ }
164
+
165
+ rda = tcg_temp_new_i64();
166
+ rdalo = load_reg(s, a->rdalo);
167
+ rdahi = load_reg(s, a->rdahi);
168
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
169
+
170
+ fn(rda, rda, a->shim);
171
+
172
+ tcg_gen_extrl_i64_i32(rdalo, rda);
173
+ tcg_gen_extrh_i64_i32(rdahi, rda);
174
+ store_reg(s, a->rdalo, rdalo);
175
+ store_reg(s, a->rdahi, rdahi);
176
+ tcg_temp_free_i64(rda);
177
+
178
+ return true;
179
+}
180
+
181
+static bool trans_ASRL_ri(DisasContext *s, arg_mve_shl_ri *a)
182
+{
183
+ return do_mve_shl_ri(s, a, tcg_gen_sari_i64);
184
+}
185
+
186
+static bool trans_LSLL_ri(DisasContext *s, arg_mve_shl_ri *a)
187
+{
188
+ return do_mve_shl_ri(s, a, tcg_gen_shli_i64);
189
+}
190
+
191
+static bool trans_LSRL_ri(DisasContext *s, arg_mve_shl_ri *a)
192
+{
193
+ return do_mve_shl_ri(s, a, tcg_gen_shri_i64);
194
+}
195
+
196
+static void gen_mve_sqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
197
+{
198
+ gen_helper_mve_sqshll(r, cpu_env, n, tcg_constant_i32(shift));
199
+}
200
+
201
+static bool trans_SQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
202
+{
203
+ return do_mve_shl_ri(s, a, gen_mve_sqshll);
204
+}
205
+
206
+static void gen_mve_uqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
207
+{
208
+ gen_helper_mve_uqshll(r, cpu_env, n, tcg_constant_i32(shift));
209
+}
210
+
211
+static bool trans_UQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
212
+{
213
+ return do_mve_shl_ri(s, a, gen_mve_uqshll);
214
+}
215
+
216
+static bool trans_SRSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
217
+{
218
+ return do_mve_shl_ri(s, a, gen_srshr64_i64);
219
+}
220
+
221
+static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
222
+{
223
+ return do_mve_shl_ri(s, a, gen_urshr64_i64);
26
+}
224
+}
27
+
225
+
28
/*
226
/*
29
* Return the underlying cycle count for the PMU cycle counters. If we're in
227
* Multiply and multiply accumulate
30
* usermode, simply return 0.
228
*/
31
@@ -XXX,XX +XXX,XX @@ static uint64_t instructions_get_count(CPUARMState *env)
32
#endif
33
34
static const pm_event pm_events[] = {
35
+ { .number = 0x000, /* SW_INCR */
36
+ .supported = event_always_supported,
37
+ .get_count = swinc_get_count,
38
+ },
39
#ifndef CONFIG_USER_ONLY
40
{ .number = 0x008, /* INST_RETIRED, Instruction architecturally executed */
41
.supported = instructions_supported,
42
@@ -XXX,XX +XXX,XX @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
43
pmu_op_finish(env);
44
}
45
46
+static void pmswinc_write(CPUARMState *env, const ARMCPRegInfo *ri,
47
+ uint64_t value)
48
+{
49
+ unsigned int i;
50
+ for (i = 0; i < pmu_num_counters(env); i++) {
51
+ /* Increment a counter's count iff: */
52
+ if ((value & (1 << i)) && /* counter's bit is set */
53
+ /* counter is enabled and not filtered */
54
+ pmu_counter_enabled(env, i) &&
55
+ /* counter is SW_INCR */
56
+ (env->cp15.c14_pmevtyper[i] & PMXEVTYPER_EVTCOUNT) == 0x0) {
57
+ pmevcntr_op_start(env, i);
58
+ env->cp15.c14_pmevcntr[i]++;
59
+ pmevcntr_op_finish(env, i);
60
+ }
61
+ }
62
+}
63
+
64
static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
65
{
66
uint64_t ret;
67
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
68
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
69
.writefn = pmovsr_write,
70
.raw_writefn = raw_write },
71
- /* Unimplemented so WI. */
72
{ .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
73
- .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NOP },
74
+ .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW,
75
+ .writefn = pmswinc_write },
76
+ { .name = "PMSWINC_EL0", .state = ARM_CP_STATE_AA64,
77
+ .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 4,
78
+ .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW,
79
+ .writefn = pmswinc_write },
80
{ .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
81
.access = PL0_RW, .type = ARM_CP_ALIAS,
82
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr),
83
--
229
--
84
2.20.1
230
2.20.1
85
231
86
232
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE long shifts by register, which perform shifts on a
2
2
pair of general-purpose registers treated as a 64-bit quantity, with
3
We will shortly want to talk about TBI as it relates to data.
3
the shift count in another general-purpose register, which might be
4
Passing around a pair of variables is less convenient than a
4
either positive or negative.
5
single variable.
5
6
6
Like the long-shifts-by-immediate, these encodings sit in the space
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
that was previously the UNPREDICTABLE MOVS/ORRS with Rm==13,15.
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Because LSLL_rr and ASRL_rr overlap with both MOV_rxri/ORR_rrri and
9
Message-id: 20190108223129.5570-20-richard.henderson@linaro.org
9
also with CSEL (as one of the previously-UNPREDICTABLE Rm==13 cases),
10
we have to move the CSEL pattern into the same decodetree group.
11
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210628135835.6690-17-peter.maydell@linaro.org
11
---
15
---
12
target/arm/cpu.h | 3 +--
16
target/arm/helper-mve.h | 6 +++
13
target/arm/translate.h | 3 +--
17
target/arm/translate.h | 1 +
14
target/arm/helper.c | 5 ++---
18
target/arm/t32.decode | 16 +++++--
15
target/arm/translate-a64.c | 13 +++++++------
19
target/arm/mve_helper.c | 93 +++++++++++++++++++++++++++++++++++++++++
16
4 files changed, 11 insertions(+), 13 deletions(-)
20
target/arm/translate.c | 69 ++++++++++++++++++++++++++++++
17
21
5 files changed, 182 insertions(+), 3 deletions(-)
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
19
index XXXXXXX..XXXXXXX 100644
23
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
20
--- a/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX 100644
21
+++ b/target/arm/cpu.h
25
--- a/target/arm/helper-mve.h
22
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, HANDLER, 21, 1)
26
+++ b/target/arm/helper-mve.h
23
FIELD(TBFLAG_A32, STACKCHECK, 22, 1)
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
28
25
/* Bit usage when in AArch64 state */
29
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
26
-FIELD(TBFLAG_A64, TBI0, 0, 1)
30
27
-FIELD(TBFLAG_A64, TBI1, 1, 1)
31
+DEF_HELPER_FLAGS_3(mve_sshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
28
+FIELD(TBFLAG_A64, TBII, 0, 2)
32
+DEF_HELPER_FLAGS_3(mve_ushll, TCG_CALL_NO_RWG, i64, env, i64, i32)
29
FIELD(TBFLAG_A64, SVEEXC_EL, 2, 2)
33
DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
30
FIELD(TBFLAG_A64, ZCR_LEN, 4, 4)
34
DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
31
FIELD(TBFLAG_A64, PAUTH_ACTIVE, 8, 1)
35
+DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
36
+DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
37
+DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
38
+DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
32
diff --git a/target/arm/translate.h b/target/arm/translate.h
39
diff --git a/target/arm/translate.h b/target/arm/translate.h
33
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate.h
41
--- a/target/arm/translate.h
35
+++ b/target/arm/translate.h
42
+++ b/target/arm/translate.h
36
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
43
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
37
int user;
44
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
38
#endif
45
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
39
ARMMMUIdx mmu_idx; /* MMU index to use for normal loads/stores */
46
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
40
- bool tbi0; /* TBI0 for EL0/1 or TBI for EL2/3 */
47
+typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
41
- bool tbi1; /* TBI1 for EL0/1, not used for EL2/3 */
48
42
+ uint8_t tbii; /* TBI1|TBI0 for EL0/1 or TBI for EL2/3 */
49
/**
43
bool ns; /* Use non-secure CPREG bank on access */
50
* arm_tbflags_from_tb:
44
int fp_excp_el; /* FP exception EL or 0 if enabled */
51
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
45
int sve_excp_el; /* SVE exception EL or 0 if enabled */
52
index XXXXXXX..XXXXXXX 100644
46
diff --git a/target/arm/helper.c b/target/arm/helper.c
53
--- a/target/arm/t32.decode
47
index XXXXXXX..XXXXXXX 100644
54
+++ b/target/arm/t32.decode
48
--- a/target/arm/helper.c
55
@@ -XXX,XX +XXX,XX @@
49
+++ b/target/arm/helper.c
56
&mcrr !extern cp opc1 crm rt rt2
50
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
57
51
*pc = env->pc;
58
&mve_shl_ri rdalo rdahi shim
52
flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
59
+&mve_shl_rr rdalo rdahi rm
53
/* Get control bits for tagged addresses */
60
54
- flags = FIELD_DP32(flags, TBFLAG_A64, TBI0,
61
# rdahi: bits [3:1] from insn, bit 0 is 1
55
+ flags = FIELD_DP32(flags, TBFLAG_A64, TBII,
62
# rdalo: bits [3:1] from insn, bit 0 is 0
56
+ (arm_regime_tbi1(env, mmu_idx) << 1) |
63
@@ -XXX,XX +XXX,XX @@
57
arm_regime_tbi0(env, mmu_idx));
64
58
- flags = FIELD_DP32(flags, TBFLAG_A64, TBI1,
65
@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
59
- arm_regime_tbi1(env, mmu_idx));
66
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
60
67
+@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
61
if (cpu_isar_feature(aa64_sve, cpu)) {
68
+ &mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
62
int sve_el = sve_exception_el(env, current_el);
69
63
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
70
{
64
index XXXXXXX..XXXXXXX 100644
71
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
65
--- a/target/arm/translate-a64.c
72
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
66
+++ b/target/arm/translate-a64.c
73
URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
67
@@ -XXX,XX +XXX,XX @@ void gen_a64_set_pc_im(uint64_t val)
74
SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
75
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
76
+
77
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
78
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
79
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
80
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
81
+ UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
82
+ SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
83
]
84
85
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
86
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
87
+
88
+ # v8.1M CSEL and friends
89
+ CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
90
}
91
{
92
MVN_rxri 1110101 0011 . 1111 0 ... .... .... .... @s_rxr_shi
93
@@ -XXX,XX +XXX,XX @@ SBC_rrri 1110101 1011 . .... 0 ... .... .... .... @s_rrr_shi
94
}
95
RSB_rrri 1110101 1110 . .... 0 ... .... .... .... @s_rrr_shi
96
97
-# v8.1M CSEL and friends
98
-CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
99
-
100
# Data-processing (register-shifted register)
101
102
MOV_rxrr 1111 1010 0 shty:2 s:1 rm:4 1111 rd:4 0000 rs:4 \
103
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/target/arm/mve_helper.c
106
+++ b/target/arm/mve_helper.c
107
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
108
return rdm;
109
}
110
111
+uint64_t HELPER(mve_sshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
112
+{
113
+ return do_sqrshl_d(n, -(int8_t)shift, false, NULL);
114
+}
115
+
116
+uint64_t HELPER(mve_ushll)(CPUARMState *env, uint64_t n, uint32_t shift)
117
+{
118
+ return do_uqrshl_d(n, (int8_t)shift, false, NULL);
119
+}
120
+
121
uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
122
{
123
return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
124
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
125
{
126
return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
127
}
128
+
129
+uint64_t HELPER(mve_sqrshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
130
+{
131
+ return do_sqrshl_d(n, -(int8_t)shift, true, &env->QF);
132
+}
133
+
134
+uint64_t HELPER(mve_uqrshll)(CPUARMState *env, uint64_t n, uint32_t shift)
135
+{
136
+ return do_uqrshl_d(n, (int8_t)shift, true, &env->QF);
137
+}
138
+
139
+/* Operate on 64-bit values, but saturate at 48 bits */
140
+static inline int64_t do_sqrshl48_d(int64_t src, int64_t shift,
141
+ bool round, uint32_t *sat)
142
+{
143
+ if (shift <= -48) {
144
+ /* Rounding the sign bit always produces 0. */
145
+ if (round) {
146
+ return 0;
147
+ }
148
+ return src >> 63;
149
+ } else if (shift < 0) {
150
+ if (round) {
151
+ src >>= -shift - 1;
152
+ return (src >> 1) + (src & 1);
153
+ }
154
+ return src >> -shift;
155
+ } else if (shift < 48) {
156
+ int64_t val = src << shift;
157
+ int64_t extval = sextract64(val, 0, 48);
158
+ if (!sat || val == extval) {
159
+ return extval;
160
+ }
161
+ } else if (!sat || src == 0) {
162
+ return 0;
163
+ }
164
+
165
+ *sat = 1;
166
+ return (1ULL << 47) - (src >= 0);
167
+}
168
+
169
+/* Operate on 64-bit values, but saturate at 48 bits */
170
+static inline uint64_t do_uqrshl48_d(uint64_t src, int64_t shift,
171
+ bool round, uint32_t *sat)
172
+{
173
+ uint64_t val, extval;
174
+
175
+ if (shift <= -(48 + round)) {
176
+ return 0;
177
+ } else if (shift < 0) {
178
+ if (round) {
179
+ val = src >> (-shift - 1);
180
+ val = (val >> 1) + (val & 1);
181
+ } else {
182
+ val = src >> -shift;
183
+ }
184
+ extval = extract64(val, 0, 48);
185
+ if (!sat || val == extval) {
186
+ return extval;
187
+ }
188
+ } else if (shift < 48) {
189
+ uint64_t val = src << shift;
190
+ uint64_t extval = extract64(val, 0, 48);
191
+ if (!sat || val == extval) {
192
+ return extval;
193
+ }
194
+ } else if (!sat || src == 0) {
195
+ return 0;
196
+ }
197
+
198
+ *sat = 1;
199
+ return MAKE_64BIT_MASK(0, 48);
200
+}
201
+
202
+uint64_t HELPER(mve_sqrshrl48)(CPUARMState *env, uint64_t n, uint32_t shift)
203
+{
204
+ return do_sqrshl48_d(n, -(int8_t)shift, true, &env->QF);
205
+}
206
+
207
+uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
208
+{
209
+ return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
210
+}
211
diff --git a/target/arm/translate.c b/target/arm/translate.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/target/arm/translate.c
214
+++ b/target/arm/translate.c
215
@@ -XXX,XX +XXX,XX @@ static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
216
return do_mve_shl_ri(s, a, gen_urshr64_i64);
217
}
218
219
+static bool do_mve_shl_rr(DisasContext *s, arg_mve_shl_rr *a, WideShiftFn *fn)
220
+{
221
+ TCGv_i64 rda;
222
+ TCGv_i32 rdalo, rdahi;
223
+
224
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
225
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
226
+ return false;
227
+ }
228
+ if (a->rdahi == 15) {
229
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
230
+ return false;
231
+ }
232
+ if (!dc_isar_feature(aa32_mve, s) ||
233
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
234
+ a->rdahi == 13 || a->rm == 13 || a->rm == 15 ||
235
+ a->rm == a->rdahi || a->rm == a->rdalo) {
236
+ /* These rdahi/rdalo/rm cases are UNPREDICTABLE; we choose to UNDEF */
237
+ unallocated_encoding(s);
238
+ return true;
239
+ }
240
+
241
+ rda = tcg_temp_new_i64();
242
+ rdalo = load_reg(s, a->rdalo);
243
+ rdahi = load_reg(s, a->rdahi);
244
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
245
+
246
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
247
+ fn(rda, cpu_env, rda, cpu_R[a->rm]);
248
+
249
+ tcg_gen_extrl_i64_i32(rdalo, rda);
250
+ tcg_gen_extrh_i64_i32(rdahi, rda);
251
+ store_reg(s, a->rdalo, rdalo);
252
+ store_reg(s, a->rdahi, rdahi);
253
+ tcg_temp_free_i64(rda);
254
+
255
+ return true;
256
+}
257
+
258
+static bool trans_LSLL_rr(DisasContext *s, arg_mve_shl_rr *a)
259
+{
260
+ return do_mve_shl_rr(s, a, gen_helper_mve_ushll);
261
+}
262
+
263
+static bool trans_ASRL_rr(DisasContext *s, arg_mve_shl_rr *a)
264
+{
265
+ return do_mve_shl_rr(s, a, gen_helper_mve_sshrl);
266
+}
267
+
268
+static bool trans_UQRSHLL64_rr(DisasContext *s, arg_mve_shl_rr *a)
269
+{
270
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll);
271
+}
272
+
273
+static bool trans_SQRSHRL64_rr(DisasContext *s, arg_mve_shl_rr *a)
274
+{
275
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl);
276
+}
277
+
278
+static bool trans_UQRSHLL48_rr(DisasContext *s, arg_mve_shl_rr *a)
279
+{
280
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll48);
281
+}
282
+
283
+static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
284
+{
285
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
286
+}
287
+
288
/*
289
* Multiply and multiply accumulate
68
*/
290
*/
69
static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
70
{
71
+ /* Note that TBII is TBI1:TBI0. */
72
+ int tbi = s->tbii;
73
74
if (s->current_el <= 1) {
75
/* Test if NEITHER or BOTH TBI values are set. If so, no need to
76
* examine bit 55 of address, can just generate code.
77
* If mixed, then test via generated code
78
*/
79
- if (s->tbi0 && s->tbi1) {
80
+ if (tbi == 3) {
81
TCGv_i64 tmp_reg = tcg_temp_new_i64();
82
/* Both bits set, sign extension from bit 55 into [63:56] will
83
* cover both cases
84
@@ -XXX,XX +XXX,XX @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
85
tcg_gen_shli_i64(tmp_reg, src, 8);
86
tcg_gen_sari_i64(cpu_pc, tmp_reg, 8);
87
tcg_temp_free_i64(tmp_reg);
88
- } else if (!s->tbi0 && !s->tbi1) {
89
+ } else if (tbi == 0) {
90
/* Neither bit set, just load it as-is */
91
tcg_gen_mov_i64(cpu_pc, src);
92
} else {
93
@@ -XXX,XX +XXX,XX @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
94
95
tcg_gen_andi_i64(tcg_bit55, src, (1ull << 55));
96
97
- if (s->tbi0) {
98
+ if (tbi == 1) {
99
/* tbi0==1, tbi1==0, so 0-fill upper byte if bit 55 = 0 */
100
tcg_gen_andi_i64(tcg_tmpval, src,
101
0x00FFFFFFFFFFFFFFull);
102
@@ -XXX,XX +XXX,XX @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
103
tcg_temp_free_i64(tcg_tmpval);
104
}
105
} else { /* EL > 1 */
106
- if (s->tbi0) {
107
+ if (tbi != 0) {
108
/* Force tag byte to all zero */
109
tcg_gen_andi_i64(cpu_pc, src, 0x00FFFFFFFFFFFFFFull);
110
} else {
111
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
112
dc->condexec_cond = 0;
113
core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
114
dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
115
- dc->tbi0 = FIELD_EX32(tb_flags, TBFLAG_A64, TBI0);
116
- dc->tbi1 = FIELD_EX32(tb_flags, TBFLAG_A64, TBI1);
117
+ dc->tbii = FIELD_EX32(tb_flags, TBFLAG_A64, TBII);
118
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
119
#if !defined(CONFIG_USER_ONLY)
120
dc->user = (dc->current_el == 0);
121
--
291
--
122
2.20.1
292
2.20.1
123
293
124
294
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Implement the MVE shifts by immediate, which perform shifts
2
2
on a single general-purpose register.
3
There are 5 bits of state that could be added, but to save
3
4
space within tbflags, add only a single enable bit.
4
These patterns overlap with the long-shift-by-immediates,
5
Helpers will determine the rest of the state at runtime.
5
so we have to rearrange the grouping a little here.
6
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190108223129.5570-4-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210628135835.6690-18-peter.maydell@linaro.org
11
---
10
---
12
target/arm/cpu.h | 1 +
11
target/arm/helper-mve.h | 3 ++
13
target/arm/translate.h | 2 ++
12
target/arm/translate.h | 1 +
14
target/arm/helper.c | 19 +++++++++++++++++++
13
target/arm/t32.decode | 31 ++++++++++++++-----
15
target/arm/translate-a64.c | 1 +
14
target/arm/mve_helper.c | 10 ++++++
16
4 files changed, 23 insertions(+)
15
target/arm/translate.c | 68 +++++++++++++++++++++++++++++++++++++++--
17
16
5 files changed, 104 insertions(+), 9 deletions(-)
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
19
index XXXXXXX..XXXXXXX 100644
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
20
--- a/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
21
+++ b/target/arm/cpu.h
20
--- a/target/arm/helper-mve.h
22
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, TBI0, 0, 1)
21
+++ b/target/arm/helper-mve.h
23
FIELD(TBFLAG_A64, TBI1, 1, 1)
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
24
FIELD(TBFLAG_A64, SVEEXC_EL, 2, 2)
23
DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
25
FIELD(TBFLAG_A64, ZCR_LEN, 4, 4)
24
DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
26
+FIELD(TBFLAG_A64, PAUTH_ACTIVE, 8, 1)
25
DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
27
26
+
28
static inline bool bswap_code(bool sctlr_b)
27
+DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
29
{
28
+DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
30
diff --git a/target/arm/translate.h b/target/arm/translate.h
29
diff --git a/target/arm/translate.h b/target/arm/translate.h
31
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate.h
31
--- a/target/arm/translate.h
33
+++ b/target/arm/translate.h
32
+++ b/target/arm/translate.h
34
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
33
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
35
bool is_ldex;
34
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
36
/* True if a single-step exception will be taken to the current EL */
35
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
37
bool ss_same_el;
36
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
38
+ /* True if v8.3-PAuth is active. */
37
+typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
39
+ bool pauth_active;
38
40
/* Bottom two bits of XScale c15_cpar coprocessor access control reg */
39
/**
41
int c15_cpar;
40
* arm_tbflags_from_tb:
42
/* TCG op of the current insn_start. */
41
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
42
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/t32.decode
45
--- a/target/arm/helper.c
44
+++ b/target/arm/t32.decode
46
+++ b/target/arm/helper.c
45
@@ -XXX,XX +XXX,XX @@
47
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
46
48
flags = FIELD_DP32(flags, TBFLAG_A64, SVEEXC_EL, sve_el);
47
&mve_shl_ri rdalo rdahi shim
49
flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
48
&mve_shl_rr rdalo rdahi rm
50
}
49
+&mve_sh_ri rda shim
51
+
50
52
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
51
# rdahi: bits [3:1] from insn, bit 0 is 1
53
+ /*
52
# rdalo: bits [3:1] from insn, bit 0 is 0
54
+ * In order to save space in flags, we record only whether
53
@@ -XXX,XX +XXX,XX @@
55
+ * pauth is "inactive", meaning all insns are implemented as
54
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
56
+ * a nop, or "active" when some action must be performed.
55
@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
57
+ * The decision of which action to take is left to a helper.
56
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
58
+ */
57
+@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
59
+ uint64_t sctlr;
58
+ &mve_sh_ri shim=%imm5_12_6
60
+ if (current_el == 0) {
59
61
+ /* FIXME: ARMv8.1-VHE S2 translation regime. */
60
{
62
+ sctlr = env->cp15.sctlr_el[1];
61
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
63
+ } else {
62
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
64
+ sctlr = env->cp15.sctlr_el[current_el];
63
# the rest fall through (where ORR_rrri and MOV_rxri will end up
65
+ }
64
# handling them as r13 and r15 accesses with the same semantics as A32).
66
+ if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
65
[
67
+ flags = FIELD_DP32(flags, TBFLAG_A64, PAUTH_ACTIVE, 1);
66
- LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
68
+ }
67
- LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
69
+ }
68
- ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
70
} else {
69
+ {
71
*pc = env->regs[15];
70
+ UQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 00 1111 @mve_sh_ri
72
flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
71
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
73
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
72
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
74
index XXXXXXX..XXXXXXX 100644
73
+ }
75
--- a/target/arm/translate-a64.c
74
76
+++ b/target/arm/translate-a64.c
75
- UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
77
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
76
- URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
78
dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
77
- SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
79
dc->sve_excp_el = FIELD_EX32(tb_flags, TBFLAG_A64, SVEEXC_EL);
78
- SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
80
dc->sve_len = (FIELD_EX32(tb_flags, TBFLAG_A64, ZCR_LEN) + 1) * 16;
79
+ {
81
+ dc->pauth_active = FIELD_EX32(tb_flags, TBFLAG_A64, PAUTH_ACTIVE);
80
+ URSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 01 1111 @mve_sh_ri
82
dc->vec_len = 0;
81
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
83
dc->vec_stride = 0;
82
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
84
dc->cp_regs = arm_cpu->cp_regs;
83
+ }
84
+
85
+ {
86
+ SRSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 10 1111 @mve_sh_ri
87
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
88
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
89
+ }
90
+
91
+ {
92
+ SQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 11 1111 @mve_sh_ri
93
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
94
+ }
95
96
LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
97
ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
98
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/mve_helper.c
101
+++ b/target/arm/mve_helper.c
102
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
103
{
104
return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
105
}
106
+
107
+uint32_t HELPER(mve_uqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
108
+{
109
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
110
+}
111
+
112
+uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
113
+{
114
+ return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
115
+}
116
diff --git a/target/arm/translate.c b/target/arm/translate.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/arm/translate.c
119
+++ b/target/arm/translate.c
120
@@ -XXX,XX +XXX,XX @@ static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
121
122
static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
123
{
124
- TCGv_i32 t = tcg_temp_new_i32();
125
+ TCGv_i32 t;
126
127
+ /* Handle shift by the input size for the benefit of trans_SRSHR_ri */
128
+ if (sh == 32) {
129
+ tcg_gen_movi_i32(d, 0);
130
+ return;
131
+ }
132
+ t = tcg_temp_new_i32();
133
tcg_gen_extract_i32(t, a, sh - 1, 1);
134
tcg_gen_sari_i32(d, a, sh);
135
tcg_gen_add_i32(d, d, t);
136
@@ -XXX,XX +XXX,XX @@ static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
137
138
static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
139
{
140
- TCGv_i32 t = tcg_temp_new_i32();
141
+ TCGv_i32 t;
142
143
+ /* Handle shift by the input size for the benefit of trans_URSHR_ri */
144
+ if (sh == 32) {
145
+ tcg_gen_extract_i32(d, a, sh - 1, 1);
146
+ return;
147
+ }
148
+ t = tcg_temp_new_i32();
149
tcg_gen_extract_i32(t, a, sh - 1, 1);
150
tcg_gen_shri_i32(d, a, sh);
151
tcg_gen_add_i32(d, d, t);
152
@@ -XXX,XX +XXX,XX @@ static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
153
return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
154
}
155
156
+static bool do_mve_sh_ri(DisasContext *s, arg_mve_sh_ri *a, ShiftImmFn *fn)
157
+{
158
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
159
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
160
+ return false;
161
+ }
162
+ if (!dc_isar_feature(aa32_mve, s) ||
163
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
164
+ a->rda == 13 || a->rda == 15) {
165
+ /* These rda cases are UNPREDICTABLE; we choose to UNDEF */
166
+ unallocated_encoding(s);
167
+ return true;
168
+ }
169
+
170
+ if (a->shim == 0) {
171
+ a->shim = 32;
172
+ }
173
+ fn(cpu_R[a->rda], cpu_R[a->rda], a->shim);
174
+
175
+ return true;
176
+}
177
+
178
+static bool trans_URSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
179
+{
180
+ return do_mve_sh_ri(s, a, gen_urshr32_i32);
181
+}
182
+
183
+static bool trans_SRSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
184
+{
185
+ return do_mve_sh_ri(s, a, gen_srshr32_i32);
186
+}
187
+
188
+static void gen_mve_sqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
189
+{
190
+ gen_helper_mve_sqshl(r, cpu_env, n, tcg_constant_i32(shift));
191
+}
192
+
193
+static bool trans_SQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
194
+{
195
+ return do_mve_sh_ri(s, a, gen_mve_sqshl);
196
+}
197
+
198
+static void gen_mve_uqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
199
+{
200
+ gen_helper_mve_uqshl(r, cpu_env, n, tcg_constant_i32(shift));
201
+}
202
+
203
+static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
204
+{
205
+ return do_mve_sh_ri(s, a, gen_mve_uqshl);
206
+}
207
+
208
/*
209
* Multiply and multiply accumulate
210
*/
85
--
211
--
86
2.20.1
212
2.20.1
87
213
88
214
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This path uses cpu_loop_exit_restore to unwind current processor state.
4
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20190108223129.5570-5-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/internals.h | 7 +++++++
12
target/arm/op_helper.c | 19 +++++++++++++++++--
13
2 files changed, 24 insertions(+), 2 deletions(-)
14
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/internals.h
18
+++ b/target/arm/internals.h
19
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_EXCRET, RES1, 7, 25) /* including the must-be-1 prefix */
20
void QEMU_NORETURN raise_exception(CPUARMState *env, uint32_t excp,
21
uint32_t syndrome, uint32_t target_el);
22
23
+/*
24
+ * Similarly, but also use unwinding to restore cpu state.
25
+ */
26
+void QEMU_NORETURN raise_exception_ra(CPUARMState *env, uint32_t excp,
27
+ uint32_t syndrome, uint32_t target_el,
28
+ uintptr_t ra);
29
+
30
/*
31
* For AArch64, map a given EL to an index in the banked_spsr array.
32
* Note that this mapping and the AArch32 mapping defined in bank_number()
33
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/op_helper.c
36
+++ b/target/arm/op_helper.c
37
@@ -XXX,XX +XXX,XX @@
38
#define SIGNBIT (uint32_t)0x80000000
39
#define SIGNBIT64 ((uint64_t)1 << 63)
40
41
-void raise_exception(CPUARMState *env, uint32_t excp,
42
- uint32_t syndrome, uint32_t target_el)
43
+static CPUState *do_raise_exception(CPUARMState *env, uint32_t excp,
44
+ uint32_t syndrome, uint32_t target_el)
45
{
46
CPUState *cs = CPU(arm_env_get_cpu(env));
47
48
@@ -XXX,XX +XXX,XX @@ void raise_exception(CPUARMState *env, uint32_t excp,
49
cs->exception_index = excp;
50
env->exception.syndrome = syndrome;
51
env->exception.target_el = target_el;
52
+
53
+ return cs;
54
+}
55
+
56
+void raise_exception(CPUARMState *env, uint32_t excp,
57
+ uint32_t syndrome, uint32_t target_el)
58
+{
59
+ CPUState *cs = do_raise_exception(env, excp, syndrome, target_el);
60
cpu_loop_exit(cs);
61
}
62
63
+void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
64
+ uint32_t target_el, uintptr_t ra)
65
+{
66
+ CPUState *cs = do_raise_exception(env, excp, syndrome, target_el);
67
+ cpu_loop_exit_restore(cs, ra);
68
+}
69
+
70
static int exception_target_el(CPUARMState *env)
71
{
72
int target_el = MAX(1, arm_current_el(env));
73
--
74
2.20.1
75
76
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-9-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate-a64.c | 146 +++++++++++++++++++++++++++++++++++++
9
1 file changed, 146 insertions(+)
10
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
14
+++ b/target/arm/translate-a64.c
15
@@ -XXX,XX +XXX,XX @@ static void handle_rev16(DisasContext *s, unsigned int sf,
16
static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
17
{
18
unsigned int sf, opcode, opcode2, rn, rd;
19
+ TCGv_i64 tcg_rd;
20
21
if (extract32(insn, 29, 1)) {
22
unallocated_encoding(s);
23
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
24
case MAP(1, 0x00, 0x05):
25
handle_cls(s, sf, rn, rd);
26
break;
27
+ case MAP(1, 0x01, 0x00): /* PACIA */
28
+ if (s->pauth_active) {
29
+ tcg_rd = cpu_reg(s, rd);
30
+ gen_helper_pacia(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
31
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
32
+ goto do_unallocated;
33
+ }
34
+ break;
35
+ case MAP(1, 0x01, 0x01): /* PACIB */
36
+ if (s->pauth_active) {
37
+ tcg_rd = cpu_reg(s, rd);
38
+ gen_helper_pacib(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
39
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
40
+ goto do_unallocated;
41
+ }
42
+ break;
43
+ case MAP(1, 0x01, 0x02): /* PACDA */
44
+ if (s->pauth_active) {
45
+ tcg_rd = cpu_reg(s, rd);
46
+ gen_helper_pacda(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
47
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
48
+ goto do_unallocated;
49
+ }
50
+ break;
51
+ case MAP(1, 0x01, 0x03): /* PACDB */
52
+ if (s->pauth_active) {
53
+ tcg_rd = cpu_reg(s, rd);
54
+ gen_helper_pacdb(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
55
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
56
+ goto do_unallocated;
57
+ }
58
+ break;
59
+ case MAP(1, 0x01, 0x04): /* AUTIA */
60
+ if (s->pauth_active) {
61
+ tcg_rd = cpu_reg(s, rd);
62
+ gen_helper_autia(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
63
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
64
+ goto do_unallocated;
65
+ }
66
+ break;
67
+ case MAP(1, 0x01, 0x05): /* AUTIB */
68
+ if (s->pauth_active) {
69
+ tcg_rd = cpu_reg(s, rd);
70
+ gen_helper_autib(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
71
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
72
+ goto do_unallocated;
73
+ }
74
+ break;
75
+ case MAP(1, 0x01, 0x06): /* AUTDA */
76
+ if (s->pauth_active) {
77
+ tcg_rd = cpu_reg(s, rd);
78
+ gen_helper_autda(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
79
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
80
+ goto do_unallocated;
81
+ }
82
+ break;
83
+ case MAP(1, 0x01, 0x07): /* AUTDB */
84
+ if (s->pauth_active) {
85
+ tcg_rd = cpu_reg(s, rd);
86
+ gen_helper_autdb(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
87
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
88
+ goto do_unallocated;
89
+ }
90
+ break;
91
+ case MAP(1, 0x01, 0x08): /* PACIZA */
92
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
93
+ goto do_unallocated;
94
+ } else if (s->pauth_active) {
95
+ tcg_rd = cpu_reg(s, rd);
96
+ gen_helper_pacia(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
97
+ }
98
+ break;
99
+ case MAP(1, 0x01, 0x09): /* PACIZB */
100
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
101
+ goto do_unallocated;
102
+ } else if (s->pauth_active) {
103
+ tcg_rd = cpu_reg(s, rd);
104
+ gen_helper_pacib(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
105
+ }
106
+ break;
107
+ case MAP(1, 0x01, 0x0a): /* PACDZA */
108
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
109
+ goto do_unallocated;
110
+ } else if (s->pauth_active) {
111
+ tcg_rd = cpu_reg(s, rd);
112
+ gen_helper_pacda(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
113
+ }
114
+ break;
115
+ case MAP(1, 0x01, 0x0b): /* PACDZB */
116
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
117
+ goto do_unallocated;
118
+ } else if (s->pauth_active) {
119
+ tcg_rd = cpu_reg(s, rd);
120
+ gen_helper_pacdb(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
121
+ }
122
+ break;
123
+ case MAP(1, 0x01, 0x0c): /* AUTIZA */
124
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
125
+ goto do_unallocated;
126
+ } else if (s->pauth_active) {
127
+ tcg_rd = cpu_reg(s, rd);
128
+ gen_helper_autia(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
129
+ }
130
+ break;
131
+ case MAP(1, 0x01, 0x0d): /* AUTIZB */
132
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
133
+ goto do_unallocated;
134
+ } else if (s->pauth_active) {
135
+ tcg_rd = cpu_reg(s, rd);
136
+ gen_helper_autib(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
137
+ }
138
+ break;
139
+ case MAP(1, 0x01, 0x0e): /* AUTDZA */
140
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
141
+ goto do_unallocated;
142
+ } else if (s->pauth_active) {
143
+ tcg_rd = cpu_reg(s, rd);
144
+ gen_helper_autda(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
145
+ }
146
+ break;
147
+ case MAP(1, 0x01, 0x0f): /* AUTDZB */
148
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
149
+ goto do_unallocated;
150
+ } else if (s->pauth_active) {
151
+ tcg_rd = cpu_reg(s, rd);
152
+ gen_helper_autdb(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
153
+ }
154
+ break;
155
+ case MAP(1, 0x01, 0x10): /* XPACI */
156
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
157
+ goto do_unallocated;
158
+ } else if (s->pauth_active) {
159
+ tcg_rd = cpu_reg(s, rd);
160
+ gen_helper_xpaci(tcg_rd, cpu_env, tcg_rd);
161
+ }
162
+ break;
163
+ case MAP(1, 0x01, 0x11): /* XPACD */
164
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
165
+ goto do_unallocated;
166
+ } else if (s->pauth_active) {
167
+ tcg_rd = cpu_reg(s, rd);
168
+ gen_helper_xpacd(tcg_rd, cpu_env, tcg_rd);
169
+ }
170
+ break;
171
default:
172
+ do_unallocated:
173
unallocated_encoding(s);
174
break;
175
}
176
--
177
2.20.1
178
179
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This will enable PAuth decode in a subsequent patch.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190108223129.5570-13-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/translate-a64.c | 47 +++++++++++++++++++++++++++++---------
11
1 file changed, 36 insertions(+), 11 deletions(-)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
18
rn = extract32(insn, 5, 5);
19
op4 = extract32(insn, 0, 5);
20
21
- if (op4 != 0x0 || op3 != 0x0 || op2 != 0x1f) {
22
- unallocated_encoding(s);
23
- return;
24
+ if (op2 != 0x1f) {
25
+ goto do_unallocated;
26
}
27
28
switch (opc) {
29
case 0: /* BR */
30
case 1: /* BLR */
31
case 2: /* RET */
32
- gen_a64_set_pc(s, cpu_reg(s, rn));
33
+ switch (op3) {
34
+ case 0:
35
+ if (op4 != 0) {
36
+ goto do_unallocated;
37
+ }
38
+ dst = cpu_reg(s, rn);
39
+ break;
40
+
41
+ default:
42
+ goto do_unallocated;
43
+ }
44
+
45
+ gen_a64_set_pc(s, dst);
46
/* BLR also needs to load return address */
47
if (opc == 1) {
48
tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
49
}
50
break;
51
+
52
case 4: /* ERET */
53
if (s->current_el == 0) {
54
- unallocated_encoding(s);
55
- return;
56
+ goto do_unallocated;
57
+ }
58
+ switch (op3) {
59
+ case 0:
60
+ if (op4 != 0) {
61
+ goto do_unallocated;
62
+ }
63
+ dst = tcg_temp_new_i64();
64
+ tcg_gen_ld_i64(dst, cpu_env,
65
+ offsetof(CPUARMState, elr_el[s->current_el]));
66
+ break;
67
+
68
+ default:
69
+ goto do_unallocated;
70
}
71
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
72
gen_io_start();
73
}
74
- dst = tcg_temp_new_i64();
75
- tcg_gen_ld_i64(dst, cpu_env,
76
- offsetof(CPUARMState, elr_el[s->current_el]));
77
+
78
gen_helper_exception_return(cpu_env, dst);
79
tcg_temp_free_i64(dst);
80
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
81
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
82
/* Must exit loop to check un-masked IRQs */
83
s->base.is_jmp = DISAS_EXIT;
84
return;
85
+
86
case 5: /* DRPS */
87
- if (rn != 0x1f) {
88
- unallocated_encoding(s);
89
+ if (op3 != 0 || op4 != 0 || rn != 0x1f) {
90
+ goto do_unallocated;
91
} else {
92
unsupported_encoding(s, insn);
93
}
94
return;
95
+
96
default:
97
+ do_unallocated:
98
unallocated_encoding(s);
99
return;
100
}
101
--
102
2.20.1
103
104
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-14-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate-a64.c | 82 +++++++++++++++++++++++++++++++++++++-
9
1 file changed, 81 insertions(+), 1 deletion(-)
10
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
14
+++ b/target/arm/translate-a64.c
15
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
16
{
17
unsigned int opc, op2, op3, rn, op4;
18
TCGv_i64 dst;
19
+ TCGv_i64 modifier;
20
21
opc = extract32(insn, 21, 4);
22
op2 = extract32(insn, 16, 5);
23
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
24
case 2: /* RET */
25
switch (op3) {
26
case 0:
27
+ /* BR, BLR, RET */
28
if (op4 != 0) {
29
goto do_unallocated;
30
}
31
dst = cpu_reg(s, rn);
32
break;
33
34
+ case 2:
35
+ case 3:
36
+ if (!dc_isar_feature(aa64_pauth, s)) {
37
+ goto do_unallocated;
38
+ }
39
+ if (opc == 2) {
40
+ /* RETAA, RETAB */
41
+ if (rn != 0x1f || op4 != 0x1f) {
42
+ goto do_unallocated;
43
+ }
44
+ rn = 30;
45
+ modifier = cpu_X[31];
46
+ } else {
47
+ /* BRAAZ, BRABZ, BLRAAZ, BLRABZ */
48
+ if (op4 != 0x1f) {
49
+ goto do_unallocated;
50
+ }
51
+ modifier = new_tmp_a64_zero(s);
52
+ }
53
+ if (s->pauth_active) {
54
+ dst = new_tmp_a64(s);
55
+ if (op3 == 2) {
56
+ gen_helper_autia(dst, cpu_env, cpu_reg(s, rn), modifier);
57
+ } else {
58
+ gen_helper_autib(dst, cpu_env, cpu_reg(s, rn), modifier);
59
+ }
60
+ } else {
61
+ dst = cpu_reg(s, rn);
62
+ }
63
+ break;
64
+
65
default:
66
goto do_unallocated;
67
}
68
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
69
}
70
break;
71
72
+ case 8: /* BRAA */
73
+ case 9: /* BLRAA */
74
+ if (!dc_isar_feature(aa64_pauth, s)) {
75
+ goto do_unallocated;
76
+ }
77
+ if (op3 != 2 || op3 != 3) {
78
+ goto do_unallocated;
79
+ }
80
+ if (s->pauth_active) {
81
+ dst = new_tmp_a64(s);
82
+ modifier = cpu_reg_sp(s, op4);
83
+ if (op3 == 2) {
84
+ gen_helper_autia(dst, cpu_env, cpu_reg(s, rn), modifier);
85
+ } else {
86
+ gen_helper_autib(dst, cpu_env, cpu_reg(s, rn), modifier);
87
+ }
88
+ } else {
89
+ dst = cpu_reg(s, rn);
90
+ }
91
+ gen_a64_set_pc(s, dst);
92
+ /* BLRAA also needs to load return address */
93
+ if (opc == 9) {
94
+ tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
95
+ }
96
+ break;
97
+
98
case 4: /* ERET */
99
if (s->current_el == 0) {
100
goto do_unallocated;
101
}
102
switch (op3) {
103
- case 0:
104
+ case 0: /* ERET */
105
if (op4 != 0) {
106
goto do_unallocated;
107
}
108
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
109
offsetof(CPUARMState, elr_el[s->current_el]));
110
break;
111
112
+ case 2: /* ERETAA */
113
+ case 3: /* ERETAB */
114
+ if (!dc_isar_feature(aa64_pauth, s)) {
115
+ goto do_unallocated;
116
+ }
117
+ if (rn != 0x1f || op4 != 0x1f) {
118
+ goto do_unallocated;
119
+ }
120
+ dst = tcg_temp_new_i64();
121
+ tcg_gen_ld_i64(dst, cpu_env,
122
+ offsetof(CPUARMState, elr_el[s->current_el]));
123
+ if (s->pauth_active) {
124
+ modifier = cpu_X[31];
125
+ if (op3 == 2) {
126
+ gen_helper_autia(dst, cpu_env, dst, modifier);
127
+ } else {
128
+ gen_helper_autib(dst, cpu_env, dst, modifier);
129
+ }
130
+ }
131
+ break;
132
+
133
default:
134
goto do_unallocated;
135
}
136
--
137
2.20.1
138
139
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
While we could expose stage_1_mmu_idx, the combination is
4
probably going to be more useful.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190108223129.5570-18-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/internals.h | 15 +++++++++++++++
12
target/arm/helper.c | 7 +++++++
13
2 files changed, 22 insertions(+)
14
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/internals.h
18
+++ b/target/arm/internals.h
19
@@ -XXX,XX +XXX,XX @@ void arm_cpu_update_vfiq(ARMCPU *cpu);
20
*/
21
ARMMMUIdx arm_mmu_idx(CPUARMState *env);
22
23
+/**
24
+ * arm_stage1_mmu_idx:
25
+ * @env: The cpu environment
26
+ *
27
+ * Return the ARMMMUIdx for the stage1 traversal for the current regime.
28
+ */
29
+#ifdef CONFIG_USER_ONLY
30
+static inline ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
31
+{
32
+ return ARMMMUIdx_S1NSE0;
33
+}
34
+#else
35
+ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env);
36
+#endif
37
+
38
#endif
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
42
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ int cpu_mmu_index(CPUARMState *env, bool ifetch)
44
return arm_to_core_mmu_idx(arm_mmu_idx(env));
45
}
46
47
+#ifndef CONFIG_USER_ONLY
48
+ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
49
+{
50
+ return stage_1_mmu_idx(arm_mmu_idx(env));
51
+}
52
+#endif
53
+
54
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
55
target_ulong *cs_base, uint32_t *pflags)
56
{
57
--
58
2.20.1
59
60
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
We need to reuse this from helper-a64.c. Provide a stub
4
definition for CONFIG_USER_ONLY. This matches the stub
5
definitions that we removed for arm_regime_tbi{0,1} before.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190108223129.5570-21-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/internals.h | 17 +++++++++++++++++
13
target/arm/helper.c | 4 ++--
14
2 files changed, 19 insertions(+), 2 deletions(-)
15
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/internals.h
19
+++ b/target/arm/internals.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
21
bool using64k : 1;
22
} ARMVAParameters;
23
24
+#ifdef CONFIG_USER_ONLY
25
+static inline ARMVAParameters aa64_va_parameters(CPUARMState *env,
26
+ uint64_t va,
27
+ ARMMMUIdx mmu_idx, bool data)
28
+{
29
+ return (ARMVAParameters) {
30
+ /* 48-bit address space */
31
+ .tsz = 16,
32
+ /* We can't handle tagged addresses properly in user-only mode */
33
+ .tbi = false,
34
+ };
35
+}
36
+#else
37
+ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
38
+ ARMMMUIdx mmu_idx, bool data);
39
+#endif
40
+
41
#endif
42
diff --git a/target/arm/helper.c b/target/arm/helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/helper.c
45
+++ b/target/arm/helper.c
46
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
47
return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
48
}
49
50
-static ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
51
- ARMMMUIdx mmu_idx, bool data)
52
+ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
53
+ ARMMMUIdx mmu_idx, bool data)
54
{
55
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
56
uint32_t el = regime_el(env, mmu_idx);
57
--
58
2.20.1
59
60
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
We will want to check TBI for I and D simultaneously.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190108223129.5570-22-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/internals.h | 15 ++++++++++++---
11
target/arm/helper.c | 10 ++++++++--
12
2 files changed, 20 insertions(+), 5 deletions(-)
13
14
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/internals.h
17
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
19
} ARMVAParameters;
20
21
#ifdef CONFIG_USER_ONLY
22
-static inline ARMVAParameters aa64_va_parameters(CPUARMState *env,
23
- uint64_t va,
24
- ARMMMUIdx mmu_idx, bool data)
25
+static inline ARMVAParameters aa64_va_parameters_both(CPUARMState *env,
26
+ uint64_t va,
27
+ ARMMMUIdx mmu_idx)
28
{
29
return (ARMVAParameters) {
30
/* 48-bit address space */
31
@@ -XXX,XX +XXX,XX @@ static inline ARMVAParameters aa64_va_parameters(CPUARMState *env,
32
.tbi = false,
33
};
34
}
35
+
36
+static inline ARMVAParameters aa64_va_parameters(CPUARMState *env,
37
+ uint64_t va,
38
+ ARMMMUIdx mmu_idx, bool data)
39
+{
40
+ return aa64_va_parameters_both(env, va, mmu_idx);
41
+}
42
#else
43
+ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
44
+ ARMMMUIdx mmu_idx);
45
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
46
ARMMMUIdx mmu_idx, bool data);
47
#endif
48
diff --git a/target/arm/helper.c b/target/arm/helper.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/helper.c
51
+++ b/target/arm/helper.c
52
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
53
return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
54
}
55
56
-ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
57
- ARMMMUIdx mmu_idx, bool data)
58
+ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
59
+ ARMMMUIdx mmu_idx)
60
{
61
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
62
uint32_t el = regime_el(env, mmu_idx);
63
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
64
};
65
}
66
67
+ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
68
+ ARMMMUIdx mmu_idx, bool data)
69
+{
70
+ return aa64_va_parameters_both(env, va, mmu_idx);
71
+}
72
+
73
static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
74
ARMMMUIdx mmu_idx)
75
{
76
--
77
2.20.1
78
79
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Use TBID in aa64_va_parameters depending on the data parameter.
4
This automatically updates all existing users of the function.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20190108223129.5570-23-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/internals.h | 1 +
12
target/arm/helper.c | 14 +++++++++++---
13
2 files changed, 12 insertions(+), 3 deletions(-)
14
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/internals.h
18
+++ b/target/arm/internals.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
20
unsigned tsz : 8;
21
unsigned select : 1;
22
bool tbi : 1;
23
+ bool tbid : 1;
24
bool epd : 1;
25
bool hpd : 1;
26
bool using16k : 1;
27
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/helper.c
30
+++ b/target/arm/helper.c
31
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
32
{
33
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
34
uint32_t el = regime_el(env, mmu_idx);
35
- bool tbi, epd, hpd, using16k, using64k;
36
+ bool tbi, tbid, epd, hpd, using16k, using64k;
37
int select, tsz;
38
39
/*
40
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
41
using16k = extract32(tcr, 15, 1);
42
if (mmu_idx == ARMMMUIdx_S2NS) {
43
/* VTCR_EL2 */
44
- tbi = hpd = false;
45
+ tbi = tbid = hpd = false;
46
} else {
47
tbi = extract32(tcr, 20, 1);
48
hpd = extract32(tcr, 24, 1);
49
+ tbid = extract32(tcr, 29, 1);
50
}
51
epd = false;
52
} else if (!select) {
53
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
54
using16k = extract32(tcr, 15, 1);
55
tbi = extract64(tcr, 37, 1);
56
hpd = extract64(tcr, 41, 1);
57
+ tbid = extract64(tcr, 51, 1);
58
} else {
59
int tg = extract32(tcr, 30, 2);
60
using16k = tg == 1;
61
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
62
epd = extract32(tcr, 23, 1);
63
tbi = extract64(tcr, 38, 1);
64
hpd = extract64(tcr, 42, 1);
65
+ tbid = extract64(tcr, 52, 1);
66
}
67
tsz = MIN(tsz, 39); /* TODO: ARMv8.4-TTST */
68
tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
69
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
70
.tsz = tsz,
71
.select = select,
72
.tbi = tbi,
73
+ .tbid = tbid,
74
.epd = epd,
75
.hpd = hpd,
76
.using16k = using16k,
77
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
78
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
79
ARMMMUIdx mmu_idx, bool data)
80
{
81
- return aa64_va_parameters_both(env, va, mmu_idx);
82
+ ARMVAParameters ret = aa64_va_parameters_both(env, va, mmu_idx);
83
+
84
+ /* Present TBI as a composite with TBID. */
85
+ ret.tbi &= (data || !ret.tbid);
86
+ return ret;
87
}
88
89
static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
90
--
91
2.20.1
92
93
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The arm_regime_tbi{0,1} functions are replacable with the new function
4
by giving the lowest and highest address.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190108223129.5570-24-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/cpu.h | 35 -----------------------
12
target/arm/helper.c | 70 ++++++++++++++++-----------------------------
13
2 files changed, 24 insertions(+), 81 deletions(-)
14
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpu_bswap_data(CPUARMState *env)
20
}
21
#endif
22
23
-#ifndef CONFIG_USER_ONLY
24
-/**
25
- * arm_regime_tbi0:
26
- * @env: CPUARMState
27
- * @mmu_idx: MMU index indicating required translation regime
28
- *
29
- * Extracts the TBI0 value from the appropriate TCR for the current EL
30
- *
31
- * Returns: the TBI0 value.
32
- */
33
-uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx);
34
-
35
-/**
36
- * arm_regime_tbi1:
37
- * @env: CPUARMState
38
- * @mmu_idx: MMU index indicating required translation regime
39
- *
40
- * Extracts the TBI1 value from the appropriate TCR for the current EL
41
- *
42
- * Returns: the TBI1 value.
43
- */
44
-uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx);
45
-#else
46
-/* We can't handle tagged addresses properly in user-only mode */
47
-static inline uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx)
48
-{
49
- return 0;
50
-}
51
-
52
-static inline uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
53
-{
54
- return 0;
55
-}
56
-#endif
57
-
58
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
59
target_ulong *cs_base, uint32_t *flags);
60
61
diff --git a/target/arm/helper.c b/target/arm/helper.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/helper.c
64
+++ b/target/arm/helper.c
65
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx)
66
return mmu_idx;
67
}
68
69
-/* Returns TBI0 value for current regime el */
70
-uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx)
71
-{
72
- TCR *tcr;
73
- uint32_t el;
74
-
75
- /* For EL0 and EL1, TBI is controlled by stage 1's TCR, so convert
76
- * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
77
- */
78
- mmu_idx = stage_1_mmu_idx(mmu_idx);
79
-
80
- tcr = regime_tcr(env, mmu_idx);
81
- el = regime_el(env, mmu_idx);
82
-
83
- if (el > 1) {
84
- return extract64(tcr->raw_tcr, 20, 1);
85
- } else {
86
- return extract64(tcr->raw_tcr, 37, 1);
87
- }
88
-}
89
-
90
-/* Returns TBI1 value for current regime el */
91
-uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
92
-{
93
- TCR *tcr;
94
- uint32_t el;
95
-
96
- /* For EL0 and EL1, TBI is controlled by stage 1's TCR, so convert
97
- * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
98
- */
99
- mmu_idx = stage_1_mmu_idx(mmu_idx);
100
-
101
- tcr = regime_tcr(env, mmu_idx);
102
- el = regime_el(env, mmu_idx);
103
-
104
- if (el > 1) {
105
- return 0;
106
- } else {
107
- return extract64(tcr->raw_tcr, 38, 1);
108
- }
109
-}
110
-
111
/* Return the TTBR associated with this translation regime */
112
static inline uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx,
113
int ttbrn)
114
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
115
116
*pc = env->pc;
117
flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
118
- /* Get control bits for tagged addresses */
119
- flags = FIELD_DP32(flags, TBFLAG_A64, TBII,
120
- (arm_regime_tbi1(env, mmu_idx) << 1) |
121
- arm_regime_tbi0(env, mmu_idx));
122
+
123
+#ifndef CONFIG_USER_ONLY
124
+ /*
125
+ * Get control bits for tagged addresses. Note that the
126
+ * translator only uses this for instruction addresses.
127
+ */
128
+ {
129
+ ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
130
+ ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
131
+ int tbii, tbid;
132
+
133
+ /* FIXME: ARMv8.1-VHE S2 translation regime. */
134
+ if (regime_el(env, stage1) < 2) {
135
+ ARMVAParameters p1 = aa64_va_parameters_both(env, -1, stage1);
136
+ tbid = (p1.tbi << 1) | p0.tbi;
137
+ tbii = tbid & ~((p1.tbid << 1) | p0.tbid);
138
+ } else {
139
+ tbid = p0.tbi;
140
+ tbii = tbid & !p0.tbid;
141
+ }
142
+
143
+ flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
144
+ }
145
+#endif
146
147
if (cpu_isar_feature(aa64_sve, cpu)) {
148
int sve_el = sve_exception_el(env, current_el);
149
--
150
2.20.1
151
152
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Stripping out the authentication data does not require any crypto,
4
it merely requires the virtual address parameters.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190108223129.5570-25-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/pauth_helper.c | 14 +++++++++++++-
12
1 file changed, 13 insertions(+), 1 deletion(-)
13
14
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/pauth_helper.c
17
+++ b/target/arm/pauth_helper.c
18
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
19
g_assert_not_reached(); /* FIXME */
20
}
21
22
+static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
23
+{
24
+ uint64_t extfield = -param.select;
25
+ int bot_pac_bit = 64 - param.tsz;
26
+ int top_pac_bit = 64 - 8 * param.tbi;
27
+
28
+ return deposit64(ptr, bot_pac_bit, top_pac_bit - bot_pac_bit, extfield);
29
+}
30
+
31
static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
32
ARMPACKey *key, bool data, int keynumber)
33
{
34
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
35
36
static uint64_t pauth_strip(CPUARMState *env, uint64_t ptr, bool data)
37
{
38
- g_assert_not_reached(); /* FIXME */
39
+ ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
40
+ ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
41
+
42
+ return pauth_original_ptr(ptr, param);
43
}
44
45
static void QEMU_NORETURN pauth_trap(CPUARMState *env, int target_el,
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This is not really functional yet, because the crypto is not yet
4
implemented. This, however follows the Auth pseudo function.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190108223129.5570-26-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/pauth_helper.c | 21 ++++++++++++++++++++-
12
1 file changed, 20 insertions(+), 1 deletion(-)
13
14
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/pauth_helper.c
17
+++ b/target/arm/pauth_helper.c
18
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
19
static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
20
ARMPACKey *key, bool data, int keynumber)
21
{
22
- g_assert_not_reached(); /* FIXME */
23
+ ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
24
+ ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
25
+ int bot_bit, top_bit;
26
+ uint64_t pac, orig_ptr, test;
27
+
28
+ orig_ptr = pauth_original_ptr(ptr, param);
29
+ pac = pauth_computepac(orig_ptr, modifier, *key);
30
+ bot_bit = 64 - param.tsz;
31
+ top_bit = 64 - 8 * param.tbi;
32
+
33
+ test = (pac ^ ptr) & ~MAKE_64BIT_MASK(55, 1);
34
+ if (unlikely(extract64(test, bot_bit, top_bit - bot_bit))) {
35
+ int error_code = (keynumber << 1) | (keynumber ^ 1);
36
+ if (param.tbi) {
37
+ return deposit64(ptr, 53, 2, error_code);
38
+ } else {
39
+ return deposit64(ptr, 61, 2, error_code);
40
+ }
41
+ }
42
+ return orig_ptr;
43
}
44
45
static uint64_t pauth_strip(CPUARMState *env, uint64_t ptr, bool data)
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This is not really functional yet, because the crypto is not yet
4
implemented. This, however follows the AddPAC pseudo function.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190108223129.5570-27-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/pauth_helper.c | 42 ++++++++++++++++++++++++++++++++++++++-
12
1 file changed, 41 insertions(+), 1 deletion(-)
13
14
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/pauth_helper.c
17
+++ b/target/arm/pauth_helper.c
18
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_computepac(uint64_t data, uint64_t modifier,
19
static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
20
ARMPACKey *key, bool data)
21
{
22
- g_assert_not_reached(); /* FIXME */
23
+ ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
24
+ ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
25
+ uint64_t pac, ext_ptr, ext, test;
26
+ int bot_bit, top_bit;
27
+
28
+ /* If tagged pointers are in use, use ptr<55>, otherwise ptr<63>. */
29
+ if (param.tbi) {
30
+ ext = sextract64(ptr, 55, 1);
31
+ } else {
32
+ ext = sextract64(ptr, 63, 1);
33
+ }
34
+
35
+ /* Build a pointer with known good extension bits. */
36
+ top_bit = 64 - 8 * param.tbi;
37
+ bot_bit = 64 - param.tsz;
38
+ ext_ptr = deposit64(ptr, bot_bit, top_bit - bot_bit, ext);
39
+
40
+ pac = pauth_computepac(ext_ptr, modifier, *key);
41
+
42
+ /*
43
+ * Check if the ptr has good extension bits and corrupt the
44
+ * pointer authentication code if not.
45
+ */
46
+ test = sextract64(ptr, bot_bit, top_bit - bot_bit);
47
+ if (test != 0 && test != -1) {
48
+ pac ^= MAKE_64BIT_MASK(top_bit - 1, 1);
49
+ }
50
+
51
+ /*
52
+ * Preserve the determination between upper and lower at bit 55,
53
+ * and insert pointer authentication code.
54
+ */
55
+ if (param.tbi) {
56
+ ptr &= ~MAKE_64BIT_MASK(bot_bit, 55 - bot_bit + 1);
57
+ pac &= MAKE_64BIT_MASK(bot_bit, 54 - bot_bit + 1);
58
+ } else {
59
+ ptr &= MAKE_64BIT_MASK(0, bot_bit);
60
+ pac &= ~(MAKE_64BIT_MASK(55, 1) | MAKE_64BIT_MASK(0, bot_bit));
61
+ }
62
+ ext &= MAKE_64BIT_MASK(55, 1);
63
+ return pac | ext | ptr;
64
}
65
66
static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
67
--
68
2.20.1
69
70
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-29-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper.c | 70 +++++++++++++++++++++++++++++++++++++++++++++
9
1 file changed, 70 insertions(+)
10
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
14
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_lor_other(CPUARMState *env,
16
return access_lor_ns(env);
17
}
18
19
+#ifdef TARGET_AARCH64
20
+static CPAccessResult access_pauth(CPUARMState *env, const ARMCPRegInfo *ri,
21
+ bool isread)
22
+{
23
+ int el = arm_current_el(env);
24
+
25
+ if (el < 2 &&
26
+ arm_feature(env, ARM_FEATURE_EL2) &&
27
+ !(arm_hcr_el2_eff(env) & HCR_APK)) {
28
+ return CP_ACCESS_TRAP_EL2;
29
+ }
30
+ if (el < 3 &&
31
+ arm_feature(env, ARM_FEATURE_EL3) &&
32
+ !(env->cp15.scr_el3 & SCR_APK)) {
33
+ return CP_ACCESS_TRAP_EL3;
34
+ }
35
+ return CP_ACCESS_OK;
36
+}
37
+
38
+static const ARMCPRegInfo pauth_reginfo[] = {
39
+ { .name = "APDAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
40
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 0,
41
+ .access = PL1_RW, .accessfn = access_pauth,
42
+ .fieldoffset = offsetof(CPUARMState, apda_key.lo) },
43
+ { .name = "APDAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
44
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 1,
45
+ .access = PL1_RW, .accessfn = access_pauth,
46
+ .fieldoffset = offsetof(CPUARMState, apda_key.hi) },
47
+ { .name = "APDBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
48
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 2,
49
+ .access = PL1_RW, .accessfn = access_pauth,
50
+ .fieldoffset = offsetof(CPUARMState, apdb_key.lo) },
51
+ { .name = "APDBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
52
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 3,
53
+ .access = PL1_RW, .accessfn = access_pauth,
54
+ .fieldoffset = offsetof(CPUARMState, apdb_key.hi) },
55
+ { .name = "APGAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
56
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 0,
57
+ .access = PL1_RW, .accessfn = access_pauth,
58
+ .fieldoffset = offsetof(CPUARMState, apga_key.lo) },
59
+ { .name = "APGAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
60
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 1,
61
+ .access = PL1_RW, .accessfn = access_pauth,
62
+ .fieldoffset = offsetof(CPUARMState, apga_key.hi) },
63
+ { .name = "APIAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
64
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 0,
65
+ .access = PL1_RW, .accessfn = access_pauth,
66
+ .fieldoffset = offsetof(CPUARMState, apia_key.lo) },
67
+ { .name = "APIAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
68
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 1,
69
+ .access = PL1_RW, .accessfn = access_pauth,
70
+ .fieldoffset = offsetof(CPUARMState, apia_key.hi) },
71
+ { .name = "APIBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
72
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 2,
73
+ .access = PL1_RW, .accessfn = access_pauth,
74
+ .fieldoffset = offsetof(CPUARMState, apib_key.lo) },
75
+ { .name = "APIBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
76
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 3,
77
+ .access = PL1_RW, .accessfn = access_pauth,
78
+ .fieldoffset = offsetof(CPUARMState, apib_key.hi) },
79
+ REGINFO_SENTINEL
80
+};
81
+#endif
82
+
83
void register_cp_regs_for_features(ARMCPU *cpu)
84
{
85
/* Register all the coprocessor registers based on feature bits */
86
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
87
define_one_arm_cp_reg(cpu, &zcr_el3_reginfo);
88
}
89
}
90
+
91
+#ifdef TARGET_AARCH64
92
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
93
+ define_arm_cp_regs(cpu, pauth_reginfo);
94
+ }
95
+#endif
96
}
97
98
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
99
--
100
2.20.1
101
102
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-30-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/cpu64.c | 4 ++++
9
1 file changed, 4 insertions(+)
10
11
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu64.c
14
+++ b/target/arm/cpu64.c
15
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
16
17
t = cpu->isar.id_aa64isar1;
18
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
19
+ t = FIELD_DP64(t, ID_AA64ISAR1, APA, 1); /* PAuth, architected only */
20
+ t = FIELD_DP64(t, ID_AA64ISAR1, API, 0);
21
+ t = FIELD_DP64(t, ID_AA64ISAR1, GPA, 1);
22
+ t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
23
cpu->isar.id_aa64isar1 = t;
24
25
t = cpu->isar.id_aa64pfr0;
26
--
27
2.20.1
28
29
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Add 4 attributes that controls the EL1 enable bits, as we may not
4
always want to turn on pointer authentication with -cpu max.
5
However, by default they are enabled.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20190108223129.5570-31-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.c | 3 +++
13
target/arm/cpu64.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++
14
2 files changed, 63 insertions(+)
15
16
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.c
19
+++ b/target/arm/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
21
env->pstate = PSTATE_MODE_EL0t;
22
/* Userspace expects access to DC ZVA, CTL_EL0 and the cache ops */
23
env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE;
24
+ /* Enable all PAC instructions */
25
+ env->cp15.hcr_el2 |= HCR_API;
26
+ env->cp15.scr_el3 |= SCR_API;
27
/* and to the FP/Neon instructions */
28
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
29
/* and to the SVE instructions */
30
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu64.c
33
+++ b/target/arm/cpu64.c
34
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name,
35
error_propagate(errp, err);
36
}
37
38
+#ifdef CONFIG_USER_ONLY
39
+static void cpu_max_get_packey(Object *obj, Visitor *v, const char *name,
40
+ void *opaque, Error **errp)
41
+{
42
+ ARMCPU *cpu = ARM_CPU(obj);
43
+ const uint64_t *bit = opaque;
44
+ bool enabled = (cpu->env.cp15.sctlr_el[1] & *bit) != 0;
45
+
46
+ visit_type_bool(v, name, &enabled, errp);
47
+}
48
+
49
+static void cpu_max_set_packey(Object *obj, Visitor *v, const char *name,
50
+ void *opaque, Error **errp)
51
+{
52
+ ARMCPU *cpu = ARM_CPU(obj);
53
+ Error *err = NULL;
54
+ const uint64_t *bit = opaque;
55
+ bool enabled;
56
+
57
+ visit_type_bool(v, name, &enabled, errp);
58
+
59
+ if (!err) {
60
+ if (enabled) {
61
+ cpu->env.cp15.sctlr_el[1] |= *bit;
62
+ } else {
63
+ cpu->env.cp15.sctlr_el[1] &= ~*bit;
64
+ }
65
+ }
66
+ error_propagate(errp, err);
67
+}
68
+#endif
69
+
70
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
71
* otherwise, a CPU with as many features enabled as our emulation supports.
72
* The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
73
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
74
*/
75
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
76
cpu->dcz_blocksize = 7; /* 512 bytes */
77
+
78
+ /*
79
+ * Note that Linux will enable enable all of the keys at once.
80
+ * But doing it this way will allow experimentation beyond that.
81
+ */
82
+ {
83
+ static const uint64_t apia_bit = SCTLR_EnIA;
84
+ static const uint64_t apib_bit = SCTLR_EnIB;
85
+ static const uint64_t apda_bit = SCTLR_EnDA;
86
+ static const uint64_t apdb_bit = SCTLR_EnDB;
87
+
88
+ object_property_add(obj, "apia", "bool", cpu_max_get_packey,
89
+ cpu_max_set_packey, NULL,
90
+ (void *)&apia_bit, &error_fatal);
91
+ object_property_add(obj, "apib", "bool", cpu_max_get_packey,
92
+ cpu_max_set_packey, NULL,
93
+ (void *)&apib_bit, &error_fatal);
94
+ object_property_add(obj, "apda", "bool", cpu_max_get_packey,
95
+ cpu_max_set_packey, NULL,
96
+ (void *)&apda_bit, &error_fatal);
97
+ object_property_add(obj, "apdb", "bool", cpu_max_get_packey,
98
+ cpu_max_set_packey, NULL,
99
+ (void *)&apdb_bit, &error_fatal);
100
+
101
+ /* Enable all PAC keys by default. */
102
+ cpu->env.cp15.sctlr_el[1] |= SCTLR_EnIA | SCTLR_EnIB;
103
+ cpu->env.cp15.sctlr_el[1] |= SCTLR_EnDA | SCTLR_EnDB;
104
+ }
105
#endif
106
107
cpu->sve_max_vq = ARM_MAX_VQ;
108
--
109
2.20.1
110
111
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
We can perform this with fewer operations.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190108223129.5570-32-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/translate-a64.c | 62 +++++++++++++-------------------------
11
1 file changed, 21 insertions(+), 41 deletions(-)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ void gen_a64_set_pc_im(uint64_t val)
18
/* Load the PC from a generic TCG variable.
19
*
20
* If address tagging is enabled via the TCR TBI bits, then loading
21
- * an address into the PC will clear out any tag in the it:
22
+ * an address into the PC will clear out any tag in it:
23
* + for EL2 and EL3 there is only one TBI bit, and if it is set
24
* then the address is zero-extended, clearing bits [63:56]
25
* + for EL0 and EL1, TBI0 controls addresses with bit 55 == 0
26
@@ -XXX,XX +XXX,XX @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
27
int tbi = s->tbii;
28
29
if (s->current_el <= 1) {
30
- /* Test if NEITHER or BOTH TBI values are set. If so, no need to
31
- * examine bit 55 of address, can just generate code.
32
- * If mixed, then test via generated code
33
- */
34
- if (tbi == 3) {
35
- TCGv_i64 tmp_reg = tcg_temp_new_i64();
36
- /* Both bits set, sign extension from bit 55 into [63:56] will
37
- * cover both cases
38
- */
39
- tcg_gen_shli_i64(tmp_reg, src, 8);
40
- tcg_gen_sari_i64(cpu_pc, tmp_reg, 8);
41
- tcg_temp_free_i64(tmp_reg);
42
- } else if (tbi == 0) {
43
- /* Neither bit set, just load it as-is */
44
- tcg_gen_mov_i64(cpu_pc, src);
45
- } else {
46
- TCGv_i64 tcg_tmpval = tcg_temp_new_i64();
47
- TCGv_i64 tcg_bit55 = tcg_temp_new_i64();
48
- TCGv_i64 tcg_zero = tcg_const_i64(0);
49
+ if (tbi != 0) {
50
+ /* Sign-extend from bit 55. */
51
+ tcg_gen_sextract_i64(cpu_pc, src, 0, 56);
52
53
- tcg_gen_andi_i64(tcg_bit55, src, (1ull << 55));
54
+ if (tbi != 3) {
55
+ TCGv_i64 tcg_zero = tcg_const_i64(0);
56
57
- if (tbi == 1) {
58
- /* tbi0==1, tbi1==0, so 0-fill upper byte if bit 55 = 0 */
59
- tcg_gen_andi_i64(tcg_tmpval, src,
60
- 0x00FFFFFFFFFFFFFFull);
61
- tcg_gen_movcond_i64(TCG_COND_EQ, cpu_pc, tcg_bit55, tcg_zero,
62
- tcg_tmpval, src);
63
- } else {
64
- /* tbi0==0, tbi1==1, so 1-fill upper byte if bit 55 = 1 */
65
- tcg_gen_ori_i64(tcg_tmpval, src,
66
- 0xFF00000000000000ull);
67
- tcg_gen_movcond_i64(TCG_COND_NE, cpu_pc, tcg_bit55, tcg_zero,
68
- tcg_tmpval, src);
69
+ /*
70
+ * The two TBI bits differ.
71
+ * If tbi0, then !tbi1: only use the extension if positive.
72
+ * if !tbi0, then tbi1: only use the extension if negative.
73
+ */
74
+ tcg_gen_movcond_i64(tbi == 1 ? TCG_COND_GE : TCG_COND_LT,
75
+ cpu_pc, cpu_pc, tcg_zero, cpu_pc, src);
76
+ tcg_temp_free_i64(tcg_zero);
77
}
78
- tcg_temp_free_i64(tcg_zero);
79
- tcg_temp_free_i64(tcg_bit55);
80
- tcg_temp_free_i64(tcg_tmpval);
81
+ return;
82
}
83
- } else { /* EL > 1 */
84
+ } else {
85
if (tbi != 0) {
86
/* Force tag byte to all zero */
87
- tcg_gen_andi_i64(cpu_pc, src, 0x00FFFFFFFFFFFFFFull);
88
- } else {
89
- /* Load unmodified address */
90
- tcg_gen_mov_i64(cpu_pc, src);
91
+ tcg_gen_extract_i64(cpu_pc, src, 0, 56);
92
+ return;
93
}
94
}
95
+
96
+ /* Load unmodified address */
97
+ tcg_gen_mov_i64(cpu_pc, src);
98
}
99
100
typedef struct DisasCompare64 {
101
--
102
2.20.1
103
104
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
Implement the MVE shifts by register, which perform
2
shifts on a single general-purpose register.
2
3
3
Rename arm_ccnt_enabled to pmu_counter_enabled, and add logic to only
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
return 'true' if the specified counter is enabled and neither prohibited
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
or filtered.
6
Message-id: 20210628135835.6690-19-peter.maydell@linaro.org
7
---
8
target/arm/helper-mve.h | 2 ++
9
target/arm/translate.h | 1 +
10
target/arm/t32.decode | 18 ++++++++++++++----
11
target/arm/mve_helper.c | 10 ++++++++++
12
target/arm/translate.c | 30 ++++++++++++++++++++++++++++++
13
5 files changed, 57 insertions(+), 4 deletions(-)
6
14
7
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
8
Signed-off-by: Aaron Lindsay <aclindsa@gmail.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20181211151945.29137-5-aaron@os.amperecomputing.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/cpu.h | 10 ++++-
15
target/arm/cpu.c | 3 ++
16
target/arm/helper.c | 96 +++++++++++++++++++++++++++++++++++++++++----
17
3 files changed, 101 insertions(+), 8 deletions(-)
18
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
17
--- a/target/arm/helper-mve.h
22
+++ b/target/arm/cpu.h
18
+++ b/target/arm/helper-mve.h
23
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_finish(CPUARMState *env);
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
24
void pmu_op_start(CPUARMState *env);
20
25
void pmu_op_finish(CPUARMState *env);
21
DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
26
22
DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
27
+/**
23
+DEF_HELPER_FLAGS_3(mve_uqrshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
28
+ * Functions to register as EL change hooks for PMU mode filtering
24
+DEF_HELPER_FLAGS_3(mve_sqrshr, TCG_CALL_NO_RWG, i32, env, i32, i32)
29
+ */
25
diff --git a/target/arm/translate.h b/target/arm/translate.h
30
+void pmu_pre_el_change(ARMCPU *cpu, void *ignored);
31
+void pmu_post_el_change(ARMCPU *cpu, void *ignored);
32
+
33
/* SCTLR bit meanings. Several bits have been reused in newer
34
* versions of the architecture; in that case we define constants
35
* for both old and new bit meanings. Code which tests against those
36
@@ -XXX,XX +XXX,XX @@ void pmu_op_finish(CPUARMState *env);
37
38
#define MDCR_EPMAD (1U << 21)
39
#define MDCR_EDAD (1U << 20)
40
-#define MDCR_SPME (1U << 17)
41
+#define MDCR_SPME (1U << 17) /* MDCR_EL3 */
42
+#define MDCR_HPMD (1U << 17) /* MDCR_EL2 */
43
#define MDCR_SDD (1U << 16)
44
#define MDCR_SPD (3U << 14)
45
#define MDCR_TDRA (1U << 11)
46
@@ -XXX,XX +XXX,XX @@ void pmu_op_finish(CPUARMState *env);
47
#define MDCR_HPME (1U << 7)
48
#define MDCR_TPM (1U << 6)
49
#define MDCR_TPMCR (1U << 5)
50
+#define MDCR_HPMN (0x1fU)
51
52
/* Not all of the MDCR_EL3 bits are present in the 32-bit SDCR */
53
#define SDCR_VALID_MASK (MDCR_EPMAD | MDCR_EDAD | MDCR_SPME | MDCR_SPD)
54
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
55
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/cpu.c
27
--- a/target/arm/translate.h
57
+++ b/target/arm/cpu.c
28
+++ b/target/arm/translate.h
58
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
29
@@ -XXX,XX +XXX,XX @@ typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
59
if (!cpu->has_pmu) {
30
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
60
unset_feature(env, ARM_FEATURE_PMU);
31
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
61
cpu->id_aa64dfr0 &= ~0xf00;
32
typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
62
+ } else if (!kvm_enabled()) {
33
+typedef void ShiftFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
63
+ arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0);
34
64
+ arm_register_el_change_hook(cpu, &pmu_post_el_change, 0);
35
/**
36
* arm_tbflags_from_tb:
37
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/t32.decode
40
+++ b/target/arm/t32.decode
41
@@ -XXX,XX +XXX,XX @@
42
&mve_shl_ri rdalo rdahi shim
43
&mve_shl_rr rdalo rdahi rm
44
&mve_sh_ri rda shim
45
+&mve_sh_rr rda rm
46
47
# rdahi: bits [3:1] from insn, bit 0 is 1
48
# rdalo: bits [3:1] from insn, bit 0 is 0
49
@@ -XXX,XX +XXX,XX @@
50
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
51
@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
52
&mve_sh_ri shim=%imm5_12_6
53
+@mve_sh_rr ....... .... . rda:4 rm:4 .... .... .... &mve_sh_rr
54
55
{
56
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
57
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
58
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
65
}
59
}
66
60
67
if (!arm_feature(env, ARM_FEATURE_EL2)) {
61
- LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
68
diff --git a/target/arm/helper.c b/target/arm/helper.c
62
- ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
69
index XXXXXXX..XXXXXXX 100644
63
- UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
70
--- a/target/arm/helper.c
64
- SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
71
+++ b/target/arm/helper.c
65
+ {
72
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
66
+ UQRSHL_rr 1110101 0010 1 .... .... 1111 0000 1101 @mve_sh_rr
73
/* Definitions for the PMU registers */
67
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
74
#define PMCRN_MASK 0xf800
68
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
75
#define PMCRN_SHIFT 11
76
+#define PMCRDP 0x10
77
#define PMCRD 0x8
78
#define PMCRC 0x4
79
#define PMCRE 0x1
80
81
+#define PMXEVTYPER_P 0x80000000
82
+#define PMXEVTYPER_U 0x40000000
83
+#define PMXEVTYPER_NSK 0x20000000
84
+#define PMXEVTYPER_NSU 0x10000000
85
+#define PMXEVTYPER_NSH 0x08000000
86
+#define PMXEVTYPER_M 0x04000000
87
+#define PMXEVTYPER_MT 0x02000000
88
+#define PMXEVTYPER_EVTCOUNT 0x0000ffff
89
+#define PMXEVTYPER_MASK (PMXEVTYPER_P | PMXEVTYPER_U | PMXEVTYPER_NSK | \
90
+ PMXEVTYPER_NSU | PMXEVTYPER_NSH | \
91
+ PMXEVTYPER_M | PMXEVTYPER_MT | \
92
+ PMXEVTYPER_EVTCOUNT)
93
+
94
static inline uint32_t pmu_num_counters(CPUARMState *env)
95
{
96
return (env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT;
97
@@ -XXX,XX +XXX,XX @@ static CPAccessResult pmreg_access_ccntr(CPUARMState *env,
98
return pmreg_access(env, ri, isread);
99
}
100
101
-static inline bool arm_ccnt_enabled(CPUARMState *env)
102
+/* Returns true if the counter (pass 31 for PMCCNTR) should count events using
103
+ * the current EL, security state, and register configuration.
104
+ */
105
+static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
106
{
107
- /* This does not support checking PMCCFILTR_EL0 register */
108
+ uint64_t filter;
109
+ bool e, p, u, nsk, nsu, nsh, m;
110
+ bool enabled, prohibited, filtered;
111
+ bool secure = arm_is_secure(env);
112
+ int el = arm_current_el(env);
113
+ uint8_t hpmn = env->cp15.mdcr_el2 & MDCR_HPMN;
114
115
- if (!(env->cp15.c9_pmcr & PMCRE) || !(env->cp15.c9_pmcnten & (1 << 31))) {
116
- return false;
117
+ if (!arm_feature(env, ARM_FEATURE_EL2) ||
118
+ (counter < hpmn || counter == 31)) {
119
+ e = env->cp15.c9_pmcr & PMCRE;
120
+ } else {
121
+ e = env->cp15.mdcr_el2 & MDCR_HPME;
122
+ }
123
+ enabled = e && (env->cp15.c9_pmcnten & (1 << counter));
124
+
125
+ if (!secure) {
126
+ if (el == 2 && (counter < hpmn || counter == 31)) {
127
+ prohibited = env->cp15.mdcr_el2 & MDCR_HPMD;
128
+ } else {
129
+ prohibited = false;
130
+ }
131
+ } else {
132
+ prohibited = arm_feature(env, ARM_FEATURE_EL3) &&
133
+ (env->cp15.mdcr_el3 & MDCR_SPME);
134
}
135
136
- return true;
137
+ if (prohibited && counter == 31) {
138
+ prohibited = env->cp15.c9_pmcr & PMCRDP;
139
+ }
69
+ }
140
+
70
+
141
+ /* TODO Remove assert, set filter to correct PMEVTYPER */
71
+ {
142
+ assert(counter == 31);
72
+ SQRSHR_rr 1110101 0010 1 .... .... 1111 0010 1101 @mve_sh_rr
143
+ filter = env->cp15.pmccfiltr_el0;
73
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
144
+
74
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
145
+ p = filter & PMXEVTYPER_P;
146
+ u = filter & PMXEVTYPER_U;
147
+ nsk = arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_NSK);
148
+ nsu = arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_NSU);
149
+ nsh = arm_feature(env, ARM_FEATURE_EL2) && (filter & PMXEVTYPER_NSH);
150
+ m = arm_el_is_aa64(env, 1) &&
151
+ arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_M);
152
+
153
+ if (el == 0) {
154
+ filtered = secure ? u : u != nsu;
155
+ } else if (el == 1) {
156
+ filtered = secure ? p : p != nsk;
157
+ } else if (el == 2) {
158
+ filtered = !nsh;
159
+ } else { /* EL3 */
160
+ filtered = m != p;
161
+ }
75
+ }
162
+
76
+
163
+ return enabled && !prohibited && !filtered;
77
UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
78
SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
79
]
80
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/mve_helper.c
83
+++ b/target/arm/mve_helper.c
84
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
85
{
86
return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
164
}
87
}
165
+
88
+
166
/*
89
+uint32_t HELPER(mve_uqrshl)(CPUARMState *env, uint32_t n, uint32_t shift)
167
* Ensure c15_ccnt is the guest-visible count so that operations such as
168
* enabling/disabling the counter or filtering, modifying the count itself,
169
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_start(CPUARMState *env)
170
cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
171
ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
172
173
- if (arm_ccnt_enabled(env)) {
174
+ if (pmu_counter_enabled(env, 31)) {
175
uint64_t eff_cycles = cycles;
176
if (env->cp15.c9_pmcr & PMCRD) {
177
/* Increment once every 64 processor clock cycles */
178
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_start(CPUARMState *env)
179
*/
180
void pmccntr_op_finish(CPUARMState *env)
181
{
182
- if (arm_ccnt_enabled(env)) {
183
+ if (pmu_counter_enabled(env, 31)) {
184
uint64_t prev_cycles = env->cp15.c15_ccnt_delta;
185
186
if (env->cp15.c9_pmcr & PMCRD) {
187
@@ -XXX,XX +XXX,XX @@ void pmu_op_finish(CPUARMState *env)
188
pmccntr_op_finish(env);
189
}
190
191
+void pmu_pre_el_change(ARMCPU *cpu, void *ignored)
192
+{
90
+{
193
+ pmu_op_start(&cpu->env);
91
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, true, &env->QF);
194
+}
92
+}
195
+
93
+
196
+void pmu_post_el_change(ARMCPU *cpu, void *ignored)
94
+uint32_t HELPER(mve_sqrshr)(CPUARMState *env, uint32_t n, uint32_t shift)
197
+{
95
+{
198
+ pmu_op_finish(&cpu->env);
96
+ return do_sqrshl_bhs(n, -(int8_t)shift, 32, true, &env->QF);
97
+}
98
diff --git a/target/arm/translate.c b/target/arm/translate.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/translate.c
101
+++ b/target/arm/translate.c
102
@@ -XXX,XX +XXX,XX @@ static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
103
return do_mve_sh_ri(s, a, gen_mve_uqshl);
104
}
105
106
+static bool do_mve_sh_rr(DisasContext *s, arg_mve_sh_rr *a, ShiftFn *fn)
107
+{
108
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
109
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
110
+ return false;
111
+ }
112
+ if (!dc_isar_feature(aa32_mve, s) ||
113
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
114
+ a->rda == 13 || a->rda == 15 || a->rm == 13 || a->rm == 15 ||
115
+ a->rm == a->rda) {
116
+ /* These rda/rm cases are UNPREDICTABLE; we choose to UNDEF */
117
+ unallocated_encoding(s);
118
+ return true;
119
+ }
120
+
121
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
122
+ fn(cpu_R[a->rda], cpu_env, cpu_R[a->rda], cpu_R[a->rm]);
123
+ return true;
199
+}
124
+}
200
+
125
+
201
static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
126
+static bool trans_SQRSHR_rr(DisasContext *s, arg_mve_sh_rr *a)
202
uint64_t value)
203
{
204
@@ -XXX,XX +XXX,XX @@ void pmu_op_finish(CPUARMState *env)
205
{
206
}
207
208
+void pmu_pre_el_change(ARMCPU *cpu, void *ignored)
209
+{
127
+{
128
+ return do_mve_sh_rr(s, a, gen_helper_mve_sqrshr);
210
+}
129
+}
211
+
130
+
212
+void pmu_post_el_change(ARMCPU *cpu, void *ignored)
131
+static bool trans_UQRSHL_rr(DisasContext *s, arg_mve_sh_rr *a)
213
+{
132
+{
133
+ return do_mve_sh_rr(s, a, gen_helper_mve_uqrshl);
214
+}
134
+}
215
+
135
+
216
#endif
136
/*
217
137
* Multiply and multiply accumulate
218
static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
138
*/
219
--
139
--
220
2.20.1
140
2.20.1
221
141
222
142
diff view generated by jsdifflib
Deleted patch
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
2
1
3
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20181211151945.29137-6-aaron@os.amperecomputing.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/helper.c | 27 ++++++++++++++++++++++++++-
10
1 file changed, 26 insertions(+), 1 deletion(-)
11
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
17
PMXEVTYPER_M | PMXEVTYPER_MT | \
18
PMXEVTYPER_EVTCOUNT)
19
20
+#define PMCCFILTR 0xf8000000
21
+#define PMCCFILTR_M PMXEVTYPER_M
22
+#define PMCCFILTR_EL0 (PMCCFILTR | PMCCFILTR_M)
23
+
24
static inline uint32_t pmu_num_counters(CPUARMState *env)
25
{
26
return (env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT;
27
@@ -XXX,XX +XXX,XX @@ static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
28
uint64_t value)
29
{
30
pmccntr_op_start(env);
31
- env->cp15.pmccfiltr_el0 = value & 0xfc000000;
32
+ env->cp15.pmccfiltr_el0 = value & PMCCFILTR_EL0;
33
pmccntr_op_finish(env);
34
}
35
36
+static void pmccfiltr_write_a32(CPUARMState *env, const ARMCPRegInfo *ri,
37
+ uint64_t value)
38
+{
39
+ pmccntr_op_start(env);
40
+ /* M is not accessible from AArch32 */
41
+ env->cp15.pmccfiltr_el0 = (env->cp15.pmccfiltr_el0 & PMCCFILTR_M) |
42
+ (value & PMCCFILTR);
43
+ pmccntr_op_finish(env);
44
+}
45
+
46
+static uint64_t pmccfiltr_read_a32(CPUARMState *env, const ARMCPRegInfo *ri)
47
+{
48
+ /* M is not visible in AArch32 */
49
+ return env->cp15.pmccfiltr_el0 & PMCCFILTR;
50
+}
51
+
52
static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
53
uint64_t value)
54
{
55
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
56
.readfn = pmccntr_read, .writefn = pmccntr_write,
57
.raw_readfn = raw_read, .raw_writefn = raw_write, },
58
#endif
59
+ { .name = "PMCCFILTR", .cp = 15, .opc1 = 0, .crn = 14, .crm = 15, .opc2 = 7,
60
+ .writefn = pmccfiltr_write_a32, .readfn = pmccfiltr_read_a32,
61
+ .access = PL0_RW, .accessfn = pmreg_access,
62
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
63
+ .resetvalue = 0, },
64
{ .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
65
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
66
.writefn = pmccfiltr_write, .raw_writefn = raw_write,
67
--
68
2.20.1
69
70
diff view generated by jsdifflib
Deleted patch
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
2
1
3
Add an array for PMOVSSET so we only define it for v7ve+ platforms
4
5
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20181211151945.29137-7-aaron@os.amperecomputing.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper.c | 28 ++++++++++++++++++++++++++++
11
1 file changed, 28 insertions(+)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
18
env->cp15.c9_pmovsr &= ~value;
19
}
20
21
+static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
22
+ uint64_t value)
23
+{
24
+ value &= pmu_counter_mask(env);
25
+ env->cp15.c9_pmovsr |= value;
26
+}
27
+
28
static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
29
uint64_t value)
30
{
31
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7mp_cp_reginfo[] = {
32
REGINFO_SENTINEL
33
};
34
35
+static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
36
+ /* PMOVSSET is not implemented in v7 before v7ve */
37
+ { .name = "PMOVSSET", .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 3,
38
+ .access = PL0_RW, .accessfn = pmreg_access,
39
+ .type = ARM_CP_ALIAS,
40
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
41
+ .writefn = pmovsset_write,
42
+ .raw_writefn = raw_write },
43
+ { .name = "PMOVSSET_EL0", .state = ARM_CP_STATE_AA64,
44
+ .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 3,
45
+ .access = PL0_RW, .accessfn = pmreg_access,
46
+ .type = ARM_CP_ALIAS,
47
+ .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
48
+ .writefn = pmovsset_write,
49
+ .raw_writefn = raw_write },
50
+ REGINFO_SENTINEL
51
+};
52
+
53
static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
54
uint64_t value)
55
{
56
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
57
!arm_feature(env, ARM_FEATURE_PMSA)) {
58
define_arm_cp_regs(cpu, v7mp_cp_reginfo);
59
}
60
+ if (arm_feature(env, ARM_FEATURE_V7VE)) {
61
+ define_arm_cp_regs(cpu, pmovsset_cp_reginfo);
62
+ }
63
if (arm_feature(env, ARM_FEATURE_V7)) {
64
/* v7 performance monitor control register: same implementor
65
* field as main ID register, and we implement only the cycle
66
--
67
2.20.1
68
69
diff view generated by jsdifflib
Deleted patch
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
2
1
3
This is immediately necessary for the PMUv3 implementation to check
4
ID_DFR0.PerfMon to enable/disable specific features, but defines the
5
full complement of fields for possible future use elsewhere.
6
7
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20181211151945.29137-8-aaron@os.amperecomputing.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 9 +++++++++
13
1 file changed, 9 insertions(+)
14
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64MMFR1, PAN, 20, 4)
20
FIELD(ID_AA64MMFR1, SPECSEI, 24, 4)
21
FIELD(ID_AA64MMFR1, XNX, 28, 4)
22
23
+FIELD(ID_DFR0, COPDBG, 0, 4)
24
+FIELD(ID_DFR0, COPSDBG, 4, 4)
25
+FIELD(ID_DFR0, MMAPDBG, 8, 4)
26
+FIELD(ID_DFR0, COPTRC, 12, 4)
27
+FIELD(ID_DFR0, MMAPTRC, 16, 4)
28
+FIELD(ID_DFR0, MPROFDBG, 20, 4)
29
+FIELD(ID_DFR0, PERFMON, 24, 4)
30
+FIELD(ID_DFR0, TRACEFILT, 28, 4)
31
+
32
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
33
34
/* If adding a feature bit which corresponds to a Linux ELF
35
--
36
2.20.1
37
38
diff view generated by jsdifflib
Deleted patch
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
2
1
3
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20181211151945.29137-9-aaron@os.amperecomputing.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/cpu.h | 4 ++--
9
target/arm/helper.c | 19 +++++++++++++++++--
10
2 files changed, 19 insertions(+), 4 deletions(-)
11
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
15
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
17
uint32_t id_pfr0;
18
uint32_t id_pfr1;
19
uint32_t id_dfr0;
20
- uint32_t pmceid0;
21
- uint32_t pmceid1;
22
+ uint64_t pmceid0;
23
+ uint64_t pmceid1;
24
uint32_t id_afr0;
25
uint32_t id_mmfr0;
26
uint32_t id_mmfr1;
27
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/helper.c
30
+++ b/target/arm/helper.c
31
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
32
} else {
33
define_arm_cp_regs(cpu, not_v7_cp_reginfo);
34
}
35
+ if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
36
+ FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
37
+ ARMCPRegInfo v81_pmu_regs[] = {
38
+ { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
39
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
40
+ .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
41
+ .resetvalue = extract64(cpu->pmceid0, 32, 32) },
42
+ { .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
43
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
44
+ .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
45
+ .resetvalue = extract64(cpu->pmceid1, 32, 32) },
46
+ REGINFO_SENTINEL
47
+ };
48
+ define_arm_cp_regs(cpu, v81_pmu_regs);
49
+ }
50
if (arm_feature(env, ARM_FEATURE_V8)) {
51
/* AArch64 ID registers, which all have impdef reset values.
52
* Note that within the ID register ranges the unused slots
53
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
54
{ .name = "PMCEID0", .state = ARM_CP_STATE_AA32,
55
.cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 6,
56
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
57
- .resetvalue = cpu->pmceid0 },
58
+ .resetvalue = extract64(cpu->pmceid0, 0, 32) },
59
{ .name = "PMCEID0_EL0", .state = ARM_CP_STATE_AA64,
60
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 6,
61
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
62
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
63
{ .name = "PMCEID1", .state = ARM_CP_STATE_AA32,
64
.cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 7,
65
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
66
- .resetvalue = cpu->pmceid1 },
67
+ .resetvalue = extract64(cpu->pmceid1, 0, 32) },
68
{ .name = "PMCEID1_EL0", .state = ARM_CP_STATE_AA64,
69
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 7,
70
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
71
--
72
2.20.1
73
74
diff view generated by jsdifflib