1
The following changes since commit 003ba52a8b327180e284630b289c6ece5a3e08b9:
1
Hi; this mostly contains the first slice of A64 decodetree
2
patches, plus some other minor pieces. It also has the
3
enablement of MTE for KVM guests.
2
4
3
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging (2023-02-16 11:16:39 +0000)
5
thanks
6
-- PMM
7
8
The following changes since commit d27e7c359330ba7020bdbed7ed2316cb4cf6ffc1:
9
10
qapi/parser: Drop two bad type hints for now (2023-05-17 10:18:33 -0700)
4
11
5
are available in the Git repository at:
12
are available in the Git repository at:
6
13
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230216
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230518
8
15
9
for you to fetch changes up to caf01d6a435d9f4a95aeae2f9fc6cb8b889b1fb8:
16
for you to fetch changes up to 91608e2a44f36e79cb83f863b8a7bb57d2c98061:
10
17
11
tests/qtest: Restrict tpm-tis-devices-{swtpm}-test to CONFIG_TCG (2023-02-16 16:28:53 +0000)
18
docs: Convert u2f.txt to rST (2023-05-18 11:40:32 +0100)
12
19
13
----------------------------------------------------------------
20
----------------------------------------------------------------
14
target-arm queue:
21
target-arm queue:
15
* Some mostly M-profile-related code cleanups
22
* Fix vd == vm overlap in sve_ldff1_z
16
* avocado: Retire the boot_linux.py AArch64 TCG tests
23
* Add support for MTE with KVM guests
17
* hw/arm/smmuv3: Add GBPA register
24
* Add RAZ/WI handling for DBGDTR[TX|RX]
18
* arm/virt: don't try to spell out the accelerator
25
* Start of conversion of A64 decoder to decodetree
19
* hw/arm: Attach PSPI module to NPCM7XX SoC
26
* Saturate L2CTLR_EL1 core count field rather than overflowing
20
* Some cleanup/refactoring patches aiming towards
27
* vexpress: Avoid trivial memory leak of 'flashalias'
21
allowing building Arm targets without CONFIG_TCG
28
* sbsa-ref: switch default cpu core to Neoverse-N1
29
* sbsa-ref: use Bochs graphics card instead of VGA
30
* MAINTAINERS: Add Marcin Juszkiewicz to sbsa-ref reviewer list
31
* docs: Convert u2f.txt to rST
22
32
23
----------------------------------------------------------------
33
----------------------------------------------------------------
24
Alex Bennée (1):
34
Alex Bennée (1):
25
tests/avocado: retire the Aarch64 TCG tests from boot_linux.py
35
target/arm: add RAZ/WI handling for DBGDTR[TX|RX]
26
27
Claudio Fontana (3):
28
target/arm: rename handle_semihosting to tcg_handle_semihosting
29
target/arm: wrap psci call with tcg_enabled
30
target/arm: wrap call to aarch64_sve_change_el in tcg_enabled()
31
36
32
Cornelia Huck (1):
37
Cornelia Huck (1):
33
arm/virt: don't try to spell out the accelerator
38
arm/kvm: add support for MTE
34
39
35
Fabiano Rosas (7):
40
Marcin Juszkiewicz (3):
36
target/arm: Move PC alignment check
41
sbsa-ref: switch default cpu core to Neoverse-N1
37
target/arm: Move cpregs code out of cpu.h
42
Maintainers: add myself as reviewer for sbsa-ref
38
tests/avocado: Skip tests that require a missing accelerator
43
sbsa-ref: use Bochs graphics card instead of VGA
39
tests/avocado: Tag TCG tests with accel:tcg
40
target/arm: Use "max" as default cpu for the virt machine with KVM
41
tests/qtest: arm-cpu-features: Match tests to required accelerators
42
tests/qtest: Restrict tpm-tis-devices-{swtpm}-test to CONFIG_TCG
43
44
44
Hao Wu (3):
45
Peter Maydell (14):
45
MAINTAINERS: Add myself to maintainers and remove Havard
46
target/arm: Create decodetree skeleton for A64
46
hw/ssi: Add Nuvoton PSPI Module
47
target/arm: Pull calls to disas_sve() and disas_sme() out of legacy decoder
47
hw/arm: Attach PSPI module to NPCM7XX SoC
48
target/arm: Convert Extract instructions to decodetree
49
target/arm: Convert unconditional branch immediate to decodetree
50
target/arm: Convert CBZ, CBNZ to decodetree
51
target/arm: Convert TBZ, TBNZ to decodetree
52
target/arm: Convert conditional branch insns to decodetree
53
target/arm: Convert BR, BLR, RET to decodetree
54
target/arm: Convert BRA[AB]Z, BLR[AB]Z, RETA[AB] to decodetree
55
target/arm: Convert BRAA, BRAB, BLRAA, BLRAB to decodetree
56
target/arm: Convert ERET, ERETAA, ERETAB to decodetree
57
target/arm: Saturate L2CTLR_EL1 core count field rather than overflowing
58
hw/arm/vexpress: Avoid trivial memory leak of 'flashalias'
59
docs: Convert u2f.txt to rST
48
60
49
Jean-Philippe Brucker (2):
61
Richard Henderson (10):
50
hw/arm/smmu-common: Support 64-bit addresses
62
target/arm: Fix vd == vm overlap in sve_ldff1_z
51
hw/arm/smmu-common: Fix TTB1 handling
63
target/arm: Split out disas_a64_legacy
64
target/arm: Convert PC-rel addressing to decodetree
65
target/arm: Split gen_add_CC and gen_sub_CC
66
target/arm: Convert Add/subtract (immediate) to decodetree
67
target/arm: Convert Add/subtract (immediate with tags) to decodetree
68
target/arm: Replace bitmask64 with MAKE_64BIT_MASK
69
target/arm: Convert Logical (immediate) to decodetree
70
target/arm: Convert Move wide (immediate) to decodetree
71
target/arm: Convert Bitfield to decodetree
52
72
53
Mostafa Saleh (1):
73
MAINTAINERS | 1 +
54
hw/arm/smmuv3: Add GBPA register
74
docs/system/device-emulation.rst | 1 +
75
docs/system/devices/usb-u2f.rst | 93 +++
76
docs/system/devices/usb.rst | 2 +-
77
docs/u2f.txt | 110 ----
78
target/arm/cpu.h | 4 +
79
target/arm/kvm_arm.h | 19 +
80
target/arm/tcg/translate.h | 5 +
81
target/arm/tcg/a64.decode | 152 +++++
82
hw/arm/sbsa-ref.c | 4 +-
83
hw/arm/vexpress.c | 40 +-
84
hw/arm/virt.c | 73 ++-
85
target/arm/cortex-regs.c | 11 +-
86
target/arm/cpu.c | 9 +-
87
target/arm/debug_helper.c | 11 +-
88
target/arm/kvm.c | 35 +
89
target/arm/kvm64.c | 5 +
90
target/arm/tcg/sve_helper.c | 6 +
91
target/arm/tcg/translate-a64.c | 1321 ++++++++++++++++----------------------
92
target/arm/tcg/meson.build | 1 +
93
20 files changed, 979 insertions(+), 924 deletions(-)
94
create mode 100644 docs/system/devices/usb-u2f.rst
95
delete mode 100644 docs/u2f.txt
96
create mode 100644 target/arm/tcg/a64.decode
55
97
56
Philippe Mathieu-Daudé (12):
57
hw/intc/armv7m_nvic: Use OBJECT_DECLARE_SIMPLE_TYPE() macro
58
target/arm: Simplify arm_v7m_mmu_idx_for_secstate() for user emulation
59
target/arm: Reduce arm_v7m_mmu_idx_[all/for_secstate_and_priv]() scope
60
target/arm: Constify ID_PFR1 on user emulation
61
target/arm: Convert CPUARMState::eabi to boolean
62
target/arm: Avoid resetting CPUARMState::eabi field
63
target/arm: Restrict CPUARMState::gicv3state to sysemu
64
target/arm: Restrict CPUARMState::arm_boot_info to sysemu
65
target/arm: Restrict CPUARMState::nvic to sysemu
66
target/arm: Store CPUARMState::nvic as NVICState*
67
target/arm: Declare CPU <-> NVIC helpers in 'hw/intc/armv7m_nvic.h'
68
hw/arm: Add missing XLNX_ZYNQMP_ARM -> USB_DWC3 Kconfig dependency
69
70
MAINTAINERS | 8 +-
71
docs/system/arm/nuvoton.rst | 2 +-
72
hw/arm/smmuv3-internal.h | 7 +
73
include/hw/arm/npcm7xx.h | 2 +
74
include/hw/arm/smmu-common.h | 2 -
75
include/hw/arm/smmuv3.h | 1 +
76
include/hw/intc/armv7m_nvic.h | 128 +++++++++++++++++-
77
include/hw/ssi/npcm_pspi.h | 53 ++++++++
78
linux-user/user-internals.h | 2 +-
79
target/arm/cpregs.h | 98 ++++++++++++++
80
target/arm/cpu.h | 228 ++-------------------------------
81
target/arm/internals.h | 14 --
82
hw/arm/npcm7xx.c | 25 +++-
83
hw/arm/smmu-common.c | 4 +-
84
hw/arm/smmuv3.c | 43 ++++++-
85
hw/arm/virt.c | 10 +-
86
hw/intc/armv7m_nvic.c | 38 ++----
87
hw/ssi/npcm_pspi.c | 221 ++++++++++++++++++++++++++++++++
88
linux-user/arm/cpu_loop.c | 4 +-
89
target/arm/cpu.c | 5 +-
90
target/arm/cpu_tcg.c | 3 +
91
target/arm/helper.c | 31 +++--
92
target/arm/m_helper.c | 86 +++++++------
93
target/arm/machine.c | 18 +--
94
tests/qtest/arm-cpu-features.c | 28 ++--
95
hw/arm/Kconfig | 1 +
96
hw/ssi/meson.build | 2 +-
97
hw/ssi/trace-events | 5 +
98
tests/avocado/avocado_qemu/__init__.py | 4 +
99
tests/avocado/boot_linux.py | 48 ++-----
100
tests/avocado/boot_linux_console.py | 1 +
101
tests/avocado/machine_aarch64_virt.py | 63 ++++++++-
102
tests/avocado/reverse_debugging.py | 8 ++
103
tests/qtest/meson.build | 4 +-
104
34 files changed, 798 insertions(+), 399 deletions(-)
105
create mode 100644 include/hw/ssi/npcm_pspi.h
106
create mode 100644 hw/ssi/npcm_pspi.c
107
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
Manually convert to OBJECT_DECLARE_SIMPLE_TYPE() macro,
4
similarly to automatic conversion from commit 8063396bf3
5
("Use OBJECT_DECLARE_SIMPLE_TYPE when possible").
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230206223502.25122-2-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/intc/armv7m_nvic.h | 5 +----
13
1 file changed, 1 insertion(+), 4 deletions(-)
14
15
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/intc/armv7m_nvic.h
18
+++ b/include/hw/intc/armv7m_nvic.h
19
@@ -XXX,XX +XXX,XX @@
20
#include "qom/object.h"
21
22
#define TYPE_NVIC "armv7m_nvic"
23
-
24
-typedef struct NVICState NVICState;
25
-DECLARE_INSTANCE_CHECKER(NVICState, NVIC,
26
- TYPE_NVIC)
27
+OBJECT_DECLARE_SIMPLE_TYPE(NVICState, NVIC)
28
29
/* Highest permitted number of exceptions (architectural limit) */
30
#define NVIC_MAX_VECTORS 512
31
--
32
2.34.1
33
34
diff view generated by jsdifflib
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
Addresses targeting the second translation table (TTB1) in the SMMU have
3
The world outside moves to newer and newer cpu cores. Let move SBSA
4
all upper bits set (except for the top byte when TBI is enabled). Fix
4
Reference Platform to something newer as well.
5
the TTB1 check.
6
5
7
Reported-by: Ola Hugosson <ola.hugosson@arm.com>
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230506183417.1360427-1-marcin.juszkiewicz@linaro.org
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
11
Message-id: 20230214171921.1917916-3-jean-philippe@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
hw/arm/smmu-common.c | 2 +-
11
hw/arm/sbsa-ref.c | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
16
13
17
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
14
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/smmu-common.c
16
--- a/hw/arm/sbsa-ref.c
20
+++ b/hw/arm/smmu-common.c
17
+++ b/hw/arm/sbsa-ref.c
21
@@ -XXX,XX +XXX,XX @@ SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova)
18
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_class_init(ObjectClass *oc, void *data)
22
/* there is a ttbr0 region and we are in it (high bits all zero) */
19
23
return &cfg->tt[0];
20
mc->init = sbsa_ref_init;
24
} else if (cfg->tt[1].tsz &&
21
mc->desc = "QEMU 'SBSA Reference' ARM Virtual Machine";
25
- !extract64(iova, 64 - cfg->tt[1].tsz, cfg->tt[1].tsz - tbi_byte)) {
22
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a57");
26
+ sextract64(iova, 64 - cfg->tt[1].tsz, cfg->tt[1].tsz - tbi_byte) == -1) {
23
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("neoverse-n1");
27
/* there is a ttbr1 region and we are in it (high bits all one) */
24
mc->max_cpus = 512;
28
return &cfg->tt[1];
25
mc->pci_allow_0_address = true;
29
} else if (!cfg->tt[0].tsz) {
26
mc->minimum_page_bits = 12;
30
--
27
--
31
2.34.1
28
2.34.1
diff view generated by jsdifflib
1
From: Fabiano Rosas <farosas@suse.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This allows the test to be skipped when TCG is not present in the QEMU
3
If vd == vm, copy vm to scratch, so that we can pre-zero
4
binary.
4
the output and still access the gather indicies.
5
5
6
Signed-off-by: Fabiano Rosas <farosas@suse.de>
6
Cc: qemu-stable@nongnu.org
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1612
8
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230504104232.1877774-1-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
tests/avocado/boot_linux_console.py | 1 +
13
target/arm/tcg/sve_helper.c | 6 ++++++
12
tests/avocado/reverse_debugging.py | 8 ++++++++
14
1 file changed, 6 insertions(+)
13
2 files changed, 9 insertions(+)
14
15
15
diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py
16
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/avocado/boot_linux_console.py
18
--- a/target/arm/tcg/sve_helper.c
18
+++ b/tests/avocado/boot_linux_console.py
19
+++ b/target/arm/tcg/sve_helper.c
19
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_uboot_netbsd9(self):
20
@@ -XXX,XX +XXX,XX @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
20
21
intptr_t reg_off;
21
def test_aarch64_raspi3_atf(self):
22
SVEHostPage info;
22
"""
23
target_ulong addr, in_page;
23
+ :avocado: tags=accel:tcg
24
+ ARMVectorReg scratch;
24
:avocado: tags=arch:aarch64
25
25
:avocado: tags=machine:raspi3b
26
/* Skip to the first true predicate. */
26
:avocado: tags=cpu:cortex-a53
27
reg_off = find_next_active(vg, 0, reg_max, esz);
27
diff --git a/tests/avocado/reverse_debugging.py b/tests/avocado/reverse_debugging.py
28
@@ -XXX,XX +XXX,XX @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
28
index XXXXXXX..XXXXXXX 100644
29
return;
29
--- a/tests/avocado/reverse_debugging.py
30
}
30
+++ b/tests/avocado/reverse_debugging.py
31
31
@@ -XXX,XX +XXX,XX @@ def reverse_debugging(self, shift=7, args=None):
32
+ /* Protect against overlap between vd and vm. */
32
vm.shutdown()
33
+ if (unlikely(vd == vm)) {
33
34
+ vm = memcpy(&scratch, vm, reg_max);
34
class ReverseDebugging_X86_64(ReverseDebugging):
35
+ }
35
+ """
36
+ :avocado: tags=accel:tcg
37
+ """
38
+
36
+
39
REG_PC = 0x10
37
/*
40
REG_CS = 0x12
38
* Probe the first element, allowing faults.
41
def get_pc(self, g):
39
*/
42
@@ -XXX,XX +XXX,XX @@ def test_x86_64_pc(self):
43
self.reverse_debugging()
44
45
class ReverseDebugging_AArch64(ReverseDebugging):
46
+ """
47
+ :avocado: tags=accel:tcg
48
+ """
49
+
50
REG_PC = 32
51
52
# unidentified gitlab timeout problem
53
--
40
--
54
2.34.1
41
2.34.1
55
56
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
Since commit acc0b8b05a when running the ZynqMP ZCU102 board with
3
At Linaro I work on sbsa-ref, know direction it goes.
4
a QEMU configured using --without-default-devices, we get:
5
4
6
$ qemu-system-aarch64 -M xlnx-zcu102
5
May not get code details each time.
7
qemu-system-aarch64: missing object type 'usb_dwc3'
8
Abort trap: 6
9
6
10
Fix by adding the missing Kconfig dependency.
7
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
11
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Fixes: acc0b8b05a ("hw/arm/xlnx-zynqmp: Connect ZynqMP's USB controllers")
9
Message-id: 20230515143753.365591-1-marcin.juszkiewicz@linaro.org
13
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Message-id: 20230216092327.2203-1-philmd@linaro.org
15
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
11
---
18
hw/arm/Kconfig | 1 +
12
MAINTAINERS | 1 +
19
1 file changed, 1 insertion(+)
13
1 file changed, 1 insertion(+)
20
14
21
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
15
diff --git a/MAINTAINERS b/MAINTAINERS
22
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/Kconfig
17
--- a/MAINTAINERS
24
+++ b/hw/arm/Kconfig
18
+++ b/MAINTAINERS
25
@@ -XXX,XX +XXX,XX @@ config XLNX_ZYNQMP_ARM
19
@@ -XXX,XX +XXX,XX @@ SBSA-REF
26
select XLNX_CSU_DMA
20
M: Radoslaw Biernacki <rad@semihalf.com>
27
select XLNX_ZYNQMP
21
M: Peter Maydell <peter.maydell@linaro.org>
28
select XLNX_ZDMA
22
R: Leif Lindholm <quic_llindhol@quicinc.com>
29
+ select USB_DWC3
23
+R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
30
24
L: qemu-arm@nongnu.org
31
config XLNX_VERSAL
25
S: Maintained
32
bool
26
F: hw/arm/sbsa-ref.c
33
--
27
--
34
2.34.1
28
2.34.1
35
29
36
30
diff view generated by jsdifflib
1
From: Cornelia Huck <cohuck@redhat.com>
1
From: Cornelia Huck <cohuck@redhat.com>
2
2
3
Just use current_accel_name() directly.
3
Extend the 'mte' property for the virt machine to cover KVM as
4
well. For KVM, we don't allocate tag memory, but instead enable the
5
capability.
6
7
If MTE has been enabled, we need to disable migration, as we do not
8
yet have a way to migrate the tags as well. Therefore, MTE will stay
9
off with KVM unless requested explicitly.
4
10
5
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
11
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
6
Reviewed-by: Eric Auger <eric.auger@redhat.com>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20230428095533.21747-2-cohuck@redhat.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
16
---
10
hw/arm/virt.c | 6 +++---
17
target/arm/cpu.h | 4 +++
11
1 file changed, 3 insertions(+), 3 deletions(-)
18
target/arm/kvm_arm.h | 19 ++++++++++++
12
19
hw/arm/virt.c | 73 +++++++++++++++++++++++++-------------------
20
target/arm/cpu.c | 9 +++---
21
target/arm/kvm.c | 35 +++++++++++++++++++++
22
target/arm/kvm64.c | 5 +++
23
6 files changed, 109 insertions(+), 36 deletions(-)
24
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu.h
28
+++ b/target/arm/cpu.h
29
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
30
*/
31
uint32_t psci_conduit;
32
33
+ /* CPU has Memory Tag Extension */
34
+ bool has_mte;
35
+
36
/* For v8M, initial value of the Secure VTOR */
37
uint32_t init_svtor;
38
/* For v8M, initial value of the Non-secure VTOR */
39
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
40
bool prop_pauth;
41
bool prop_pauth_impdef;
42
bool prop_lpa2;
43
+ OnOffAuto prop_mte;
44
45
/* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
46
uint32_t dcz_blocksize;
47
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/kvm_arm.h
50
+++ b/target/arm/kvm_arm.h
51
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_pmu_supported(void);
52
*/
53
bool kvm_arm_sve_supported(void);
54
55
+/**
56
+ * kvm_arm_mte_supported:
57
+ *
58
+ * Returns: true if KVM can enable MTE, and false otherwise.
59
+ */
60
+bool kvm_arm_mte_supported(void);
61
+
62
/**
63
* kvm_arm_get_max_vm_ipa_size:
64
* @ms: Machine state handle
65
@@ -XXX,XX +XXX,XX @@ void kvm_arm_pvtime_init(CPUState *cs, uint64_t ipa);
66
67
int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level);
68
69
+void kvm_arm_enable_mte(Object *cpuobj, Error **errp);
70
+
71
#else
72
73
/*
74
@@ -XXX,XX +XXX,XX @@ static inline bool kvm_arm_steal_time_supported(void)
75
return false;
76
}
77
78
+static inline bool kvm_arm_mte_supported(void)
79
+{
80
+ return false;
81
+}
82
+
83
/*
84
* These functions should never actually be called without KVM support.
85
*/
86
@@ -XXX,XX +XXX,XX @@ static inline uint32_t kvm_arm_sve_get_vls(CPUState *cs)
87
g_assert_not_reached();
88
}
89
90
+static inline void kvm_arm_enable_mte(Object *cpuobj, Error **errp)
91
+{
92
+ g_assert_not_reached();
93
+}
94
+
95
#endif
96
97
static inline const char *gic_class_name(void)
13
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
98
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
14
index XXXXXXX..XXXXXXX 100644
99
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/virt.c
100
--- a/hw/arm/virt.c
16
+++ b/hw/arm/virt.c
101
+++ b/hw/arm/virt.c
17
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
102
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
18
if (vms->secure && (kvm_enabled() || hvf_enabled())) {
19
error_report("mach-virt: %s does not support providing "
20
"Security extensions (TrustZone) to the guest CPU",
21
- kvm_enabled() ? "KVM" : "HVF");
22
+ current_accel_name());
23
exit(1);
103
exit(1);
24
}
104
}
25
105
26
if (vms->virt && (kvm_enabled() || hvf_enabled())) {
106
- if (vms->mte && (kvm_enabled() || hvf_enabled())) {
27
error_report("mach-virt: %s does not support providing "
107
+ if (vms->mte && hvf_enabled()) {
28
"Virtualization extensions to the guest CPU",
29
- kvm_enabled() ? "KVM" : "HVF");
30
+ current_accel_name());
31
exit(1);
32
}
33
34
if (vms->mte && (kvm_enabled() || hvf_enabled())) {
35
error_report("mach-virt: %s does not support providing "
108
error_report("mach-virt: %s does not support providing "
36
"MTE to the guest CPU",
109
"MTE to the guest CPU",
37
- kvm_enabled() ? "KVM" : "HVF");
110
current_accel_name());
38
+ current_accel_name());
111
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
39
exit(1);
112
}
113
114
if (vms->mte) {
115
- /* Create the memory region only once, but link to all cpus. */
116
- if (!tag_sysmem) {
117
- /*
118
- * The property exists only if MemTag is supported.
119
- * If it is, we must allocate the ram to back that up.
120
- */
121
- if (!object_property_find(cpuobj, "tag-memory")) {
122
- error_report("MTE requested, but not supported "
123
- "by the guest CPU");
124
+ if (tcg_enabled()) {
125
+ /* Create the memory region only once, but link to all cpus. */
126
+ if (!tag_sysmem) {
127
+ /*
128
+ * The property exists only if MemTag is supported.
129
+ * If it is, we must allocate the ram to back that up.
130
+ */
131
+ if (!object_property_find(cpuobj, "tag-memory")) {
132
+ error_report("MTE requested, but not supported "
133
+ "by the guest CPU");
134
+ exit(1);
135
+ }
136
+
137
+ tag_sysmem = g_new(MemoryRegion, 1);
138
+ memory_region_init(tag_sysmem, OBJECT(machine),
139
+ "tag-memory", UINT64_MAX / 32);
140
+
141
+ if (vms->secure) {
142
+ secure_tag_sysmem = g_new(MemoryRegion, 1);
143
+ memory_region_init(secure_tag_sysmem, OBJECT(machine),
144
+ "secure-tag-memory",
145
+ UINT64_MAX / 32);
146
+
147
+ /* As with ram, secure-tag takes precedence over tag. */
148
+ memory_region_add_subregion_overlap(secure_tag_sysmem,
149
+ 0, tag_sysmem, -1);
150
+ }
151
+ }
152
+
153
+ object_property_set_link(cpuobj, "tag-memory",
154
+ OBJECT(tag_sysmem), &error_abort);
155
+ if (vms->secure) {
156
+ object_property_set_link(cpuobj, "secure-tag-memory",
157
+ OBJECT(secure_tag_sysmem),
158
+ &error_abort);
159
+ }
160
+ } else if (kvm_enabled()) {
161
+ if (!kvm_arm_mte_supported()) {
162
+ error_report("MTE requested, but not supported by KVM");
163
exit(1);
164
}
165
-
166
- tag_sysmem = g_new(MemoryRegion, 1);
167
- memory_region_init(tag_sysmem, OBJECT(machine),
168
- "tag-memory", UINT64_MAX / 32);
169
-
170
- if (vms->secure) {
171
- secure_tag_sysmem = g_new(MemoryRegion, 1);
172
- memory_region_init(secure_tag_sysmem, OBJECT(machine),
173
- "secure-tag-memory", UINT64_MAX / 32);
174
-
175
- /* As with ram, secure-tag takes precedence over tag. */
176
- memory_region_add_subregion_overlap(secure_tag_sysmem, 0,
177
- tag_sysmem, -1);
178
- }
179
- }
180
-
181
- object_property_set_link(cpuobj, "tag-memory", OBJECT(tag_sysmem),
182
- &error_abort);
183
- if (vms->secure) {
184
- object_property_set_link(cpuobj, "secure-tag-memory",
185
- OBJECT(secure_tag_sysmem),
186
- &error_abort);
187
+ kvm_arm_enable_mte(cpuobj, &error_abort);
188
}
189
}
190
191
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
192
index XXXXXXX..XXXXXXX 100644
193
--- a/target/arm/cpu.c
194
+++ b/target/arm/cpu.c
195
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
196
qdev_prop_allow_set_link_before_realize,
197
OBJ_PROP_LINK_STRONG);
198
}
199
+ cpu->has_mte = true;
40
}
200
}
41
201
#endif
202
}
203
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
204
}
205
if (cpu->tag_memory) {
206
error_setg(errp,
207
- "Cannot enable %s when guest CPUs has MTE enabled",
208
+ "Cannot enable %s when guest CPUs has tag memory enabled",
209
current_accel_name());
210
return;
211
}
212
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
213
}
214
215
#ifndef CONFIG_USER_ONLY
216
- if (cpu->tag_memory == NULL && cpu_isar_feature(aa64_mte, cpu)) {
217
+ if (!cpu->has_mte && cpu_isar_feature(aa64_mte, cpu)) {
218
/*
219
- * Disable the MTE feature bits if we do not have tag-memory
220
- * provided by the machine.
221
+ * Disable the MTE feature bits if we do not have the feature
222
+ * setup by the machine.
223
*/
224
cpu->isar.id_aa64pfr1 =
225
FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 0);
226
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
227
index XXXXXXX..XXXXXXX 100644
228
--- a/target/arm/kvm.c
229
+++ b/target/arm/kvm.c
230
@@ -XXX,XX +XXX,XX @@
231
#include "hw/boards.h"
232
#include "hw/irq.h"
233
#include "qemu/log.h"
234
+#include "migration/blocker.h"
235
236
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
237
KVM_CAP_LAST_INFO
238
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_cpu_check_are_resettable(void)
239
void kvm_arch_accel_class_init(ObjectClass *oc)
240
{
241
}
242
+
243
+void kvm_arm_enable_mte(Object *cpuobj, Error **errp)
244
+{
245
+ static bool tried_to_enable;
246
+ static bool succeeded_to_enable;
247
+ Error *mte_migration_blocker = NULL;
248
+ int ret;
249
+
250
+ if (!tried_to_enable) {
251
+ /*
252
+ * MTE on KVM is enabled on a per-VM basis (and retrying doesn't make
253
+ * sense), and we only want a single migration blocker as well.
254
+ */
255
+ tried_to_enable = true;
256
+
257
+ ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_MTE, 0);
258
+ if (ret) {
259
+ error_setg_errno(errp, -ret, "Failed to enable KVM_CAP_ARM_MTE");
260
+ return;
261
+ }
262
+
263
+ /* TODO: add proper migration support with MTE enabled */
264
+ error_setg(&mte_migration_blocker,
265
+ "Live migration disabled due to MTE enabled");
266
+ if (migrate_add_blocker(mte_migration_blocker, errp)) {
267
+ error_free(mte_migration_blocker);
268
+ return;
269
+ }
270
+ succeeded_to_enable = true;
271
+ }
272
+ if (succeeded_to_enable) {
273
+ object_property_set_bool(cpuobj, "has_mte", true, NULL);
274
+ }
275
+}
276
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
277
index XXXXXXX..XXXXXXX 100644
278
--- a/target/arm/kvm64.c
279
+++ b/target/arm/kvm64.c
280
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_steal_time_supported(void)
281
return kvm_check_extension(kvm_state, KVM_CAP_STEAL_TIME);
282
}
283
284
+bool kvm_arm_mte_supported(void)
285
+{
286
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_MTE);
287
+}
288
+
289
QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
290
291
uint32_t kvm_arm_sve_get_vls(CPUState *cs)
42
--
292
--
43
2.34.1
293
2.34.1
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
The two TCG tests for GICv2 and GICv3 are very heavy weight distros
3
The commit b3aa2f2128 (target/arm: provide stubs for more external
4
that take a long time to boot up, especially for an --enable-debug
4
debug registers) was added to handle HyperV's unconditional usage of
5
build. The total code coverage they give is:
5
Debug Communications Channel. It turns out that Linux will similarly
6
break if you enable CONFIG_HVC_DCC "ARM JTAG DCC console".
6
7
7
Overall coverage rate:
8
Extend the registers we RAZ/WI set to avoid this.
8
lines......: 11.2% (59584 of 530123 lines)
9
functions..: 15.0% (7436 of 49443 functions)
10
branches...: 6.3% (19273 of 303933 branches)
11
9
12
We already get pretty close to that with the machine_aarch64_virt
10
Cc: Anders Roxell <anders.roxell@linaro.org>
13
tests which only does one full boot (~120s vs ~600s) of alpine. We
11
Cc: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
14
expand the kernel+initrd boot (~8s) to test both GICs and also add an
15
RNG device and a block device to generate a few IRQs and exercise the
16
storage layer. With that we get to a coverage of:
17
18
Overall coverage rate:
19
lines......: 11.0% (58121 of 530123 lines)
20
functions..: 14.9% (7343 of 49443 functions)
21
branches...: 6.0% (18269 of 303933 branches)
22
23
which I feel is close enough given the massive time saving. If we want
24
to target any more sub-systems we can use lighter weight more directed
25
tests.
26
27
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
12
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
28
Reviewed-by: Fabiano Rosas <farosas@suse.de>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Acked-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20230516104420.407912-1-alex.bennee@linaro.org
30
Message-id: 20230203181632.2919715-1-alex.bennee@linaro.org
31
Cc: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
---
16
---
34
tests/avocado/boot_linux.py | 48 ++++----------------
17
target/arm/debug_helper.c | 11 +++++++++--
35
tests/avocado/machine_aarch64_virt.py | 63 ++++++++++++++++++++++++---
18
1 file changed, 9 insertions(+), 2 deletions(-)
36
2 files changed, 65 insertions(+), 46 deletions(-)
37
19
38
diff --git a/tests/avocado/boot_linux.py b/tests/avocado/boot_linux.py
20
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
39
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
40
--- a/tests/avocado/boot_linux.py
22
--- a/target/arm/debug_helper.c
41
+++ b/tests/avocado/boot_linux.py
23
+++ b/target/arm/debug_helper.c
42
@@ -XXX,XX +XXX,XX @@ def test_pc_q35_kvm(self):
24
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
43
self.launch_and_wait(set_up_ssh_connection=False)
25
.access = PL0_R, .accessfn = access_tdcc,
44
26
.type = ARM_CP_CONST, .resetvalue = 0 },
45
27
/*
46
-# For Aarch64 we only boot KVM tests in CI as the TCG tests are very
28
- * OSDTRRX_EL1/OSDTRTX_EL1 are used for save and restore of DBGDTRRX_EL0.
47
-# heavyweight. There are lighter weight distros which we use in the
29
- * It is a component of the Debug Communications Channel, which is not implemented.
48
-# machine_aarch64_virt.py tests.
30
+ * These registers belong to the Debug Communications Channel,
49
+# For Aarch64 we only boot KVM tests in CI as booting the current
31
+ * which is not implemented. However we implement RAZ/WI behaviour
50
+# Fedora OS in TCG tests is very heavyweight. There are lighter weight
32
+ * with trapping to prevent spurious SIGILLs if the guest OS does
51
+# distros which we use in the machine_aarch64_virt.py tests.
33
+ * access them as the support cannot be probed for.
52
class BootLinuxAarch64(LinuxTest):
34
*/
53
"""
35
{ .name = "OSDTRRX_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14,
54
:avocado: tags=arch:aarch64
36
.opc0 = 2, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 2,
55
:avocado: tags=machine:virt
37
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
56
- :avocado: tags=machine:gic-version=2
38
.opc0 = 2, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
57
"""
39
.access = PL1_RW, .accessfn = access_tdcc,
58
timeout = 720
40
.type = ARM_CP_CONST, .resetvalue = 0 },
59
41
+ /* DBGDTRTX_EL0/DBGDTRRX_EL0 depend on direction */
60
- def add_common_args(self):
42
+ { .name = "DBGDTR_EL0", .state = ARM_CP_STATE_BOTH, .cp = 14,
61
- self.vm.add_args('-bios',
43
+ .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 5, .opc2 = 0,
62
- os.path.join(BUILD_DIR, 'pc-bios',
44
+ .access = PL0_RW, .accessfn = access_tdcc,
63
- 'edk2-aarch64-code.fd'))
45
+ .type = ARM_CP_CONST, .resetvalue = 0 },
64
- self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
46
/*
65
- self.vm.add_args('-object', 'rng-random,id=rng0,filename=/dev/urandom')
47
* OSECCR_EL1 provides a mechanism for an operating system
66
-
48
* to access the contents of EDECCR. EDECCR is not implemented though,
67
- @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
68
- def test_fedora_cloud_tcg_gicv2(self):
69
- """
70
- :avocado: tags=accel:tcg
71
- :avocado: tags=cpu:max
72
- :avocado: tags=device:gicv2
73
- """
74
- self.require_accelerator("tcg")
75
- self.vm.add_args("-accel", "tcg")
76
- self.vm.add_args("-cpu", "max,lpa2=off")
77
- self.vm.add_args("-machine", "virt,gic-version=2")
78
- self.add_common_args()
79
- self.launch_and_wait(set_up_ssh_connection=False)
80
-
81
- @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
82
- def test_fedora_cloud_tcg_gicv3(self):
83
- """
84
- :avocado: tags=accel:tcg
85
- :avocado: tags=cpu:max
86
- :avocado: tags=device:gicv3
87
- """
88
- self.require_accelerator("tcg")
89
- self.vm.add_args("-accel", "tcg")
90
- self.vm.add_args("-cpu", "max,lpa2=off")
91
- self.vm.add_args("-machine", "virt,gic-version=3")
92
- self.add_common_args()
93
- self.launch_and_wait(set_up_ssh_connection=False)
94
-
95
def test_virt_kvm(self):
96
"""
97
:avocado: tags=accel:kvm
98
@@ -XXX,XX +XXX,XX @@ def test_virt_kvm(self):
99
self.require_accelerator("kvm")
100
self.vm.add_args("-accel", "kvm")
101
self.vm.add_args("-machine", "virt,gic-version=host")
102
- self.add_common_args()
103
+ self.vm.add_args('-bios',
104
+ os.path.join(BUILD_DIR, 'pc-bios',
105
+ 'edk2-aarch64-code.fd'))
106
+ self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
107
+ self.vm.add_args('-object', 'rng-random,id=rng0,filename=/dev/urandom')
108
self.launch_and_wait(set_up_ssh_connection=False)
109
110
111
diff --git a/tests/avocado/machine_aarch64_virt.py b/tests/avocado/machine_aarch64_virt.py
112
index XXXXXXX..XXXXXXX 100644
113
--- a/tests/avocado/machine_aarch64_virt.py
114
+++ b/tests/avocado/machine_aarch64_virt.py
115
@@ -XXX,XX +XXX,XX @@
116
117
import time
118
import os
119
+import logging
120
121
from avocado_qemu import QemuSystemTest
122
from avocado_qemu import wait_for_console_pattern
123
from avocado_qemu import exec_command
124
from avocado_qemu import BUILD_DIR
125
+from avocado.utils import process
126
+from avocado.utils.path import find_command
127
128
class Aarch64VirtMachine(QemuSystemTest):
129
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
130
@@ -XXX,XX +XXX,XX @@ def test_alpine_virt_tcg_gic_max(self):
131
self.wait_for_console_pattern('Welcome to Alpine Linux 3.16')
132
133
134
- def test_aarch64_virt(self):
135
+ def common_aarch64_virt(self, machine):
136
"""
137
- :avocado: tags=arch:aarch64
138
- :avocado: tags=machine:virt
139
- :avocado: tags=accel:tcg
140
- :avocado: tags=cpu:max
141
+ Common code to launch basic virt machine with kernel+initrd
142
+ and a scratch disk.
143
"""
144
+ logger = logging.getLogger('aarch64_virt')
145
+
146
kernel_url = ('https://fileserver.linaro.org/s/'
147
'z6B2ARM7DQT3HWN/download')
148
-
149
kernel_hash = 'ed11daab50c151dde0e1e9c9cb8b2d9bd3215347'
150
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
151
152
@@ -XXX,XX +XXX,XX @@ def test_aarch64_virt(self):
153
'console=ttyAMA0')
154
self.require_accelerator("tcg")
155
self.vm.add_args('-cpu', 'max,pauth-impdef=on',
156
+ '-machine', machine,
157
'-accel', 'tcg',
158
'-kernel', kernel_path,
159
'-append', kernel_command_line)
160
+
161
+ # A RNG offers an easy way to generate a few IRQs
162
+ self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
163
+ self.vm.add_args('-object',
164
+ 'rng-random,id=rng0,filename=/dev/urandom')
165
+
166
+ # Also add a scratch block device
167
+ logger.info('creating scratch qcow2 image')
168
+ image_path = os.path.join(self.workdir, 'scratch.qcow2')
169
+ qemu_img = os.path.join(BUILD_DIR, 'qemu-img')
170
+ if not os.path.exists(qemu_img):
171
+ qemu_img = find_command('qemu-img', False)
172
+ if qemu_img is False:
173
+ self.cancel('Could not find "qemu-img", which is required to '
174
+ 'create the temporary qcow2 image')
175
+ cmd = '%s create -f qcow2 %s 8M' % (qemu_img, image_path)
176
+ process.run(cmd)
177
+
178
+ # Add the device
179
+ self.vm.add_args('-blockdev',
180
+ f"driver=qcow2,file.driver=file,file.filename={image_path},node-name=scratch")
181
+ self.vm.add_args('-device',
182
+ 'virtio-blk-device,drive=scratch')
183
+
184
self.vm.launch()
185
self.wait_for_console_pattern('Welcome to Buildroot')
186
time.sleep(0.1)
187
exec_command(self, 'root')
188
time.sleep(0.1)
189
+ exec_command(self, 'dd if=/dev/hwrng of=/dev/vda bs=512 count=4')
190
+ time.sleep(0.1)
191
+ exec_command(self, 'md5sum /dev/vda')
192
+ time.sleep(0.1)
193
+ exec_command(self, 'cat /proc/interrupts')
194
+ time.sleep(0.1)
195
exec_command(self, 'cat /proc/self/maps')
196
time.sleep(0.1)
197
+
198
+ def test_aarch64_virt_gicv3(self):
199
+ """
200
+ :avocado: tags=arch:aarch64
201
+ :avocado: tags=machine:virt
202
+ :avocado: tags=accel:tcg
203
+ :avocado: tags=cpu:max
204
+ """
205
+ self.common_aarch64_virt("virt,gic_version=3")
206
+
207
+ def test_aarch64_virt_gicv2(self):
208
+ """
209
+ :avocado: tags=arch:aarch64
210
+ :avocado: tags=machine:virt
211
+ :avocado: tags=accel:tcg
212
+ :avocado: tags=cpu:max
213
+ """
214
+ self.common_aarch64_virt("virt,gic-version=2")
215
--
49
--
216
2.34.1
50
2.34.1
217
51
218
52
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
3
Bochs card is normal PCI Express card so it fits better in system with
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
PCI Express bus. VGA is simple legacy PCI card.
5
Message-id: 20230206223502.25122-10-philmd@linaro.org
5
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
8
Message-id: 20230505120936.1097060-1-marcin.juszkiewicz@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/cpu.h | 2 +-
11
hw/arm/sbsa-ref.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
10
13
11
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu.h
16
--- a/hw/arm/sbsa-ref.c
14
+++ b/target/arm/cpu.h
17
+++ b/hw/arm/sbsa-ref.c
15
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
18
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms)
16
uint32_t ctrl;
19
}
17
} sau;
20
}
18
21
19
- void *nvic;
22
- pci_create_simple(pci->bus, -1, "VGA");
20
#if !defined(CONFIG_USER_ONLY)
23
+ pci_create_simple(pci->bus, -1, "bochs-display");
21
+ void *nvic;
24
22
const struct arm_boot_info *boot_info;
25
create_smmu(sms, pci->bus);
23
/* Store GICv3CPUState to access from this struct */
26
}
24
void *gicv3state;
25
--
27
--
26
2.34.1
28
2.34.1
27
28
diff view generated by jsdifflib
1
From: Mostafa Saleh <smostafa@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
GBPA register can be used to globally abort all
3
Split out all of the decode stuff from aarch64_tr_translate_insn.
4
transactions.
4
Call it disas_a64_legacy to indicate it will be replaced.
5
5
6
It is described in the SMMU manual in "6.3.14 SMMU_GBPA".
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
ABORT reset value is IMPLEMENTATION DEFINED, it is chosen to
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
be zero(Do not abort incoming transactions).
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
9
Message-id: 20230512144106.3608981-2-peter.maydell@linaro.org
10
Other fields have default values of Use Incoming.
10
[PMM: Rebased]
11
12
If UPDATE is not set, the write is ignored. This is the only permitted
13
behavior in SMMUv3.2 and later.(6.3.14.1 Update procedure)
14
15
As this patch adds a new state to the SMMU (GBPA), it is added
16
in a new subsection for forward migration compatibility.
17
GBPA is only migrated if its value is different from the reset value.
18
It does this to be backward migration compatible if SW didn't write
19
the register.
20
21
Signed-off-by: Mostafa Saleh <smostafa@google.com>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Reviewed-by: Eric Auger <eric.auger@redhat.com>
24
Message-id: 20230214094009.2445653-1-smostafa@google.com
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
---
13
---
28
hw/arm/smmuv3-internal.h | 7 +++++++
14
target/arm/tcg/translate-a64.c | 82 ++++++++++++++++++----------------
29
include/hw/arm/smmuv3.h | 1 +
15
1 file changed, 44 insertions(+), 38 deletions(-)
30
hw/arm/smmuv3.c | 43 +++++++++++++++++++++++++++++++++++++++-
31
3 files changed, 50 insertions(+), 1 deletion(-)
32
16
33
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
17
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
34
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/smmuv3-internal.h
19
--- a/target/arm/tcg/translate-a64.c
36
+++ b/hw/arm/smmuv3-internal.h
20
+++ b/target/arm/tcg/translate-a64.c
37
@@ -XXX,XX +XXX,XX @@ REG32(CR0ACK, 0x24)
21
@@ -XXX,XX +XXX,XX @@ static bool btype_destination_ok(uint32_t insn, bool bt, int btype)
38
REG32(CR1, 0x28)
22
return false;
39
REG32(CR2, 0x2c)
40
REG32(STATUSR, 0x40)
41
+REG32(GBPA, 0x44)
42
+ FIELD(GBPA, ABORT, 20, 1)
43
+ FIELD(GBPA, UPDATE, 31, 1)
44
+
45
+/* Use incoming. */
46
+#define SMMU_GBPA_RESET_VAL 0x1000
47
+
48
REG32(IRQ_CTRL, 0x50)
49
FIELD(IRQ_CTRL, GERROR_IRQEN, 0, 1)
50
FIELD(IRQ_CTRL, PRI_IRQEN, 1, 1)
51
diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
52
index XXXXXXX..XXXXXXX 100644
53
--- a/include/hw/arm/smmuv3.h
54
+++ b/include/hw/arm/smmuv3.h
55
@@ -XXX,XX +XXX,XX @@ struct SMMUv3State {
56
uint32_t cr[3];
57
uint32_t cr0ack;
58
uint32_t statusr;
59
+ uint32_t gbpa;
60
uint32_t irq_ctrl;
61
uint32_t gerror;
62
uint32_t gerrorn;
63
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/arm/smmuv3.c
66
+++ b/hw/arm/smmuv3.c
67
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
68
s->gerror = 0;
69
s->gerrorn = 0;
70
s->statusr = 0;
71
+ s->gbpa = SMMU_GBPA_RESET_VAL;
72
}
23
}
73
24
74
static int smmu_get_ste(SMMUv3State *s, dma_addr_t addr, STE *buf,
25
+/* C3.1 A64 instruction index by encoding */
75
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
26
+static void disas_a64_legacy(DisasContext *s, uint32_t insn)
76
qemu_mutex_lock(&s->mutex);
27
+{
77
28
+ switch (extract32(insn, 25, 4)) {
78
if (!smmu_enabled(s)) {
29
+ case 0x0:
79
- status = SMMU_TRANS_DISABLE;
30
+ if (!extract32(insn, 31, 1) || !disas_sme(s, insn)) {
80
+ if (FIELD_EX32(s->gbpa, GBPA, ABORT)) {
31
+ unallocated_encoding(s);
81
+ status = SMMU_TRANS_ABORT;
82
+ } else {
83
+ status = SMMU_TRANS_DISABLE;
84
+ }
32
+ }
85
goto epilogue;
33
+ break;
86
}
34
+ case 0x1: case 0x3: /* UNALLOCATED */
87
35
+ unallocated_encoding(s);
88
@@ -XXX,XX +XXX,XX @@ static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset,
36
+ break;
89
case A_GERROR_IRQ_CFG2:
37
+ case 0x2:
90
s->gerror_irq_cfg2 = data;
38
+ if (!disas_sve(s, insn)) {
91
return MEMTX_OK;
39
+ unallocated_encoding(s);
92
+ case A_GBPA:
93
+ /*
94
+ * If UPDATE is not set, the write is ignored. This is the only
95
+ * permitted behavior in SMMUv3.2 and later.
96
+ */
97
+ if (data & R_GBPA_UPDATE_MASK) {
98
+ /* Ignore update bit as write is synchronous. */
99
+ s->gbpa = data & ~R_GBPA_UPDATE_MASK;
100
+ }
40
+ }
101
+ return MEMTX_OK;
41
+ break;
102
case A_STRTAB_BASE: /* 64b */
42
+ case 0x8: case 0x9: /* Data processing - immediate */
103
s->strtab_base = deposit64(s->strtab_base, 0, 32, data);
43
+ disas_data_proc_imm(s, insn);
104
return MEMTX_OK;
44
+ break;
105
@@ -XXX,XX +XXX,XX @@ static MemTxResult smmu_readl(SMMUv3State *s, hwaddr offset,
45
+ case 0xa: case 0xb: /* Branch, exception generation and system insns */
106
case A_STATUSR:
46
+ disas_b_exc_sys(s, insn);
107
*data = s->statusr;
47
+ break;
108
return MEMTX_OK;
48
+ case 0x4:
109
+ case A_GBPA:
49
+ case 0x6:
110
+ *data = s->gbpa;
50
+ case 0xc:
111
+ return MEMTX_OK;
51
+ case 0xe: /* Loads and stores */
112
case A_IRQ_CTRL:
52
+ disas_ldst(s, insn);
113
case A_IRQ_CTRL_ACK:
53
+ break;
114
*data = s->irq_ctrl;
54
+ case 0x5:
115
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_smmuv3_queue = {
55
+ case 0xd: /* Data processing - register */
116
},
56
+ disas_data_proc_reg(s, insn);
117
};
57
+ break;
118
58
+ case 0x7:
119
+static bool smmuv3_gbpa_needed(void *opaque)
59
+ case 0xf: /* Data processing - SIMD and floating point */
120
+{
60
+ disas_data_proc_simd_fp(s, insn);
121
+ SMMUv3State *s = opaque;
61
+ break;
122
+
62
+ default:
123
+ /* Only migrate GBPA if it has different reset value. */
63
+ assert(FALSE); /* all 15 cases should be handled above */
124
+ return s->gbpa != SMMU_GBPA_RESET_VAL;
64
+ break;
65
+ }
125
+}
66
+}
126
+
67
+
127
+static const VMStateDescription vmstate_gbpa = {
68
static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
128
+ .name = "smmuv3/gbpa",
69
CPUState *cpu)
129
+ .version_id = 1,
70
{
130
+ .minimum_version_id = 1,
71
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
131
+ .needed = smmuv3_gbpa_needed,
72
disas_sme_fa64(s, insn);
132
+ .fields = (VMStateField[]) {
73
}
133
+ VMSTATE_UINT32(gbpa, SMMUv3State),
74
134
+ VMSTATE_END_OF_LIST()
75
- switch (extract32(insn, 25, 4)) {
135
+ }
76
- case 0x0:
136
+};
77
- if (!extract32(insn, 31, 1) || !disas_sme(s, insn)) {
137
+
78
- unallocated_encoding(s);
138
static const VMStateDescription vmstate_smmuv3 = {
79
- }
139
.name = "smmuv3",
80
- break;
140
.version_id = 1,
81
- case 0x1: case 0x3: /* UNALLOCATED */
141
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_smmuv3 = {
82
- unallocated_encoding(s);
142
83
- break;
143
VMSTATE_END_OF_LIST(),
84
- case 0x2:
144
},
85
- if (!disas_sve(s, insn)) {
145
+ .subsections = (const VMStateDescription * []) {
86
- unallocated_encoding(s);
146
+ &vmstate_gbpa,
87
- }
147
+ NULL
88
- break;
148
+ }
89
- case 0x8: case 0x9: /* Data processing - immediate */
149
};
90
- disas_data_proc_imm(s, insn);
150
91
- break;
151
static void smmuv3_instance_init(Object *obj)
92
- case 0xa: case 0xb: /* Branch, exception generation and system insns */
93
- disas_b_exc_sys(s, insn);
94
- break;
95
- case 0x4:
96
- case 0x6:
97
- case 0xc:
98
- case 0xe: /* Loads and stores */
99
- disas_ldst(s, insn);
100
- break;
101
- case 0x5:
102
- case 0xd: /* Data processing - register */
103
- disas_data_proc_reg(s, insn);
104
- break;
105
- case 0x7:
106
- case 0xf: /* Data processing - SIMD and floating point */
107
- disas_data_proc_simd_fp(s, insn);
108
- break;
109
- default:
110
- assert(FALSE); /* all 15 cases should be handled above */
111
- break;
112
- }
113
+ disas_a64_legacy(s, insn);
114
115
/*
116
* After execution of most insns, btype is reset to 0.
152
--
117
--
153
2.34.1
118
2.34.1
diff view generated by jsdifflib
1
From: Fabiano Rosas <farosas@suse.de>
1
The A64 translator uses a hand-written decoder for everything except
2
SVE or SME. It's fairly well structured, but it's becoming obvious
3
that it's still more painful to add instructions to than the A32
4
translator, because putting a new instruction into the right place in
5
a hand-written decoder is much harder than adding new instruction
6
patterns to a decodetree file.
2
7
3
Since commit cf7c6d1004 ("target/arm: Split out cpregs.h") we now have
8
As the first step in conversion to decodetree, create the skeleton of
4
a cpregs.h header which is more suitable for this code.
9
the decodetree decoder; where it does not handle instructions we will
10
fall back to the legacy decoder (which will be for everything at the
11
moment, since there are no patterns in a64.decode).
5
12
6
Code moved verbatim.
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20230512144106.3608981-3-peter.maydell@linaro.org
16
---
17
target/arm/tcg/a64.decode | 20 ++++++++++++++++++++
18
target/arm/tcg/translate-a64.c | 18 +++++++++++-------
19
target/arm/tcg/meson.build | 1 +
20
3 files changed, 32 insertions(+), 7 deletions(-)
21
create mode 100644 target/arm/tcg/a64.decode
7
22
8
Signed-off-by: Fabiano Rosas <farosas@suse.de>
23
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
new file mode 100644
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
25
index XXXXXXX..XXXXXXX
11
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
26
--- /dev/null
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
+++ b/target/arm/tcg/a64.decode
13
---
28
@@ -XXX,XX +XXX,XX @@
14
target/arm/cpregs.h | 98 +++++++++++++++++++++++++++++++++++++++++++++
29
+# AArch64 A64 allowed instruction decoding
15
target/arm/cpu.h | 91 -----------------------------------------
30
+#
16
2 files changed, 98 insertions(+), 91 deletions(-)
31
+# Copyright (c) 2023 Linaro, Ltd
17
32
+#
18
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
33
+# This library is free software; you can redistribute it and/or
34
+# modify it under the terms of the GNU Lesser General Public
35
+# License as published by the Free Software Foundation; either
36
+# version 2.1 of the License, or (at your option) any later version.
37
+#
38
+# This library is distributed in the hope that it will be useful,
39
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
40
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41
+# Lesser General Public License for more details.
42
+#
43
+# You should have received a copy of the GNU Lesser General Public
44
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
45
+
46
+#
47
+# This file is processed by scripts/decodetree.py
48
+#
49
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
19
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpregs.h
51
--- a/target/arm/tcg/translate-a64.c
21
+++ b/target/arm/cpregs.h
52
+++ b/target/arm/tcg/translate-a64.c
22
@@ -XXX,XX +XXX,XX @@ enum {
53
@@ -XXX,XX +XXX,XX @@ enum a64_shift_type {
23
ARM_CP_SME = 1 << 19,
54
A64_SHIFT_TYPE_ROR = 3
24
};
55
};
25
56
26
+/*
57
+/*
27
+ * Interface for defining coprocessor registers.
58
+ * Include the generated decoders.
28
+ * Registers are defined in tables of arm_cp_reginfo structs
29
+ * which are passed to define_arm_cp_regs().
30
+ */
59
+ */
31
+
60
+
32
+/*
61
+#include "decode-sme-fa64.c.inc"
33
+ * When looking up a coprocessor register we look for it
62
+#include "decode-a64.c.inc"
34
+ * via an integer which encodes all of:
35
+ * coprocessor number
36
+ * Crn, Crm, opc1, opc2 fields
37
+ * 32 or 64 bit register (ie is it accessed via MRC/MCR
38
+ * or via MRRC/MCRR?)
39
+ * non-secure/secure bank (AArch32 only)
40
+ * We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field.
41
+ * (In this case crn and opc2 should be zero.)
42
+ * For AArch64, there is no 32/64 bit size distinction;
43
+ * instead all registers have a 2 bit op0, 3 bit op1 and op2,
44
+ * and 4 bit CRn and CRm. The encoding patterns are chosen
45
+ * to be easy to convert to and from the KVM encodings, and also
46
+ * so that the hashtable can contain both AArch32 and AArch64
47
+ * registers (to allow for interprocessing where we might run
48
+ * 32 bit code on a 64 bit core).
49
+ */
50
+/*
51
+ * This bit is private to our hashtable cpreg; in KVM register
52
+ * IDs the AArch64/32 distinction is the KVM_REG_ARM/ARM64
53
+ * in the upper bits of the 64 bit ID.
54
+ */
55
+#define CP_REG_AA64_SHIFT 28
56
+#define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
57
+
63
+
58
+/*
64
/* Table based decoder typedefs - used when the relevant bits for decode
59
+ * To enable banking of coprocessor registers depending on ns-bit we
65
* are too awkwardly scattered across the instruction (eg SIMD).
60
+ * add a bit to distinguish between secure and non-secure cpregs in the
66
*/
61
+ * hashtable.
67
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
62
+ */
68
}
63
+#define CP_REG_NS_SHIFT 29
69
}
64
+#define CP_REG_NS_MASK (1 << CP_REG_NS_SHIFT)
70
65
+
71
-/*
66
+#define ENCODE_CP_REG(cp, is64, ns, crn, crm, opc1, opc2) \
72
- * Include the generated SME FA64 decoder.
67
+ ((ns) << CP_REG_NS_SHIFT | ((cp) << 16) | ((is64) << 15) | \
68
+ ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
69
+
70
+#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
71
+ (CP_REG_AA64_MASK | \
72
+ ((cp) << CP_REG_ARM_COPROC_SHIFT) | \
73
+ ((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | \
74
+ ((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \
75
+ ((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | \
76
+ ((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) | \
77
+ ((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT))
78
+
79
+/*
80
+ * Convert a full 64 bit KVM register ID to the truncated 32 bit
81
+ * version used as a key for the coprocessor register hashtable
82
+ */
83
+static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid)
84
+{
85
+ uint32_t cpregid = kvmid;
86
+ if ((kvmid & CP_REG_ARCH_MASK) == CP_REG_ARM64) {
87
+ cpregid |= CP_REG_AA64_MASK;
88
+ } else {
89
+ if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
90
+ cpregid |= (1 << 15);
91
+ }
92
+
93
+ /*
94
+ * KVM is always non-secure so add the NS flag on AArch32 register
95
+ * entries.
96
+ */
97
+ cpregid |= 1 << CP_REG_NS_SHIFT;
98
+ }
99
+ return cpregid;
100
+}
101
+
102
+/*
103
+ * Convert a truncated 32 bit hashtable key into the full
104
+ * 64 bit KVM register ID.
105
+ */
106
+static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
107
+{
108
+ uint64_t kvmid;
109
+
110
+ if (cpregid & CP_REG_AA64_MASK) {
111
+ kvmid = cpregid & ~CP_REG_AA64_MASK;
112
+ kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM64;
113
+ } else {
114
+ kvmid = cpregid & ~(1 << 15);
115
+ if (cpregid & (1 << 15)) {
116
+ kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM;
117
+ } else {
118
+ kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM;
119
+ }
120
+ }
121
+ return kvmid;
122
+}
123
+
124
/*
125
* Valid values for ARMCPRegInfo state field, indicating which of
126
* the AArch32 and AArch64 execution states this register is visible in.
127
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
128
index XXXXXXX..XXXXXXX 100644
129
--- a/target/arm/cpu.h
130
+++ b/target/arm/cpu.h
131
@@ -XXX,XX +XXX,XX @@ void arm_cpu_list(void);
132
uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
133
uint32_t cur_el, bool secure);
134
135
-/* Interface for defining coprocessor registers.
136
- * Registers are defined in tables of arm_cp_reginfo structs
137
- * which are passed to define_arm_cp_regs().
138
- */
73
- */
139
-
74
-
140
-/* When looking up a coprocessor register we look for it
75
-#include "decode-sme-fa64.c.inc"
141
- * via an integer which encodes all of:
142
- * coprocessor number
143
- * Crn, Crm, opc1, opc2 fields
144
- * 32 or 64 bit register (ie is it accessed via MRC/MCR
145
- * or via MRRC/MCRR?)
146
- * non-secure/secure bank (AArch32 only)
147
- * We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field.
148
- * (In this case crn and opc2 should be zero.)
149
- * For AArch64, there is no 32/64 bit size distinction;
150
- * instead all registers have a 2 bit op0, 3 bit op1 and op2,
151
- * and 4 bit CRn and CRm. The encoding patterns are chosen
152
- * to be easy to convert to and from the KVM encodings, and also
153
- * so that the hashtable can contain both AArch32 and AArch64
154
- * registers (to allow for interprocessing where we might run
155
- * 32 bit code on a 64 bit core).
156
- */
157
-/* This bit is private to our hashtable cpreg; in KVM register
158
- * IDs the AArch64/32 distinction is the KVM_REG_ARM/ARM64
159
- * in the upper bits of the 64 bit ID.
160
- */
161
-#define CP_REG_AA64_SHIFT 28
162
-#define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT)
163
-
76
-
164
-/* To enable banking of coprocessor registers depending on ns-bit we
77
static bool trans_OK(DisasContext *s, arg_OK *a)
165
- * add a bit to distinguish between secure and non-secure cpregs in the
166
- * hashtable.
167
- */
168
-#define CP_REG_NS_SHIFT 29
169
-#define CP_REG_NS_MASK (1 << CP_REG_NS_SHIFT)
170
-
171
-#define ENCODE_CP_REG(cp, is64, ns, crn, crm, opc1, opc2) \
172
- ((ns) << CP_REG_NS_SHIFT | ((cp) << 16) | ((is64) << 15) | \
173
- ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2))
174
-
175
-#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \
176
- (CP_REG_AA64_MASK | \
177
- ((cp) << CP_REG_ARM_COPROC_SHIFT) | \
178
- ((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | \
179
- ((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \
180
- ((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | \
181
- ((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) | \
182
- ((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT))
183
-
184
-/* Convert a full 64 bit KVM register ID to the truncated 32 bit
185
- * version used as a key for the coprocessor register hashtable
186
- */
187
-static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid)
188
-{
189
- uint32_t cpregid = kvmid;
190
- if ((kvmid & CP_REG_ARCH_MASK) == CP_REG_ARM64) {
191
- cpregid |= CP_REG_AA64_MASK;
192
- } else {
193
- if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) {
194
- cpregid |= (1 << 15);
195
- }
196
-
197
- /* KVM is always non-secure so add the NS flag on AArch32 register
198
- * entries.
199
- */
200
- cpregid |= 1 << CP_REG_NS_SHIFT;
201
- }
202
- return cpregid;
203
-}
204
-
205
-/* Convert a truncated 32 bit hashtable key into the full
206
- * 64 bit KVM register ID.
207
- */
208
-static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
209
-{
210
- uint64_t kvmid;
211
-
212
- if (cpregid & CP_REG_AA64_MASK) {
213
- kvmid = cpregid & ~CP_REG_AA64_MASK;
214
- kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM64;
215
- } else {
216
- kvmid = cpregid & ~(1 << 15);
217
- if (cpregid & (1 << 15)) {
218
- kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM;
219
- } else {
220
- kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM;
221
- }
222
- }
223
- return kvmid;
224
-}
225
-
226
/* Return the highest implemented Exception Level */
227
static inline int arm_highest_el(CPUARMState *env)
228
{
78
{
79
return true;
80
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
81
disas_sme_fa64(s, insn);
82
}
83
84
- disas_a64_legacy(s, insn);
85
+
86
+ if (!disas_a64(s, insn)) {
87
+ disas_a64_legacy(s, insn);
88
+ }
89
90
/*
91
* After execution of most insns, btype is reset to 0.
92
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
93
index XXXXXXX..XXXXXXX 100644
94
--- a/target/arm/tcg/meson.build
95
+++ b/target/arm/tcg/meson.build
96
@@ -XXX,XX +XXX,XX @@ gen = [
97
decodetree.process('a32-uncond.decode', extra_args: '--static-decode=disas_a32_uncond'),
98
decodetree.process('t32.decode', extra_args: '--static-decode=disas_t32'),
99
decodetree.process('t16.decode', extra_args: ['-w', '16', '--static-decode=disas_t16']),
100
+ decodetree.process('a64.decode', extra_args: ['--static-decode=disas_a64']),
101
]
102
103
arm_ss.add(gen)
229
--
104
--
230
2.34.1
105
2.34.1
231
232
diff view generated by jsdifflib
1
From: Fabiano Rosas <farosas@suse.de>
1
The SVE and SME decode is already done by decodetree. Pull the calls
2
to these decoders out of the legacy decoder. This doesn't change
3
behaviour because all the patterns in sve.decode and sme.decode
4
already require the bits that the legacy decoder is decoding to have
5
the correct values.
2
6
3
If a test was tagged with the "accel" tag and the specified
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
accelerator it not present in the qemu binary, cancel the test.
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230512144106.3608981-4-peter.maydell@linaro.org
10
---
11
target/arm/tcg/translate-a64.c | 20 ++++----------------
12
1 file changed, 4 insertions(+), 16 deletions(-)
5
13
6
We can now write tests without explicit calls to require_accelerator,
14
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
7
just the tag is enough.
8
9
Signed-off-by: Fabiano Rosas <farosas@suse.de>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
tests/avocado/avocado_qemu/__init__.py | 4 ++++
15
1 file changed, 4 insertions(+)
16
17
diff --git a/tests/avocado/avocado_qemu/__init__.py b/tests/avocado/avocado_qemu/__init__.py
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/avocado/avocado_qemu/__init__.py
16
--- a/target/arm/tcg/translate-a64.c
20
+++ b/tests/avocado/avocado_qemu/__init__.py
17
+++ b/target/arm/tcg/translate-a64.c
21
@@ -XXX,XX +XXX,XX @@ def setUp(self):
18
@@ -XXX,XX +XXX,XX @@ static bool btype_destination_ok(uint32_t insn, bool bt, int btype)
22
19
static void disas_a64_legacy(DisasContext *s, uint32_t insn)
23
super().setUp('qemu-system-')
20
{
24
21
switch (extract32(insn, 25, 4)) {
25
+ accel_required = self._get_unique_tag_val('accel')
22
- case 0x0:
26
+ if accel_required:
23
- if (!extract32(insn, 31, 1) || !disas_sme(s, insn)) {
27
+ self.require_accelerator(accel_required)
24
- unallocated_encoding(s);
28
+
25
- }
29
self.machine = self.params.get('machine',
26
- break;
30
default=self._get_unique_tag_val('machine'))
27
- case 0x1: case 0x3: /* UNALLOCATED */
28
- unallocated_encoding(s);
29
- break;
30
- case 0x2:
31
- if (!disas_sve(s, insn)) {
32
- unallocated_encoding(s);
33
- }
34
- break;
35
case 0x8: case 0x9: /* Data processing - immediate */
36
disas_data_proc_imm(s, insn);
37
break;
38
@@ -XXX,XX +XXX,XX @@ static void disas_a64_legacy(DisasContext *s, uint32_t insn)
39
disas_data_proc_simd_fp(s, insn);
40
break;
41
default:
42
- assert(FALSE); /* all 15 cases should be handled above */
43
+ unallocated_encoding(s);
44
break;
45
}
46
}
47
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
48
disas_sme_fa64(s, insn);
49
}
50
51
-
52
- if (!disas_a64(s, insn)) {
53
+ if (!disas_a64(s, insn) &&
54
+ !disas_sme(s, insn) &&
55
+ !disas_sve(s, insn)) {
56
disas_a64_legacy(s, insn);
57
}
31
58
32
--
59
--
33
2.34.1
60
2.34.1
34
35
diff view generated by jsdifflib
1
From: Claudio Fontana <cfontana@suse.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Claudio Fontana <cfontana@suse.de>
3
Convert the ADR and ADRP instructions.
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
5
Signed-off-by: Fabiano Rosas <farosas@suse.de>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230512144106.3608981-5-peter.maydell@linaro.org
9
[PMM: Rebased]
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
12
---
9
target/arm/helper.c | 12 +++++++-----
13
target/arm/tcg/a64.decode | 13 ++++++++++++
10
1 file changed, 7 insertions(+), 5 deletions(-)
14
target/arm/tcg/translate-a64.c | 38 +++++++++++++---------------------
15
2 files changed, 27 insertions(+), 24 deletions(-)
11
16
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
19
--- a/target/arm/tcg/a64.decode
15
+++ b/target/arm/helper.c
20
+++ b/target/arm/tcg/a64.decode
16
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
21
@@ -XXX,XX +XXX,XX @@
17
unsigned int cur_el = arm_current_el(env);
22
#
18
int rt;
23
# This file is processed by scripts/decodetree.py
19
24
#
20
- /*
25
+
21
- * Note that new_el can never be 0. If cur_el is 0, then
26
+&ri rd imm
22
- * el0_a64 is is_a64(), else el0_a64 is ignored.
27
+
23
- */
28
+
24
- aarch64_sve_change_el(env, cur_el, new_el, is_a64(env));
29
+### Data Processing - Immediate
25
+ if (tcg_enabled()) {
30
+
26
+ /*
31
+# PC-rel addressing
27
+ * Note that new_el can never be 0. If cur_el is 0, then
32
+
28
+ * el0_a64 is is_a64(), else el0_a64 is ignored.
33
+%imm_pcrel 5:s19 29:2
29
+ */
34
+@pcrel . .. ..... ................... rd:5 &ri imm=%imm_pcrel
30
+ aarch64_sve_change_el(env, cur_el, new_el, is_a64(env));
35
+
31
+ }
36
+ADR 0 .. 10000 ................... ..... @pcrel
32
37
+ADRP 1 .. 10000 ................... ..... @pcrel
33
if (cur_el < new_el) {
38
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
34
/*
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/tcg/translate-a64.c
41
+++ b/target/arm/tcg/translate-a64.c
42
@@ -XXX,XX +XXX,XX @@ static void disas_ldst(DisasContext *s, uint32_t insn)
43
}
44
}
45
46
-/* PC-rel. addressing
47
- * 31 30 29 28 24 23 5 4 0
48
- * +----+-------+-----------+-------------------+------+
49
- * | op | immlo | 1 0 0 0 0 | immhi | Rd |
50
- * +----+-------+-----------+-------------------+------+
51
+/*
52
+ * PC-rel. addressing
53
*/
54
-static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
55
+
56
+static bool trans_ADR(DisasContext *s, arg_ri *a)
57
{
58
- unsigned int page, rd;
59
- int64_t offset;
60
+ gen_pc_plus_diff(s, cpu_reg(s, a->rd), a->imm);
61
+ return true;
62
+}
63
64
- page = extract32(insn, 31, 1);
65
- /* SignExtend(immhi:immlo) -> offset */
66
- offset = sextract64(insn, 5, 19);
67
- offset = offset << 2 | extract32(insn, 29, 2);
68
- rd = extract32(insn, 0, 5);
69
+static bool trans_ADRP(DisasContext *s, arg_ri *a)
70
+{
71
+ int64_t offset = (int64_t)a->imm << 12;
72
73
- if (page) {
74
- /* ADRP (page based) */
75
- offset <<= 12;
76
- /* The page offset is ok for CF_PCREL. */
77
- offset -= s->pc_curr & 0xfff;
78
- }
79
-
80
- gen_pc_plus_diff(s, cpu_reg(s, rd), offset);
81
+ /* The page offset is ok for CF_PCREL. */
82
+ offset -= s->pc_curr & 0xfff;
83
+ gen_pc_plus_diff(s, cpu_reg(s, a->rd), offset);
84
+ return true;
85
}
86
87
/*
88
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
89
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
90
{
91
switch (extract32(insn, 23, 6)) {
92
- case 0x20: case 0x21: /* PC-rel. addressing */
93
- disas_pc_rel_adr(s, insn);
94
- break;
95
case 0x22: /* Add/subtract (immediate) */
96
disas_add_sub_imm(s, insn);
97
break;
35
--
98
--
36
2.34.1
99
2.34.1
37
38
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
3
Split out specific 32-bit and 64-bit functions.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
These carry the same signature as tcg_gen_add_i64,
5
Message-id: 20230206223502.25122-5-philmd@linaro.org
5
and so will be easier to pass as callbacks.
6
7
Retain gen_add_CC and gen_sub_CC during conversion.
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20230512144106.3608981-6-peter.maydell@linaro.org
13
[PMM: rebased]
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
16
---
8
target/arm/helper.c | 12 ++++++++++--
17
target/arm/tcg/translate-a64.c | 149 +++++++++++++++++++--------------
9
1 file changed, 10 insertions(+), 2 deletions(-)
18
1 file changed, 84 insertions(+), 65 deletions(-)
10
19
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
12
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
22
--- a/target/arm/tcg/translate-a64.c
14
+++ b/target/arm/helper.c
23
+++ b/target/arm/tcg/translate-a64.c
15
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
24
@@ -XXX,XX +XXX,XX @@ static inline void gen_logic_CC(int sf, TCGv_i64 result)
25
}
26
27
/* dest = T0 + T1; compute C, N, V and Z flags */
28
+static void gen_add64_CC(TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
29
+{
30
+ TCGv_i64 result, flag, tmp;
31
+ result = tcg_temp_new_i64();
32
+ flag = tcg_temp_new_i64();
33
+ tmp = tcg_temp_new_i64();
34
+
35
+ tcg_gen_movi_i64(tmp, 0);
36
+ tcg_gen_add2_i64(result, flag, t0, tmp, t1, tmp);
37
+
38
+ tcg_gen_extrl_i64_i32(cpu_CF, flag);
39
+
40
+ gen_set_NZ64(result);
41
+
42
+ tcg_gen_xor_i64(flag, result, t0);
43
+ tcg_gen_xor_i64(tmp, t0, t1);
44
+ tcg_gen_andc_i64(flag, flag, tmp);
45
+ tcg_gen_extrh_i64_i32(cpu_VF, flag);
46
+
47
+ tcg_gen_mov_i64(dest, result);
48
+}
49
+
50
+static void gen_add32_CC(TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
51
+{
52
+ TCGv_i32 t0_32 = tcg_temp_new_i32();
53
+ TCGv_i32 t1_32 = tcg_temp_new_i32();
54
+ TCGv_i32 tmp = tcg_temp_new_i32();
55
+
56
+ tcg_gen_movi_i32(tmp, 0);
57
+ tcg_gen_extrl_i64_i32(t0_32, t0);
58
+ tcg_gen_extrl_i64_i32(t1_32, t1);
59
+ tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, t1_32, tmp);
60
+ tcg_gen_mov_i32(cpu_ZF, cpu_NF);
61
+ tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
62
+ tcg_gen_xor_i32(tmp, t0_32, t1_32);
63
+ tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
64
+ tcg_gen_extu_i32_i64(dest, cpu_NF);
65
+}
66
+
67
static void gen_add_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
68
{
69
if (sf) {
70
- TCGv_i64 result, flag, tmp;
71
- result = tcg_temp_new_i64();
72
- flag = tcg_temp_new_i64();
73
- tmp = tcg_temp_new_i64();
74
-
75
- tcg_gen_movi_i64(tmp, 0);
76
- tcg_gen_add2_i64(result, flag, t0, tmp, t1, tmp);
77
-
78
- tcg_gen_extrl_i64_i32(cpu_CF, flag);
79
-
80
- gen_set_NZ64(result);
81
-
82
- tcg_gen_xor_i64(flag, result, t0);
83
- tcg_gen_xor_i64(tmp, t0, t1);
84
- tcg_gen_andc_i64(flag, flag, tmp);
85
- tcg_gen_extrh_i64_i32(cpu_VF, flag);
86
-
87
- tcg_gen_mov_i64(dest, result);
88
+ gen_add64_CC(dest, t0, t1);
89
} else {
90
- /* 32 bit arithmetic */
91
- TCGv_i32 t0_32 = tcg_temp_new_i32();
92
- TCGv_i32 t1_32 = tcg_temp_new_i32();
93
- TCGv_i32 tmp = tcg_temp_new_i32();
94
-
95
- tcg_gen_movi_i32(tmp, 0);
96
- tcg_gen_extrl_i64_i32(t0_32, t0);
97
- tcg_gen_extrl_i64_i32(t1_32, t1);
98
- tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, t1_32, tmp);
99
- tcg_gen_mov_i32(cpu_ZF, cpu_NF);
100
- tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
101
- tcg_gen_xor_i32(tmp, t0_32, t1_32);
102
- tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
103
- tcg_gen_extu_i32_i64(dest, cpu_NF);
104
+ gen_add32_CC(dest, t0, t1);
16
}
105
}
17
}
106
}
18
107
19
+#ifndef CONFIG_USER_ONLY
108
/* dest = T0 - T1; compute C, N, V and Z flags */
20
/*
109
+static void gen_sub64_CC(TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
21
* We don't know until after realize whether there's a GICv3
110
+{
22
* attached, and that is what registers the gicv3 sysregs.
111
+ /* 64 bit arithmetic */
23
@@ -XXX,XX +XXX,XX @@ static uint64_t id_pfr1_read(CPUARMState *env, const ARMCPRegInfo *ri)
112
+ TCGv_i64 result, flag, tmp;
24
return pfr1;
113
+
114
+ result = tcg_temp_new_i64();
115
+ flag = tcg_temp_new_i64();
116
+ tcg_gen_sub_i64(result, t0, t1);
117
+
118
+ gen_set_NZ64(result);
119
+
120
+ tcg_gen_setcond_i64(TCG_COND_GEU, flag, t0, t1);
121
+ tcg_gen_extrl_i64_i32(cpu_CF, flag);
122
+
123
+ tcg_gen_xor_i64(flag, result, t0);
124
+ tmp = tcg_temp_new_i64();
125
+ tcg_gen_xor_i64(tmp, t0, t1);
126
+ tcg_gen_and_i64(flag, flag, tmp);
127
+ tcg_gen_extrh_i64_i32(cpu_VF, flag);
128
+ tcg_gen_mov_i64(dest, result);
129
+}
130
+
131
+static void gen_sub32_CC(TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
132
+{
133
+ /* 32 bit arithmetic */
134
+ TCGv_i32 t0_32 = tcg_temp_new_i32();
135
+ TCGv_i32 t1_32 = tcg_temp_new_i32();
136
+ TCGv_i32 tmp;
137
+
138
+ tcg_gen_extrl_i64_i32(t0_32, t0);
139
+ tcg_gen_extrl_i64_i32(t1_32, t1);
140
+ tcg_gen_sub_i32(cpu_NF, t0_32, t1_32);
141
+ tcg_gen_mov_i32(cpu_ZF, cpu_NF);
142
+ tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0_32, t1_32);
143
+ tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
144
+ tmp = tcg_temp_new_i32();
145
+ tcg_gen_xor_i32(tmp, t0_32, t1_32);
146
+ tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
147
+ tcg_gen_extu_i32_i64(dest, cpu_NF);
148
+}
149
+
150
static void gen_sub_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
151
{
152
if (sf) {
153
- /* 64 bit arithmetic */
154
- TCGv_i64 result, flag, tmp;
155
-
156
- result = tcg_temp_new_i64();
157
- flag = tcg_temp_new_i64();
158
- tcg_gen_sub_i64(result, t0, t1);
159
-
160
- gen_set_NZ64(result);
161
-
162
- tcg_gen_setcond_i64(TCG_COND_GEU, flag, t0, t1);
163
- tcg_gen_extrl_i64_i32(cpu_CF, flag);
164
-
165
- tcg_gen_xor_i64(flag, result, t0);
166
- tmp = tcg_temp_new_i64();
167
- tcg_gen_xor_i64(tmp, t0, t1);
168
- tcg_gen_and_i64(flag, flag, tmp);
169
- tcg_gen_extrh_i64_i32(cpu_VF, flag);
170
- tcg_gen_mov_i64(dest, result);
171
+ gen_sub64_CC(dest, t0, t1);
172
} else {
173
- /* 32 bit arithmetic */
174
- TCGv_i32 t0_32 = tcg_temp_new_i32();
175
- TCGv_i32 t1_32 = tcg_temp_new_i32();
176
- TCGv_i32 tmp;
177
-
178
- tcg_gen_extrl_i64_i32(t0_32, t0);
179
- tcg_gen_extrl_i64_i32(t1_32, t1);
180
- tcg_gen_sub_i32(cpu_NF, t0_32, t1_32);
181
- tcg_gen_mov_i32(cpu_ZF, cpu_NF);
182
- tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0_32, t1_32);
183
- tcg_gen_xor_i32(cpu_VF, cpu_NF, t0_32);
184
- tmp = tcg_temp_new_i32();
185
- tcg_gen_xor_i32(tmp, t0_32, t1_32);
186
- tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
187
- tcg_gen_extu_i32_i64(dest, cpu_NF);
188
+ gen_sub32_CC(dest, t0, t1);
189
}
25
}
190
}
26
191
27
-#ifndef CONFIG_USER_ONLY
28
static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
29
{
30
ARMCPU *cpu = env_archcpu(env);
31
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
32
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 1,
33
.access = PL1_R, .type = ARM_CP_NO_RAW,
34
.accessfn = access_aa32_tid3,
35
+#ifdef CONFIG_USER_ONLY
36
+ .type = ARM_CP_CONST,
37
+ .resetvalue = cpu->isar.id_pfr1,
38
+#else
39
+ .type = ARM_CP_NO_RAW,
40
+ .accessfn = access_aa32_tid3,
41
.readfn = id_pfr1_read,
42
- .writefn = arm_cp_write_ignore },
43
+ .writefn = arm_cp_write_ignore
44
+#endif
45
+ },
46
{ .name = "ID_DFR0", .state = ARM_CP_STATE_BOTH,
47
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 1, .opc2 = 2,
48
.access = PL1_R, .type = ARM_CP_CONST,
49
--
192
--
50
2.34.1
193
2.34.1
51
52
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
arm_v7m_mmu_idx_all() and arm_v7m_mmu_idx_for_secstate_and_priv()
3
Convert the ADD and SUB (immediate) instructions.
4
are only used for system emulation in m_helper.c.
5
Move the definitions to avoid prototype forward declarations.
6
4
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20230206223502.25122-4-philmd@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230512144106.3608981-7-peter.maydell@linaro.org
9
[PMM: Rebased; adjusted to use translate.h's TRANS macro]
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
target/arm/internals.h | 14 --------
13
target/arm/tcg/translate.h | 5 +++
13
target/arm/m_helper.c | 74 +++++++++++++++++++++---------------------
14
target/arm/tcg/a64.decode | 17 ++++++++
14
2 files changed, 37 insertions(+), 51 deletions(-)
15
target/arm/tcg/translate-a64.c | 73 ++++++++++------------------------
16
3 files changed, 42 insertions(+), 53 deletions(-)
15
17
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
18
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/internals.h
20
--- a/target/arm/tcg/translate.h
19
+++ b/target/arm/internals.h
21
+++ b/target/arm/tcg/translate.h
20
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx core_to_aa64_mmu_idx(int mmu_idx)
22
@@ -XXX,XX +XXX,XX @@ static inline int rsub_8(DisasContext *s, int x)
21
23
return 8 - x;
22
int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx);
24
}
23
25
24
-/*
26
+static inline int shl_12(DisasContext *s, int x)
25
- * Return the MMU index for a v7M CPU with all relevant information
26
- * manually specified.
27
- */
28
-ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
29
- bool secstate, bool priv, bool negpri);
30
-
31
-/*
32
- * Return the MMU index for a v7M CPU in the specified security and
33
- * privilege state.
34
- */
35
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
36
- bool secstate, bool priv);
37
-
38
/* Return the MMU index for a v7M CPU in the specified security state */
39
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate);
40
41
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/m_helper.c
44
+++ b/target/arm/m_helper.c
45
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
46
47
#else /* !CONFIG_USER_ONLY */
48
49
+static ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
50
+ bool secstate, bool priv, bool negpri)
51
+{
27
+{
52
+ ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
28
+ return x << 12;
53
+
54
+ if (priv) {
55
+ mmu_idx |= ARM_MMU_IDX_M_PRIV;
56
+ }
57
+
58
+ if (negpri) {
59
+ mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
60
+ }
61
+
62
+ if (secstate) {
63
+ mmu_idx |= ARM_MMU_IDX_M_S;
64
+ }
65
+
66
+ return mmu_idx;
67
+}
29
+}
68
+
30
+
69
+static ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
31
static inline int neon_3same_fp_size(DisasContext *s, int x)
70
+ bool secstate, bool priv)
32
{
33
/* Convert 0==fp32, 1==fp16 into a MO_* value */
34
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/tcg/a64.decode
37
+++ b/target/arm/tcg/a64.decode
38
@@ -XXX,XX +XXX,XX @@
39
#
40
41
&ri rd imm
42
+&rri_sf rd rn imm sf
43
44
45
### Data Processing - Immediate
46
@@ -XXX,XX +XXX,XX @@
47
48
ADR 0 .. 10000 ................... ..... @pcrel
49
ADRP 1 .. 10000 ................... ..... @pcrel
50
+
51
+# Add/subtract (immediate)
52
+
53
+%imm12_sh12 10:12 !function=shl_12
54
+@addsub_imm sf:1 .. ...... . imm:12 rn:5 rd:5
55
+@addsub_imm12 sf:1 .. ...... . ............ rn:5 rd:5 imm=%imm12_sh12
56
+
57
+ADD_i . 00 100010 0 ............ ..... ..... @addsub_imm
58
+ADD_i . 00 100010 1 ............ ..... ..... @addsub_imm12
59
+ADDS_i . 01 100010 0 ............ ..... ..... @addsub_imm
60
+ADDS_i . 01 100010 1 ............ ..... ..... @addsub_imm12
61
+
62
+SUB_i . 10 100010 0 ............ ..... ..... @addsub_imm
63
+SUB_i . 10 100010 1 ............ ..... ..... @addsub_imm12
64
+SUBS_i . 11 100010 0 ............ ..... ..... @addsub_imm
65
+SUBS_i . 11 100010 1 ............ ..... ..... @addsub_imm12
66
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/tcg/translate-a64.c
69
+++ b/target/arm/tcg/translate-a64.c
70
@@ -XXX,XX +XXX,XX @@ static void disas_ldst(DisasContext *s, uint32_t insn)
71
}
72
}
73
74
+typedef void ArithTwoOp(TCGv_i64, TCGv_i64, TCGv_i64);
75
+
76
+static bool gen_rri(DisasContext *s, arg_rri_sf *a,
77
+ bool rd_sp, bool rn_sp, ArithTwoOp *fn)
71
+{
78
+{
72
+ bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
79
+ TCGv_i64 tcg_rn = rn_sp ? cpu_reg_sp(s, a->rn) : cpu_reg(s, a->rn);
80
+ TCGv_i64 tcg_rd = rd_sp ? cpu_reg_sp(s, a->rd) : cpu_reg(s, a->rd);
81
+ TCGv_i64 tcg_imm = tcg_constant_i64(a->imm);
73
+
82
+
74
+ return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
83
+ fn(tcg_rd, tcg_rn, tcg_imm);
75
+}
84
+ if (!a->sf) {
76
+
85
+ tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
77
+/* Return the MMU index for a v7M CPU in the specified security state */
86
+ }
78
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
87
+ return true;
79
+{
80
+ bool priv = arm_v7m_is_handler_mode(env) ||
81
+ !(env->v7m.control[secstate] & 1);
82
+
83
+ return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
84
+}
88
+}
85
+
89
+
86
/*
90
/*
87
* What kind of stack write are we doing? This affects how exceptions
91
* PC-rel. addressing
88
* generated during the stacking are treated.
92
*/
89
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
93
@@ -XXX,XX +XXX,XX @@ static bool trans_ADRP(DisasContext *s, arg_ri *a)
90
return tt_resp;
94
91
}
95
/*
92
96
* Add/subtract (immediate)
93
-ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
97
- *
94
- bool secstate, bool priv, bool negpri)
98
- * 31 30 29 28 23 22 21 10 9 5 4 0
99
- * +--+--+--+-------------+--+-------------+-----+-----+
100
- * |sf|op| S| 1 0 0 0 1 0 |sh| imm12 | Rn | Rd |
101
- * +--+--+--+-------------+--+-------------+-----+-----+
102
- *
103
- * sf: 0 -> 32bit, 1 -> 64bit
104
- * op: 0 -> add , 1 -> sub
105
- * S: 1 -> set flags
106
- * sh: 1 -> LSL imm by 12
107
*/
108
-static void disas_add_sub_imm(DisasContext *s, uint32_t insn)
95
-{
109
-{
96
- ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
110
- int rd = extract32(insn, 0, 5);
111
- int rn = extract32(insn, 5, 5);
112
- uint64_t imm = extract32(insn, 10, 12);
113
- bool shift = extract32(insn, 22, 1);
114
- bool setflags = extract32(insn, 29, 1);
115
- bool sub_op = extract32(insn, 30, 1);
116
- bool is_64bit = extract32(insn, 31, 1);
97
-
117
-
98
- if (priv) {
118
- TCGv_i64 tcg_rn = cpu_reg_sp(s, rn);
99
- mmu_idx |= ARM_MMU_IDX_M_PRIV;
119
- TCGv_i64 tcg_rd = setflags ? cpu_reg(s, rd) : cpu_reg_sp(s, rd);
120
- TCGv_i64 tcg_result;
121
-
122
- if (shift) {
123
- imm <<= 12;
100
- }
124
- }
101
-
125
-
102
- if (negpri) {
126
- tcg_result = tcg_temp_new_i64();
103
- mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
127
- if (!setflags) {
128
- if (sub_op) {
129
- tcg_gen_subi_i64(tcg_result, tcg_rn, imm);
130
- } else {
131
- tcg_gen_addi_i64(tcg_result, tcg_rn, imm);
132
- }
133
- } else {
134
- TCGv_i64 tcg_imm = tcg_constant_i64(imm);
135
- if (sub_op) {
136
- gen_sub_CC(is_64bit, tcg_result, tcg_rn, tcg_imm);
137
- } else {
138
- gen_add_CC(is_64bit, tcg_result, tcg_rn, tcg_imm);
139
- }
104
- }
140
- }
105
-
141
-
106
- if (secstate) {
142
- if (is_64bit) {
107
- mmu_idx |= ARM_MMU_IDX_M_S;
143
- tcg_gen_mov_i64(tcg_rd, tcg_result);
144
- } else {
145
- tcg_gen_ext32u_i64(tcg_rd, tcg_result);
108
- }
146
- }
109
-
110
- return mmu_idx;
111
-}
147
-}
112
-
148
+TRANS(ADD_i, gen_rri, a, 1, 1, tcg_gen_add_i64)
113
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
149
+TRANS(SUB_i, gen_rri, a, 1, 1, tcg_gen_sub_i64)
114
- bool secstate, bool priv)
150
+TRANS(ADDS_i, gen_rri, a, 0, 1, a->sf ? gen_add64_CC : gen_add32_CC)
115
-{
151
+TRANS(SUBS_i, gen_rri, a, 0, 1, a->sf ? gen_sub64_CC : gen_sub32_CC)
116
- bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
152
117
-
153
/*
118
- return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
154
* Add/subtract (immediate, with tags)
119
-}
155
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
120
-
156
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
121
-/* Return the MMU index for a v7M CPU in the specified security state */
157
{
122
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
158
switch (extract32(insn, 23, 6)) {
123
-{
159
- case 0x22: /* Add/subtract (immediate) */
124
- bool priv = arm_v7m_is_handler_mode(env) ||
160
- disas_add_sub_imm(s, insn);
125
- !(env->v7m.control[secstate] & 1);
161
- break;
126
-
162
case 0x23: /* Add/subtract (immediate, with tags) */
127
- return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
163
disas_add_sub_imm_with_tags(s, insn);
128
-}
164
break;
129
-
130
#endif /* !CONFIG_USER_ONLY */
131
--
165
--
132
2.34.1
166
2.34.1
133
134
diff view generated by jsdifflib
1
From: Claudio Fontana <cfontana@suse.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
for "all" builds (tcg + kvm), we want to avoid doing
3
Convert the ADDG and SUBG (immediate) instructions.
4
the psci check if tcg is built-in, but not enabled.
5
4
6
Signed-off-by: Claudio Fontana <cfontana@suse.de>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Fabiano Rosas <farosas@suse.de>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20230512144106.3608981-8-peter.maydell@linaro.org
9
[PMM: Rebased; use TRANS_FEAT()]
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
target/arm/helper.c | 3 ++-
13
target/arm/tcg/a64.decode | 8 +++++++
13
1 file changed, 2 insertions(+), 1 deletion(-)
14
target/arm/tcg/translate-a64.c | 38 ++++++++++------------------------
15
2 files changed, 19 insertions(+), 27 deletions(-)
14
16
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
19
--- a/target/arm/tcg/a64.decode
18
+++ b/target/arm/helper.c
20
+++ b/target/arm/tcg/a64.decode
19
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ SUB_i . 10 100010 0 ............ ..... ..... @addsub_imm
20
#include "hw/irq.h"
22
SUB_i . 10 100010 1 ............ ..... ..... @addsub_imm12
21
#include "sysemu/cpu-timers.h"
23
SUBS_i . 11 100010 0 ............ ..... ..... @addsub_imm
22
#include "sysemu/kvm.h"
24
SUBS_i . 11 100010 1 ............ ..... ..... @addsub_imm12
23
+#include "sysemu/tcg.h"
25
+
24
#include "qapi/qapi-commands-machine-target.h"
26
+# Add/subtract (immediate with tags)
25
#include "qapi/error.h"
27
+
26
#include "qemu/guest-random.h"
28
+&rri_tag rd rn uimm6 uimm4
27
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_interrupt(CPUState *cs)
29
+@addsub_imm_tag . .. ...... . uimm6:6 .. uimm4:4 rn:5 rd:5 &rri_tag
28
env->exception.syndrome);
30
+
31
+ADDG_i 1 00 100011 0 ...... 00 .... ..... ..... @addsub_imm_tag
32
+SUBG_i 1 10 100011 0 ...... 00 .... ..... ..... @addsub_imm_tag
33
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/tcg/translate-a64.c
36
+++ b/target/arm/tcg/translate-a64.c
37
@@ -XXX,XX +XXX,XX @@ TRANS(SUBS_i, gen_rri, a, 0, 1, a->sf ? gen_sub64_CC : gen_sub32_CC)
38
39
/*
40
* Add/subtract (immediate, with tags)
41
- *
42
- * 31 30 29 28 23 22 21 16 14 10 9 5 4 0
43
- * +--+--+--+-------------+--+---------+--+-------+-----+-----+
44
- * |sf|op| S| 1 0 0 0 1 1 |o2| uimm6 |o3| uimm4 | Rn | Rd |
45
- * +--+--+--+-------------+--+---------+--+-------+-----+-----+
46
- *
47
- * op: 0 -> add, 1 -> sub
48
*/
49
-static void disas_add_sub_imm_with_tags(DisasContext *s, uint32_t insn)
50
+
51
+static bool gen_add_sub_imm_with_tags(DisasContext *s, arg_rri_tag *a,
52
+ bool sub_op)
53
{
54
- int rd = extract32(insn, 0, 5);
55
- int rn = extract32(insn, 5, 5);
56
- int uimm4 = extract32(insn, 10, 4);
57
- int uimm6 = extract32(insn, 16, 6);
58
- bool sub_op = extract32(insn, 30, 1);
59
TCGv_i64 tcg_rn, tcg_rd;
60
int imm;
61
62
- /* Test all of sf=1, S=0, o2=0, o3=0. */
63
- if ((insn & 0xa040c000u) != 0x80000000u ||
64
- !dc_isar_feature(aa64_mte_insn_reg, s)) {
65
- unallocated_encoding(s);
66
- return;
67
- }
68
-
69
- imm = uimm6 << LOG2_TAG_GRANULE;
70
+ imm = a->uimm6 << LOG2_TAG_GRANULE;
71
if (sub_op) {
72
imm = -imm;
29
}
73
}
30
74
31
- if (arm_is_psci_call(cpu, cs->exception_index)) {
75
- tcg_rn = cpu_reg_sp(s, rn);
32
+ if (tcg_enabled() && arm_is_psci_call(cpu, cs->exception_index)) {
76
- tcg_rd = cpu_reg_sp(s, rd);
33
arm_handle_psci_call(cpu);
77
+ tcg_rn = cpu_reg_sp(s, a->rn);
34
qemu_log_mask(CPU_LOG_INT, "...handled as PSCI call\n");
78
+ tcg_rd = cpu_reg_sp(s, a->rd);
35
return;
79
80
if (s->ata) {
81
gen_helper_addsubg(tcg_rd, cpu_env, tcg_rn,
82
tcg_constant_i32(imm),
83
- tcg_constant_i32(uimm4));
84
+ tcg_constant_i32(a->uimm4));
85
} else {
86
tcg_gen_addi_i64(tcg_rd, tcg_rn, imm);
87
gen_address_with_allocation_tag0(tcg_rd, tcg_rd);
88
}
89
+ return true;
90
}
91
92
+TRANS_FEAT(ADDG_i, aa64_mte_insn_reg, gen_add_sub_imm_with_tags, a, false)
93
+TRANS_FEAT(SUBG_i, aa64_mte_insn_reg, gen_add_sub_imm_with_tags, a, true)
94
+
95
/* The input should be a value in the bottom e bits (with higher
96
* bits zero); returns that value replicated into every element
97
* of size e in a 64 bit integer.
98
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
99
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
100
{
101
switch (extract32(insn, 23, 6)) {
102
- case 0x23: /* Add/subtract (immediate, with tags) */
103
- disas_add_sub_imm_with_tags(s, insn);
104
- break;
105
case 0x24: /* Logical (immediate) */
106
disas_logic_imm(s, insn);
107
break;
36
--
108
--
37
2.34.1
109
2.34.1
38
39
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
3
Use the bitops.h macro rather than rolling our own here.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
5
Message-id: 20230206223502.25122-9-philmd@linaro.org
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230512144106.3608981-9-peter.maydell@linaro.org
7
---
9
---
8
target/arm/cpu.h | 2 +-
10
target/arm/tcg/translate-a64.c | 11 ++---------
9
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 2 insertions(+), 9 deletions(-)
10
12
11
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu.h
15
--- a/target/arm/tcg/translate-a64.c
14
+++ b/target/arm/cpu.h
16
+++ b/target/arm/tcg/translate-a64.c
15
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
17
@@ -XXX,XX +XXX,XX @@ static uint64_t bitfield_replicate(uint64_t mask, unsigned int e)
16
} sau;
18
return mask;
17
19
}
18
void *nvic;
20
19
- const struct arm_boot_info *boot_info;
21
-/* Return a value with the bottom len bits set (where 0 < len <= 64) */
20
#if !defined(CONFIG_USER_ONLY)
22
-static inline uint64_t bitmask64(unsigned int length)
21
+ const struct arm_boot_info *boot_info;
23
-{
22
/* Store GICv3CPUState to access from this struct */
24
- assert(length > 0 && length <= 64);
23
void *gicv3state;
25
- return ~0ULL >> (64 - length);
24
#else /* CONFIG_USER_ONLY */
26
-}
27
-
28
/* Simplified variant of pseudocode DecodeBitMasks() for the case where we
29
* only require the wmask. Returns false if the imms/immr/immn are a reserved
30
* value (ie should cause a guest UNDEF exception), and true if they are
31
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
32
/* Create the value of one element: s+1 set bits rotated
33
* by r within the element (which is e bits wide)...
34
*/
35
- mask = bitmask64(s + 1);
36
+ mask = MAKE_64BIT_MASK(0, s + 1);
37
if (r) {
38
mask = (mask >> r) | (mask << (e - r));
39
- mask &= bitmask64(e);
40
+ mask &= MAKE_64BIT_MASK(0, e);
41
}
42
/* ...then replicate the element over the whole 64 bit value */
43
mask = bitfield_replicate(mask, e);
25
--
44
--
26
2.34.1
45
2.34.1
27
28
diff view generated by jsdifflib
1
From: Fabiano Rosas <farosas@suse.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Move this earlier to make the next patch diff cleaner. While here
3
Convert the ADD, ORR, EOR, ANDS (immediate) instructions.
4
update the comment slightly to not give the impression that the
5
misalignment affects only TCG.
6
4
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Fabiano Rosas <farosas@suse.de>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20230512144106.3608981-10-peter.maydell@linaro.org
9
[PMM: rebased]
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
target/arm/machine.c | 18 +++++++++---------
12
target/arm/tcg/a64.decode | 15 ++++++
14
1 file changed, 9 insertions(+), 9 deletions(-)
13
target/arm/tcg/translate-a64.c | 94 +++++++++++-----------------------
14
2 files changed, 44 insertions(+), 65 deletions(-)
15
15
16
diff --git a/target/arm/machine.c b/target/arm/machine.c
16
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/machine.c
18
--- a/target/arm/tcg/a64.decode
19
+++ b/target/arm/machine.c
19
+++ b/target/arm/tcg/a64.decode
20
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
20
@@ -XXX,XX +XXX,XX @@ SUBS_i . 11 100010 1 ............ ..... ..... @addsub_imm12
21
}
21
22
ADDG_i 1 00 100011 0 ...... 00 .... ..... ..... @addsub_imm_tag
23
SUBG_i 1 10 100011 0 ...... 00 .... ..... ..... @addsub_imm_tag
24
+
25
+# Logical (immediate)
26
+
27
+&rri_log rd rn sf dbm
28
+@logic_imm_64 1 .. ...... dbm:13 rn:5 rd:5 &rri_log sf=1
29
+@logic_imm_32 0 .. ...... 0 dbm:12 rn:5 rd:5 &rri_log sf=0
30
+
31
+AND_i . 00 100100 . ...... ...... ..... ..... @logic_imm_64
32
+AND_i . 00 100100 . ...... ...... ..... ..... @logic_imm_32
33
+ORR_i . 01 100100 . ...... ...... ..... ..... @logic_imm_64
34
+ORR_i . 01 100100 . ...... ...... ..... ..... @logic_imm_32
35
+EOR_i . 10 100100 . ...... ...... ..... ..... @logic_imm_64
36
+EOR_i . 10 100100 . ...... ...... ..... ..... @logic_imm_32
37
+ANDS_i . 11 100100 . ...... ...... ..... ..... @logic_imm_64
38
+ANDS_i . 11 100100 . ...... ...... ..... ..... @logic_imm_32
39
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/tcg/translate-a64.c
42
+++ b/target/arm/tcg/translate-a64.c
43
@@ -XXX,XX +XXX,XX @@ static uint64_t bitfield_replicate(uint64_t mask, unsigned int e)
44
return mask;
45
}
46
47
-/* Simplified variant of pseudocode DecodeBitMasks() for the case where we
48
+/*
49
+ * Logical (immediate)
50
+ */
51
+
52
+/*
53
+ * Simplified variant of pseudocode DecodeBitMasks() for the case where we
54
* only require the wmask. Returns false if the imms/immr/immn are a reserved
55
* value (ie should cause a guest UNDEF exception), and true if they are
56
* valid, in which case the decoded bit pattern is written to result.
57
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
58
return true;
59
}
60
61
-/* Logical (immediate)
62
- * 31 30 29 28 23 22 21 16 15 10 9 5 4 0
63
- * +----+-----+-------------+---+------+------+------+------+
64
- * | sf | opc | 1 0 0 1 0 0 | N | immr | imms | Rn | Rd |
65
- * +----+-----+-------------+---+------+------+------+------+
66
- */
67
-static void disas_logic_imm(DisasContext *s, uint32_t insn)
68
+static bool gen_rri_log(DisasContext *s, arg_rri_log *a, bool set_cc,
69
+ void (*fn)(TCGv_i64, TCGv_i64, int64_t))
70
{
71
- unsigned int sf, opc, is_n, immr, imms, rn, rd;
72
TCGv_i64 tcg_rd, tcg_rn;
73
- uint64_t wmask;
74
- bool is_and = false;
75
+ uint64_t imm;
76
77
- sf = extract32(insn, 31, 1);
78
- opc = extract32(insn, 29, 2);
79
- is_n = extract32(insn, 22, 1);
80
- immr = extract32(insn, 16, 6);
81
- imms = extract32(insn, 10, 6);
82
- rn = extract32(insn, 5, 5);
83
- rd = extract32(insn, 0, 5);
84
-
85
- if (!sf && is_n) {
86
- unallocated_encoding(s);
87
- return;
88
+ /* Some immediate field values are reserved. */
89
+ if (!logic_imm_decode_wmask(&imm, extract32(a->dbm, 12, 1),
90
+ extract32(a->dbm, 0, 6),
91
+ extract32(a->dbm, 6, 6))) {
92
+ return false;
93
+ }
94
+ if (!a->sf) {
95
+ imm &= 0xffffffffull;
22
}
96
}
23
97
24
+ /*
98
- if (opc == 0x3) { /* ANDS */
25
+ * Misaligned thumb pc is architecturally impossible. Fail the
99
- tcg_rd = cpu_reg(s, rd);
26
+ * incoming migration. For TCG it would trigger the assert in
100
- } else {
27
+ * thumb_tr_translate_insn().
101
- tcg_rd = cpu_reg_sp(s, rd);
28
+ */
102
- }
29
+ if (!is_a64(env) && env->thumb && (env->regs[15] & 1)) {
103
- tcg_rn = cpu_reg(s, rn);
30
+ return -1;
104
+ tcg_rd = set_cc ? cpu_reg(s, a->rd) : cpu_reg_sp(s, a->rd);
31
+ }
105
+ tcg_rn = cpu_reg(s, a->rn);
32
+
106
33
hw_breakpoint_update_all(cpu);
107
- if (!logic_imm_decode_wmask(&wmask, is_n, imms, immr)) {
34
hw_watchpoint_update_all(cpu);
108
- /* some immediate field values are reserved */
35
109
- unallocated_encoding(s);
36
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
110
- return;
37
}
111
+ fn(tcg_rd, tcg_rn, imm);
112
+ if (set_cc) {
113
+ gen_logic_CC(a->sf, tcg_rd);
38
}
114
}
39
115
-
40
- /*
116
- if (!sf) {
41
- * Misaligned thumb pc is architecturally impossible.
117
- wmask &= 0xffffffff;
42
- * We have an assert in thumb_tr_translate_insn to verify this.
43
- * Fail an incoming migrate to avoid this assert.
44
- */
45
- if (!is_a64(env) && env->thumb && (env->regs[15] & 1)) {
46
- return -1;
47
- }
118
- }
48
-
119
-
49
if (!kvm_enabled()) {
120
- switch (opc) {
50
pmu_op_finish(&cpu->env);
121
- case 0x3: /* ANDS */
122
- case 0x0: /* AND */
123
- tcg_gen_andi_i64(tcg_rd, tcg_rn, wmask);
124
- is_and = true;
125
- break;
126
- case 0x1: /* ORR */
127
- tcg_gen_ori_i64(tcg_rd, tcg_rn, wmask);
128
- break;
129
- case 0x2: /* EOR */
130
- tcg_gen_xori_i64(tcg_rd, tcg_rn, wmask);
131
- break;
132
- default:
133
- assert(FALSE); /* must handle all above */
134
- break;
135
- }
136
-
137
- if (!sf && !is_and) {
138
- /* zero extend final result; we know we can skip this for AND
139
- * since the immediate had the high 32 bits clear.
140
- */
141
+ if (!a->sf) {
142
tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
51
}
143
}
144
-
145
- if (opc == 3) { /* ANDS */
146
- gen_logic_CC(sf, tcg_rd);
147
- }
148
+ return true;
149
}
150
151
+TRANS(AND_i, gen_rri_log, a, false, tcg_gen_andi_i64)
152
+TRANS(ORR_i, gen_rri_log, a, false, tcg_gen_ori_i64)
153
+TRANS(EOR_i, gen_rri_log, a, false, tcg_gen_xori_i64)
154
+TRANS(ANDS_i, gen_rri_log, a, true, tcg_gen_andi_i64)
155
+
156
/*
157
* Move wide (immediate)
158
*
159
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
160
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
161
{
162
switch (extract32(insn, 23, 6)) {
163
- case 0x24: /* Logical (immediate) */
164
- disas_logic_imm(s, insn);
165
- break;
166
case 0x25: /* Move wide (immediate) */
167
disas_movw_imm(s, insn);
168
break;
52
--
169
--
53
2.34.1
170
2.34.1
54
55
diff view generated by jsdifflib
1
From: Fabiano Rosas <farosas@suse.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
These tests set -accel tcg, so restrict them to when TCG is present.
3
Convert the MON, MOVZ, MOVK instructions.
4
4
5
Signed-off-by: Fabiano Rosas <farosas@suse.de>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Acked-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230512144106.3608981-11-peter.maydell@linaro.org
9
[PMM: Rebased]
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
12
---
10
tests/qtest/meson.build | 4 ++--
13
target/arm/tcg/a64.decode | 13 ++++++
11
1 file changed, 2 insertions(+), 2 deletions(-)
14
target/arm/tcg/translate-a64.c | 73 ++++++++++++++--------------------
15
2 files changed, 42 insertions(+), 44 deletions(-)
12
16
13
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
17
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/qtest/meson.build
19
--- a/target/arm/tcg/a64.decode
16
+++ b/tests/qtest/meson.build
20
+++ b/target/arm/tcg/a64.decode
17
@@ -XXX,XX +XXX,XX @@ qtests_arm = \
21
@@ -XXX,XX +XXX,XX @@ EOR_i . 10 100100 . ...... ...... ..... ..... @logic_imm_64
18
# TODO: once aarch64 TCG is fixed on ARM 32 bit host, make bios-tables-test unconditional
22
EOR_i . 10 100100 . ...... ...... ..... ..... @logic_imm_32
19
qtests_aarch64 = \
23
ANDS_i . 11 100100 . ...... ...... ..... ..... @logic_imm_64
20
(cpu != 'arm' and unpack_edk2_blobs ? ['bios-tables-test'] : []) + \
24
ANDS_i . 11 100100 . ...... ...... ..... ..... @logic_imm_32
21
- (config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? ['tpm-tis-device-test'] : []) + \
25
+
22
- (config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? ['tpm-tis-device-swtpm-test'] : []) + \
26
+# Move wide (immediate)
23
+ (config_all.has_key('CONFIG_TCG') and config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? \
27
+
24
+ ['tpm-tis-device-test', 'tpm-tis-device-swtpm-test'] : []) + \
28
+&movw rd sf imm hw
25
(config_all_devices.has_key('CONFIG_XLNX_ZYNQMP_ARM') ? ['xlnx-can-test', 'fuzz-xlnx-dp-test'] : []) + \
29
+@movw_64 1 .. ...... hw:2 imm:16 rd:5 &movw sf=1
26
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
30
+@movw_32 0 .. ...... 0 hw:1 imm:16 rd:5 &movw sf=0
27
['arm-cpu-features',
31
+
32
+MOVN . 00 100101 .. ................ ..... @movw_64
33
+MOVN . 00 100101 .. ................ ..... @movw_32
34
+MOVZ . 10 100101 .. ................ ..... @movw_64
35
+MOVZ . 10 100101 .. ................ ..... @movw_32
36
+MOVK . 11 100101 .. ................ ..... @movw_64
37
+MOVK . 11 100101 .. ................ ..... @movw_32
38
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/tcg/translate-a64.c
41
+++ b/target/arm/tcg/translate-a64.c
42
@@ -XXX,XX +XXX,XX @@ TRANS(ANDS_i, gen_rri_log, a, true, tcg_gen_andi_i64)
43
44
/*
45
* Move wide (immediate)
46
- *
47
- * 31 30 29 28 23 22 21 20 5 4 0
48
- * +--+-----+-------------+-----+----------------+------+
49
- * |sf| opc | 1 0 0 1 0 1 | hw | imm16 | Rd |
50
- * +--+-----+-------------+-----+----------------+------+
51
- *
52
- * sf: 0 -> 32 bit, 1 -> 64 bit
53
- * opc: 00 -> N, 10 -> Z, 11 -> K
54
- * hw: shift/16 (0,16, and sf only 32, 48)
55
*/
56
-static void disas_movw_imm(DisasContext *s, uint32_t insn)
57
+
58
+static bool trans_MOVZ(DisasContext *s, arg_movw *a)
59
{
60
- int rd = extract32(insn, 0, 5);
61
- uint64_t imm = extract32(insn, 5, 16);
62
- int sf = extract32(insn, 31, 1);
63
- int opc = extract32(insn, 29, 2);
64
- int pos = extract32(insn, 21, 2) << 4;
65
- TCGv_i64 tcg_rd = cpu_reg(s, rd);
66
+ int pos = a->hw << 4;
67
+ tcg_gen_movi_i64(cpu_reg(s, a->rd), (uint64_t)a->imm << pos);
68
+ return true;
69
+}
70
71
- if (!sf && (pos >= 32)) {
72
- unallocated_encoding(s);
73
- return;
74
- }
75
+static bool trans_MOVN(DisasContext *s, arg_movw *a)
76
+{
77
+ int pos = a->hw << 4;
78
+ uint64_t imm = a->imm;
79
80
- switch (opc) {
81
- case 0: /* MOVN */
82
- case 2: /* MOVZ */
83
- imm <<= pos;
84
- if (opc == 0) {
85
- imm = ~imm;
86
- }
87
- if (!sf) {
88
- imm &= 0xffffffffu;
89
- }
90
- tcg_gen_movi_i64(tcg_rd, imm);
91
- break;
92
- case 3: /* MOVK */
93
- tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_constant_i64(imm), pos, 16);
94
- if (!sf) {
95
- tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
96
- }
97
- break;
98
- default:
99
- unallocated_encoding(s);
100
- break;
101
+ imm = ~(imm << pos);
102
+ if (!a->sf) {
103
+ imm = (uint32_t)imm;
104
}
105
+ tcg_gen_movi_i64(cpu_reg(s, a->rd), imm);
106
+ return true;
107
+}
108
+
109
+static bool trans_MOVK(DisasContext *s, arg_movw *a)
110
+{
111
+ int pos = a->hw << 4;
112
+ TCGv_i64 tcg_rd, tcg_im;
113
+
114
+ tcg_rd = cpu_reg(s, a->rd);
115
+ tcg_im = tcg_constant_i64(a->imm);
116
+ tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_im, pos, 16);
117
+ if (!a->sf) {
118
+ tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
119
+ }
120
+ return true;
121
}
122
123
/* Bitfield
124
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
125
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
126
{
127
switch (extract32(insn, 23, 6)) {
128
- case 0x25: /* Move wide (immediate) */
129
- disas_movw_imm(s, insn);
130
- break;
131
case 0x26: /* Bitfield */
132
disas_bitfield(s, insn);
133
break;
28
--
134
--
29
2.34.1
135
2.34.1
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Hao Wu <wuhaotsh@google.com>
3
Convert the BFM, SBFM, UBFM instructions.
4
Reviewed-by: Titus Rwantare <titusr@google.com>
4
5
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20230208235433.3989937-4-wuhaotsh@google.com
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230512144106.3608981-12-peter.maydell@linaro.org
9
[PMM: Rebased]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
11
---
9
docs/system/arm/nuvoton.rst | 2 +-
12
target/arm/tcg/a64.decode | 13 +++
10
include/hw/arm/npcm7xx.h | 2 ++
13
target/arm/tcg/translate-a64.c | 144 ++++++++++++++++++---------------
11
hw/arm/npcm7xx.c | 25 +++++++++++++++++++++++--
14
2 files changed, 94 insertions(+), 63 deletions(-)
12
3 files changed, 26 insertions(+), 3 deletions(-)
13
15
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
16
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/nuvoton.rst
18
--- a/target/arm/tcg/a64.decode
17
+++ b/docs/system/arm/nuvoton.rst
19
+++ b/target/arm/tcg/a64.decode
18
@@ -XXX,XX +XXX,XX @@ Supported devices
20
@@ -XXX,XX +XXX,XX @@ MOVZ . 10 100101 .. ................ ..... @movw_64
19
* SMBus controller (SMBF)
21
MOVZ . 10 100101 .. ................ ..... @movw_32
20
* Ethernet controller (EMC)
22
MOVK . 11 100101 .. ................ ..... @movw_64
21
* Tachometer
23
MOVK . 11 100101 .. ................ ..... @movw_32
22
+ * Peripheral SPI controller (PSPI)
24
+
23
25
+# Bitfield
24
Missing devices
26
+
25
---------------
27
+&bitfield rd rn sf immr imms
26
@@ -XXX,XX +XXX,XX @@ Missing devices
28
+@bitfield_64 1 .. ...... 1 immr:6 imms:6 rn:5 rd:5 &bitfield sf=1
27
29
+@bitfield_32 0 .. ...... 0 0 immr:5 0 imms:5 rn:5 rd:5 &bitfield sf=0
28
* Ethernet controller (GMAC)
30
+
29
* USB device (USBD)
31
+SBFM . 00 100110 . ...... ...... ..... ..... @bitfield_64
30
- * Peripheral SPI controller (PSPI)
32
+SBFM . 00 100110 . ...... ...... ..... ..... @bitfield_32
31
* SD/MMC host
33
+BFM . 01 100110 . ...... ...... ..... ..... @bitfield_64
32
* PECI interface
34
+BFM . 01 100110 . ...... ...... ..... ..... @bitfield_32
33
* PCI and PCIe root complex and bridges
35
+UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_64
34
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
36
+UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_32
37
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
35
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/arm/npcm7xx.h
39
--- a/target/arm/tcg/translate-a64.c
37
+++ b/include/hw/arm/npcm7xx.h
40
+++ b/target/arm/tcg/translate-a64.c
38
@@ -XXX,XX +XXX,XX @@
41
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVK(DisasContext *s, arg_movw *a)
39
#include "hw/nvram/npcm7xx_otp.h"
42
return true;
40
#include "hw/timer/npcm7xx_timer.h"
43
}
41
#include "hw/ssi/npcm7xx_fiu.h"
44
42
+#include "hw/ssi/npcm_pspi.h"
45
-/* Bitfield
43
#include "hw/usb/hcd-ehci.h"
46
- * 31 30 29 28 23 22 21 16 15 10 9 5 4 0
44
#include "hw/usb/hcd-ohci.h"
47
- * +----+-----+-------------+---+------+------+------+------+
45
#include "target/arm/cpu.h"
48
- * | sf | opc | 1 0 0 1 1 0 | N | immr | imms | Rn | Rd |
46
@@ -XXX,XX +XXX,XX @@ struct NPCM7xxState {
49
- * +----+-----+-------------+---+------+------+------+------+
47
NPCM7xxFIUState fiu[2];
50
+/*
48
NPCM7xxEMCState emc[2];
51
+ * Bitfield
49
NPCM7xxSDHCIState mmc;
52
*/
50
+ NPCMPSPIState pspi[2];
53
-static void disas_bitfield(DisasContext *s, uint32_t insn)
51
};
54
+
52
55
+static bool trans_SBFM(DisasContext *s, arg_SBFM *a)
53
#define TYPE_NPCM7XX "npcm7xx"
56
{
54
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
57
- unsigned int sf, n, opc, ri, si, rn, rd, bitsize, pos, len;
55
index XXXXXXX..XXXXXXX 100644
58
- TCGv_i64 tcg_rd, tcg_tmp;
56
--- a/hw/arm/npcm7xx.c
59
+ TCGv_i64 tcg_rd = cpu_reg(s, a->rd);
57
+++ b/hw/arm/npcm7xx.c
60
+ TCGv_i64 tcg_tmp = read_cpu_reg(s, a->rn, 1);
58
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
61
+ unsigned int bitsize = a->sf ? 64 : 32;
59
NPCM7XX_EMC1RX_IRQ = 15,
62
+ unsigned int ri = a->immr;
60
NPCM7XX_EMC1TX_IRQ,
63
+ unsigned int si = a->imms;
61
NPCM7XX_MMC_IRQ = 26,
64
+ unsigned int pos, len;
62
+ NPCM7XX_PSPI2_IRQ = 28,
65
63
+ NPCM7XX_PSPI1_IRQ = 31,
66
- sf = extract32(insn, 31, 1);
64
NPCM7XX_TIMER0_IRQ = 32, /* Timer Module 0 */
67
- opc = extract32(insn, 29, 2);
65
NPCM7XX_TIMER1_IRQ,
68
- n = extract32(insn, 22, 1);
66
NPCM7XX_TIMER2_IRQ,
69
- ri = extract32(insn, 16, 6);
67
@@ -XXX,XX +XXX,XX @@ static const hwaddr npcm7xx_emc_addr[] = {
70
- si = extract32(insn, 10, 6);
68
0xf0826000,
71
- rn = extract32(insn, 5, 5);
69
};
72
- rd = extract32(insn, 0, 5);
70
73
- bitsize = sf ? 64 : 32;
71
+/* Register base address for each PSPI Module */
74
-
72
+static const hwaddr npcm7xx_pspi_addr[] = {
75
- if (sf != n || ri >= bitsize || si >= bitsize || opc > 2) {
73
+ 0xf0200000,
76
- unallocated_encoding(s);
74
+ 0xf0201000,
77
- return;
75
+};
78
- }
76
+
79
-
77
static const struct {
80
- tcg_rd = cpu_reg(s, rd);
78
hwaddr regs_addr;
81
-
79
uint32_t unconnected_pins;
82
- /* Suppress the zero-extend for !sf. Since RI and SI are constrained
80
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init(Object *obj)
83
- to be smaller than bitsize, we'll never reference data outside the
81
object_initialize_child(obj, "emc[*]", &s->emc[i], TYPE_NPCM7XX_EMC);
84
- low 32-bits anyway. */
85
- tcg_tmp = read_cpu_reg(s, rn, 1);
86
-
87
- /* Recognize simple(r) extractions. */
88
if (si >= ri) {
89
/* Wd<s-r:0> = Wn<s:r> */
90
len = (si - ri) + 1;
91
- if (opc == 0) { /* SBFM: ASR, SBFX, SXTB, SXTH, SXTW */
92
- tcg_gen_sextract_i64(tcg_rd, tcg_tmp, ri, len);
93
- goto done;
94
- } else if (opc == 2) { /* UBFM: UBFX, LSR, UXTB, UXTH */
95
- tcg_gen_extract_i64(tcg_rd, tcg_tmp, ri, len);
96
- return;
97
+ tcg_gen_sextract_i64(tcg_rd, tcg_tmp, ri, len);
98
+ if (!a->sf) {
99
+ tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
100
}
101
- /* opc == 1, BFXIL fall through to deposit */
102
+ } else {
103
+ /* Wd<32+s-r,32-r> = Wn<s:0> */
104
+ len = si + 1;
105
+ pos = (bitsize - ri) & (bitsize - 1);
106
+
107
+ if (len < ri) {
108
+ /*
109
+ * Sign extend the destination field from len to fill the
110
+ * balance of the word. Let the deposit below insert all
111
+ * of those sign bits.
112
+ */
113
+ tcg_gen_sextract_i64(tcg_tmp, tcg_tmp, 0, len);
114
+ len = ri;
115
+ }
116
+
117
+ /*
118
+ * We start with zero, and we haven't modified any bits outside
119
+ * bitsize, therefore no final zero-extension is unneeded for !sf.
120
+ */
121
+ tcg_gen_deposit_z_i64(tcg_rd, tcg_tmp, pos, len);
122
+ }
123
+ return true;
124
+}
125
+
126
+static bool trans_UBFM(DisasContext *s, arg_UBFM *a)
127
+{
128
+ TCGv_i64 tcg_rd = cpu_reg(s, a->rd);
129
+ TCGv_i64 tcg_tmp = read_cpu_reg(s, a->rn, 1);
130
+ unsigned int bitsize = a->sf ? 64 : 32;
131
+ unsigned int ri = a->immr;
132
+ unsigned int si = a->imms;
133
+ unsigned int pos, len;
134
+
135
+ tcg_rd = cpu_reg(s, a->rd);
136
+ tcg_tmp = read_cpu_reg(s, a->rn, 1);
137
+
138
+ if (si >= ri) {
139
+ /* Wd<s-r:0> = Wn<s:r> */
140
+ len = (si - ri) + 1;
141
+ tcg_gen_extract_i64(tcg_rd, tcg_tmp, ri, len);
142
+ } else {
143
+ /* Wd<32+s-r,32-r> = Wn<s:0> */
144
+ len = si + 1;
145
+ pos = (bitsize - ri) & (bitsize - 1);
146
+ tcg_gen_deposit_z_i64(tcg_rd, tcg_tmp, pos, len);
147
+ }
148
+ return true;
149
+}
150
+
151
+static bool trans_BFM(DisasContext *s, arg_BFM *a)
152
+{
153
+ TCGv_i64 tcg_rd = cpu_reg(s, a->rd);
154
+ TCGv_i64 tcg_tmp = read_cpu_reg(s, a->rn, 1);
155
+ unsigned int bitsize = a->sf ? 64 : 32;
156
+ unsigned int ri = a->immr;
157
+ unsigned int si = a->imms;
158
+ unsigned int pos, len;
159
+
160
+ tcg_rd = cpu_reg(s, a->rd);
161
+ tcg_tmp = read_cpu_reg(s, a->rn, 1);
162
+
163
+ if (si >= ri) {
164
+ /* Wd<s-r:0> = Wn<s:r> */
165
tcg_gen_shri_i64(tcg_tmp, tcg_tmp, ri);
166
+ len = (si - ri) + 1;
167
pos = 0;
168
} else {
169
- /* Handle the ri > si case with a deposit
170
- * Wd<32+s-r,32-r> = Wn<s:0>
171
- */
172
+ /* Wd<32+s-r,32-r> = Wn<s:0> */
173
len = si + 1;
174
pos = (bitsize - ri) & (bitsize - 1);
82
}
175
}
83
176
84
+ for (i = 0; i < ARRAY_SIZE(s->pspi); i++) {
177
- if (opc == 0 && len < ri) {
85
+ object_initialize_child(obj, "pspi[*]", &s->pspi[i], TYPE_NPCM_PSPI);
178
- /* SBFM: sign extend the destination field from len to fill
86
+ }
179
- the balance of the word. Let the deposit below insert all
87
+
180
- of those sign bits. */
88
object_initialize_child(obj, "mmc", &s->mmc, TYPE_NPCM7XX_SDHCI);
181
- tcg_gen_sextract_i64(tcg_tmp, tcg_tmp, 0, len);
182
- len = ri;
183
- }
184
-
185
- if (opc == 1) { /* BFM, BFXIL */
186
- tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, pos, len);
187
- } else {
188
- /* SBFM or UBFM: We start with zero, and we haven't modified
189
- any bits outside bitsize, therefore the zero-extension
190
- below is unneeded. */
191
- tcg_gen_deposit_z_i64(tcg_rd, tcg_tmp, pos, len);
192
- return;
193
- }
194
-
195
- done:
196
- if (!sf) { /* zero extend final result */
197
+ tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, pos, len);
198
+ if (!a->sf) {
199
tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
200
}
201
+ return true;
89
}
202
}
90
203
91
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
204
/* Extract
92
sysbus_connect_irq(SYS_BUS_DEVICE(&s->mmc), 0,
205
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
93
npcm7xx_irq(s, NPCM7XX_MMC_IRQ));
206
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
94
207
{
95
+ /* PSPI */
208
switch (extract32(insn, 23, 6)) {
96
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_pspi_addr) != ARRAY_SIZE(s->pspi));
209
- case 0x26: /* Bitfield */
97
+ for (i = 0; i < ARRAY_SIZE(s->pspi); i++) {
210
- disas_bitfield(s, insn);
98
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->pspi[i]);
211
- break;
99
+ int irq = (i == 0) ? NPCM7XX_PSPI1_IRQ : NPCM7XX_PSPI2_IRQ;
212
case 0x27: /* Extract */
100
+
213
disas_extract(s, insn);
101
+ sysbus_realize(sbd, &error_abort);
214
break;
102
+ sysbus_mmio_map(sbd, 0, npcm7xx_pspi_addr[i]);
103
+ sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, irq));
104
+ }
105
+
106
create_unimplemented_device("npcm7xx.shm", 0xc0001000, 4 * KiB);
107
create_unimplemented_device("npcm7xx.vdmx", 0xe0800000, 4 * KiB);
108
create_unimplemented_device("npcm7xx.pcierc", 0xe1000000, 64 * KiB);
109
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
110
create_unimplemented_device("npcm7xx.peci", 0xf0100000, 4 * KiB);
111
create_unimplemented_device("npcm7xx.siox[1]", 0xf0101000, 4 * KiB);
112
create_unimplemented_device("npcm7xx.siox[2]", 0xf0102000, 4 * KiB);
113
- create_unimplemented_device("npcm7xx.pspi1", 0xf0200000, 4 * KiB);
114
- create_unimplemented_device("npcm7xx.pspi2", 0xf0201000, 4 * KiB);
115
create_unimplemented_device("npcm7xx.ahbpci", 0xf0400000, 1 * MiB);
116
create_unimplemented_device("npcm7xx.mcphy", 0xf05f0000, 64 * KiB);
117
create_unimplemented_device("npcm7xx.gmac1", 0xf0802000, 8 * KiB);
118
--
215
--
119
2.34.1
216
2.34.1
diff view generated by jsdifflib
1
From: Fabiano Rosas <farosas@suse.de>
1
Convert the EXTR instruction to decodetree (this is the
2
only one in the 'Extract" class). This is the last of
3
the dp-immediate insns in the legacy decoder, so we
4
can now remove disas_data_proc_imm().
2
5
3
Now that the cortex-a15 is under CONFIG_TCG, use as default CPU for a
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
KVM-only build the 'max' cpu.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230512144106.3608981-13-peter.maydell@linaro.org
9
---
10
target/arm/tcg/a64.decode | 7 +++
11
target/arm/tcg/translate-a64.c | 94 +++++++++++-----------------------
12
2 files changed, 36 insertions(+), 65 deletions(-)
5
13
6
Note that we cannot use 'host' here because the qtests can run without
14
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
7
any other accelerator (than qtest) and 'host' depends on KVM being
8
enabled.
9
10
Signed-off-by: Fabiano Rosas <farosas@suse.de>
11
Acked-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Thomas Huth <thuth@redhat.com>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/arm/virt.c | 4 ++++
16
1 file changed, 4 insertions(+)
17
18
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/virt.c
16
--- a/target/arm/tcg/a64.decode
21
+++ b/hw/arm/virt.c
17
+++ b/target/arm/tcg/a64.decode
22
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
18
@@ -XXX,XX +XXX,XX @@ BFM . 01 100110 . ...... ...... ..... ..... @bitfield_64
23
mc->minimum_page_bits = 12;
19
BFM . 01 100110 . ...... ...... ..... ..... @bitfield_32
24
mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
20
UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_64
25
mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
21
UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_32
26
+#ifdef CONFIG_TCG
22
+
27
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
23
+# Extract
28
+#else
24
+
29
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("max");
25
+&extract rd rn rm imm sf
30
+#endif
26
+
31
mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
27
+EXTR 1 00 100111 1 0 rm:5 imm:6 rn:5 rd:5 &extract sf=1
32
mc->kvm_type = virt_kvm_type;
28
+EXTR 0 00 100111 0 0 rm:5 0 imm:5 rn:5 rd:5 &extract sf=0
33
assert(!mc->get_hotplug_handler);
29
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/tcg/translate-a64.c
32
+++ b/target/arm/tcg/translate-a64.c
33
@@ -XXX,XX +XXX,XX @@ static bool trans_BFM(DisasContext *s, arg_BFM *a)
34
return true;
35
}
36
37
-/* Extract
38
- * 31 30 29 28 23 22 21 20 16 15 10 9 5 4 0
39
- * +----+------+-------------+---+----+------+--------+------+------+
40
- * | sf | op21 | 1 0 0 1 1 1 | N | o0 | Rm | imms | Rn | Rd |
41
- * +----+------+-------------+---+----+------+--------+------+------+
42
- */
43
-static void disas_extract(DisasContext *s, uint32_t insn)
44
+static bool trans_EXTR(DisasContext *s, arg_extract *a)
45
{
46
- unsigned int sf, n, rm, imm, rn, rd, bitsize, op21, op0;
47
+ TCGv_i64 tcg_rd, tcg_rm, tcg_rn;
48
49
- sf = extract32(insn, 31, 1);
50
- n = extract32(insn, 22, 1);
51
- rm = extract32(insn, 16, 5);
52
- imm = extract32(insn, 10, 6);
53
- rn = extract32(insn, 5, 5);
54
- rd = extract32(insn, 0, 5);
55
- op21 = extract32(insn, 29, 2);
56
- op0 = extract32(insn, 21, 1);
57
- bitsize = sf ? 64 : 32;
58
+ tcg_rd = cpu_reg(s, a->rd);
59
60
- if (sf != n || op21 || op0 || imm >= bitsize) {
61
- unallocated_encoding(s);
62
- } else {
63
- TCGv_i64 tcg_rd, tcg_rm, tcg_rn;
64
-
65
- tcg_rd = cpu_reg(s, rd);
66
-
67
- if (unlikely(imm == 0)) {
68
- /* tcg shl_i32/shl_i64 is undefined for 32/64 bit shifts,
69
- * so an extract from bit 0 is a special case.
70
- */
71
- if (sf) {
72
- tcg_gen_mov_i64(tcg_rd, cpu_reg(s, rm));
73
- } else {
74
- tcg_gen_ext32u_i64(tcg_rd, cpu_reg(s, rm));
75
- }
76
+ if (unlikely(a->imm == 0)) {
77
+ /*
78
+ * tcg shl_i32/shl_i64 is undefined for 32/64 bit shifts,
79
+ * so an extract from bit 0 is a special case.
80
+ */
81
+ if (a->sf) {
82
+ tcg_gen_mov_i64(tcg_rd, cpu_reg(s, a->rm));
83
} else {
84
- tcg_rm = cpu_reg(s, rm);
85
- tcg_rn = cpu_reg(s, rn);
86
+ tcg_gen_ext32u_i64(tcg_rd, cpu_reg(s, a->rm));
87
+ }
88
+ } else {
89
+ tcg_rm = cpu_reg(s, a->rm);
90
+ tcg_rn = cpu_reg(s, a->rn);
91
92
- if (sf) {
93
- /* Specialization to ROR happens in EXTRACT2. */
94
- tcg_gen_extract2_i64(tcg_rd, tcg_rm, tcg_rn, imm);
95
+ if (a->sf) {
96
+ /* Specialization to ROR happens in EXTRACT2. */
97
+ tcg_gen_extract2_i64(tcg_rd, tcg_rm, tcg_rn, a->imm);
98
+ } else {
99
+ TCGv_i32 t0 = tcg_temp_new_i32();
100
+
101
+ tcg_gen_extrl_i64_i32(t0, tcg_rm);
102
+ if (a->rm == a->rn) {
103
+ tcg_gen_rotri_i32(t0, t0, a->imm);
104
} else {
105
- TCGv_i32 t0 = tcg_temp_new_i32();
106
-
107
- tcg_gen_extrl_i64_i32(t0, tcg_rm);
108
- if (rm == rn) {
109
- tcg_gen_rotri_i32(t0, t0, imm);
110
- } else {
111
- TCGv_i32 t1 = tcg_temp_new_i32();
112
- tcg_gen_extrl_i64_i32(t1, tcg_rn);
113
- tcg_gen_extract2_i32(t0, t0, t1, imm);
114
- }
115
- tcg_gen_extu_i32_i64(tcg_rd, t0);
116
+ TCGv_i32 t1 = tcg_temp_new_i32();
117
+ tcg_gen_extrl_i64_i32(t1, tcg_rn);
118
+ tcg_gen_extract2_i32(t0, t0, t1, a->imm);
119
}
120
+ tcg_gen_extu_i32_i64(tcg_rd, t0);
121
}
122
}
123
-}
124
-
125
-/* Data processing - immediate */
126
-static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
127
-{
128
- switch (extract32(insn, 23, 6)) {
129
- case 0x27: /* Extract */
130
- disas_extract(s, insn);
131
- break;
132
- default:
133
- unallocated_encoding(s);
134
- break;
135
- }
136
+ return true;
137
}
138
139
/* Shift a TCGv src by TCGv shift_amount, put result in dst.
140
@@ -XXX,XX +XXX,XX @@ static bool btype_destination_ok(uint32_t insn, bool bt, int btype)
141
static void disas_a64_legacy(DisasContext *s, uint32_t insn)
142
{
143
switch (extract32(insn, 25, 4)) {
144
- case 0x8: case 0x9: /* Data processing - immediate */
145
- disas_data_proc_imm(s, insn);
146
- break;
147
case 0xa: case 0xb: /* Branch, exception generation and system insns */
148
disas_b_exc_sys(s, insn);
149
break;
34
--
150
--
35
2.34.1
151
2.34.1
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Convert the unconditional branch immediate insns B and BL to
2
decodetree.
2
3
3
While dozens of files include "cpu.h", only 3 files require
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
these NVIC helper declarations.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20230512144106.3608981-14-peter.maydell@linaro.org
7
---
8
target/arm/tcg/a64.decode | 9 +++++++++
9
target/arm/tcg/translate-a64.c | 31 +++++++++++--------------------
10
2 files changed, 20 insertions(+), 20 deletions(-)
5
11
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20230206223502.25122-12-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/intc/armv7m_nvic.h | 123 ++++++++++++++++++++++++++++++++++
12
target/arm/cpu.h | 123 ----------------------------------
13
target/arm/cpu.c | 4 +-
14
target/arm/cpu_tcg.c | 3 +
15
target/arm/m_helper.c | 3 +
16
5 files changed, 132 insertions(+), 124 deletions(-)
17
18
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/intc/armv7m_nvic.h
14
--- a/target/arm/tcg/a64.decode
21
+++ b/include/hw/intc/armv7m_nvic.h
15
+++ b/target/arm/tcg/a64.decode
22
@@ -XXX,XX +XXX,XX @@ struct NVICState {
16
@@ -XXX,XX +XXX,XX @@
23
qemu_irq sysresetreq;
17
24
};
18
&ri rd imm
25
19
&rri_sf rd rn imm sf
26
+/* Interface between CPU and Interrupt controller. */
20
+&i imm
27
+/**
21
28
+ * armv7m_nvic_set_pending: mark the specified exception as pending
22
29
+ * @s: the NVIC
23
### Data Processing - Immediate
30
+ * @irq: the exception number to mark pending
24
@@ -XXX,XX +XXX,XX @@ UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_32
31
+ * @secure: false for non-banked exceptions or for the nonsecure
25
32
+ * version of a banked exception, true for the secure version of a banked
26
EXTR 1 00 100111 1 0 rm:5 imm:6 rn:5 rd:5 &extract sf=1
33
+ * exception.
27
EXTR 0 00 100111 0 0 rm:5 0 imm:5 rn:5 rd:5 &extract sf=0
34
+ *
28
+
35
+ * Marks the specified exception as pending. Note that we will assert()
29
+# Branches
36
+ * if @secure is true and @irq does not specify one of the fixed set
30
+
37
+ * of architecturally banked exceptions.
31
+%imm26 0:s26 !function=times_4
38
+ */
32
+@branch . ..... .......................... &i imm=%imm26
39
+void armv7m_nvic_set_pending(NVICState *s, int irq, bool secure);
33
+
40
+/**
34
+B 0 00101 .......................... @branch
41
+ * armv7m_nvic_set_pending_derived: mark this derived exception as pending
35
+BL 1 00101 .......................... @branch
42
+ * @s: the NVIC
36
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
43
+ * @irq: the exception number to mark pending
37
index XXXXXXX..XXXXXXX 100644
44
+ * @secure: false for non-banked exceptions or for the nonsecure
38
--- a/target/arm/tcg/translate-a64.c
45
+ * version of a banked exception, true for the secure version of a banked
39
+++ b/target/arm/tcg/translate-a64.c
46
+ * exception.
40
@@ -XXX,XX +XXX,XX @@ static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table,
47
+ *
41
* match up with those in the manual.
48
+ * Similar to armv7m_nvic_set_pending(), but specifically for derived
42
*/
49
+ * exceptions (exceptions generated in the course of trying to take
43
50
+ * a different exception).
44
-/* Unconditional branch (immediate)
51
+ */
45
- * 31 30 26 25 0
52
+void armv7m_nvic_set_pending_derived(NVICState *s, int irq, bool secure);
46
- * +----+-----------+-------------------------------------+
53
+/**
47
- * | op | 0 0 1 0 1 | imm26 |
54
+ * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
48
- * +----+-----------+-------------------------------------+
55
+ * @s: the NVIC
49
- */
56
+ * @irq: the exception number to mark pending
50
-static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
57
+ * @secure: false for non-banked exceptions or for the nonsecure
51
+static bool trans_B(DisasContext *s, arg_i *a)
58
+ * version of a banked exception, true for the secure version of a banked
52
{
59
+ * exception.
53
- int64_t diff = sextract32(insn, 0, 26) * 4;
60
+ *
54
-
61
+ * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
55
- if (insn & (1U << 31)) {
62
+ * generated in the course of lazy stacking of FP registers.
56
- /* BL Branch with link */
63
+ */
57
- gen_pc_plus_diff(s, cpu_reg(s, 30), curr_insn_len(s));
64
+void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure);
58
- }
65
+/**
59
-
66
+ * armv7m_nvic_get_pending_irq_info: return highest priority pending
60
- /* B Branch / BL Branch with link */
67
+ * exception, and whether it targets Secure state
61
reset_btype(s);
68
+ * @s: the NVIC
62
- gen_goto_tb(s, 0, diff);
69
+ * @pirq: set to pending exception number
63
+ gen_goto_tb(s, 0, a->imm);
70
+ * @ptargets_secure: set to whether pending exception targets Secure
71
+ *
72
+ * This function writes the number of the highest priority pending
73
+ * exception (the one which would be made active by
74
+ * armv7m_nvic_acknowledge_irq()) to @pirq, and sets @ptargets_secure
75
+ * to true if the current highest priority pending exception should
76
+ * be taken to Secure state, false for NS.
77
+ */
78
+void armv7m_nvic_get_pending_irq_info(NVICState *s, int *pirq,
79
+ bool *ptargets_secure);
80
+/**
81
+ * armv7m_nvic_acknowledge_irq: make highest priority pending exception active
82
+ * @s: the NVIC
83
+ *
84
+ * Move the current highest priority pending exception from the pending
85
+ * state to the active state, and update v7m.exception to indicate that
86
+ * it is the exception currently being handled.
87
+ */
88
+void armv7m_nvic_acknowledge_irq(NVICState *s);
89
+/**
90
+ * armv7m_nvic_complete_irq: complete specified interrupt or exception
91
+ * @s: the NVIC
92
+ * @irq: the exception number to complete
93
+ * @secure: true if this exception was secure
94
+ *
95
+ * Returns: -1 if the irq was not active
96
+ * 1 if completing this irq brought us back to base (no active irqs)
97
+ * 0 if there is still an irq active after this one was completed
98
+ * (Ignoring -1, this is the same as the RETTOBASE value before completion.)
99
+ */
100
+int armv7m_nvic_complete_irq(NVICState *s, int irq, bool secure);
101
+/**
102
+ * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
103
+ * @s: the NVIC
104
+ * @irq: the exception number to mark pending
105
+ * @secure: false for non-banked exceptions or for the nonsecure
106
+ * version of a banked exception, true for the secure version of a banked
107
+ * exception.
108
+ *
109
+ * Return whether an exception is "ready", i.e. whether the exception is
110
+ * enabled and is configured at a priority which would allow it to
111
+ * interrupt the current execution priority. This controls whether the
112
+ * RDY bit for it in the FPCCR is set.
113
+ */
114
+bool armv7m_nvic_get_ready_status(NVICState *s, int irq, bool secure);
115
+/**
116
+ * armv7m_nvic_raw_execution_priority: return the raw execution priority
117
+ * @s: the NVIC
118
+ *
119
+ * Returns: the raw execution priority as defined by the v8M architecture.
120
+ * This is the execution priority minus the effects of AIRCR.PRIS,
121
+ * and minus any PRIMASK/FAULTMASK/BASEPRI priority boosting.
122
+ * (v8M ARM ARM I_PKLD.)
123
+ */
124
+int armv7m_nvic_raw_execution_priority(NVICState *s);
125
+/**
126
+ * armv7m_nvic_neg_prio_requested: return true if the requested execution
127
+ * priority is negative for the specified security state.
128
+ * @s: the NVIC
129
+ * @secure: the security state to test
130
+ * This corresponds to the pseudocode IsReqExecPriNeg().
131
+ */
132
+#ifndef CONFIG_USER_ONLY
133
+bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure);
134
+#else
135
+static inline bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure)
136
+{
137
+ return false;
138
+}
139
+#endif
140
+#ifndef CONFIG_USER_ONLY
141
+bool armv7m_nvic_can_take_pending_exception(NVICState *s);
142
+#else
143
+static inline bool armv7m_nvic_can_take_pending_exception(NVICState *s)
144
+{
145
+ return true;
64
+ return true;
146
+}
65
+}
147
+#endif
148
+
66
+
149
#endif
67
+static bool trans_BL(DisasContext *s, arg_i *a)
150
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
68
+{
151
index XXXXXXX..XXXXXXX 100644
69
+ gen_pc_plus_diff(s, cpu_reg(s, 30), curr_insn_len(s));
152
--- a/target/arm/cpu.h
70
+ reset_btype(s);
153
+++ b/target/arm/cpu.h
71
+ gen_goto_tb(s, 0, a->imm);
154
@@ -XXX,XX +XXX,XX @@ void arm_cpu_list(void);
72
+ return true;
155
uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
73
}
156
uint32_t cur_el, bool secure);
74
157
75
/* Compare and branch (immediate)
158
-/* Interface between CPU and Interrupt controller. */
76
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
159
-#ifndef CONFIG_USER_ONLY
77
static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
160
-bool armv7m_nvic_can_take_pending_exception(NVICState *s);
78
{
161
-#else
79
switch (extract32(insn, 25, 7)) {
162
-static inline bool armv7m_nvic_can_take_pending_exception(NVICState *s)
80
- case 0x0a: case 0x0b:
163
-{
81
- case 0x4a: case 0x4b: /* Unconditional branch (immediate) */
164
- return true;
82
- disas_uncond_b_imm(s, insn);
165
-}
83
- break;
166
-#endif
84
case 0x1a: case 0x5a: /* Compare & branch (immediate) */
167
-/**
85
disas_comp_b_imm(s, insn);
168
- * armv7m_nvic_set_pending: mark the specified exception as pending
86
break;
169
- * @s: the NVIC
170
- * @irq: the exception number to mark pending
171
- * @secure: false for non-banked exceptions or for the nonsecure
172
- * version of a banked exception, true for the secure version of a banked
173
- * exception.
174
- *
175
- * Marks the specified exception as pending. Note that we will assert()
176
- * if @secure is true and @irq does not specify one of the fixed set
177
- * of architecturally banked exceptions.
178
- */
179
-void armv7m_nvic_set_pending(NVICState *s, int irq, bool secure);
180
-/**
181
- * armv7m_nvic_set_pending_derived: mark this derived exception as pending
182
- * @s: the NVIC
183
- * @irq: the exception number to mark pending
184
- * @secure: false for non-banked exceptions or for the nonsecure
185
- * version of a banked exception, true for the secure version of a banked
186
- * exception.
187
- *
188
- * Similar to armv7m_nvic_set_pending(), but specifically for derived
189
- * exceptions (exceptions generated in the course of trying to take
190
- * a different exception).
191
- */
192
-void armv7m_nvic_set_pending_derived(NVICState *s, int irq, bool secure);
193
-/**
194
- * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
195
- * @s: the NVIC
196
- * @irq: the exception number to mark pending
197
- * @secure: false for non-banked exceptions or for the nonsecure
198
- * version of a banked exception, true for the secure version of a banked
199
- * exception.
200
- *
201
- * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
202
- * generated in the course of lazy stacking of FP registers.
203
- */
204
-void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure);
205
-/**
206
- * armv7m_nvic_get_pending_irq_info: return highest priority pending
207
- * exception, and whether it targets Secure state
208
- * @s: the NVIC
209
- * @pirq: set to pending exception number
210
- * @ptargets_secure: set to whether pending exception targets Secure
211
- *
212
- * This function writes the number of the highest priority pending
213
- * exception (the one which would be made active by
214
- * armv7m_nvic_acknowledge_irq()) to @pirq, and sets @ptargets_secure
215
- * to true if the current highest priority pending exception should
216
- * be taken to Secure state, false for NS.
217
- */
218
-void armv7m_nvic_get_pending_irq_info(NVICState *s, int *pirq,
219
- bool *ptargets_secure);
220
-/**
221
- * armv7m_nvic_acknowledge_irq: make highest priority pending exception active
222
- * @s: the NVIC
223
- *
224
- * Move the current highest priority pending exception from the pending
225
- * state to the active state, and update v7m.exception to indicate that
226
- * it is the exception currently being handled.
227
- */
228
-void armv7m_nvic_acknowledge_irq(NVICState *s);
229
-/**
230
- * armv7m_nvic_complete_irq: complete specified interrupt or exception
231
- * @s: the NVIC
232
- * @irq: the exception number to complete
233
- * @secure: true if this exception was secure
234
- *
235
- * Returns: -1 if the irq was not active
236
- * 1 if completing this irq brought us back to base (no active irqs)
237
- * 0 if there is still an irq active after this one was completed
238
- * (Ignoring -1, this is the same as the RETTOBASE value before completion.)
239
- */
240
-int armv7m_nvic_complete_irq(NVICState *s, int irq, bool secure);
241
-/**
242
- * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
243
- * @s: the NVIC
244
- * @irq: the exception number to mark pending
245
- * @secure: false for non-banked exceptions or for the nonsecure
246
- * version of a banked exception, true for the secure version of a banked
247
- * exception.
248
- *
249
- * Return whether an exception is "ready", i.e. whether the exception is
250
- * enabled and is configured at a priority which would allow it to
251
- * interrupt the current execution priority. This controls whether the
252
- * RDY bit for it in the FPCCR is set.
253
- */
254
-bool armv7m_nvic_get_ready_status(NVICState *s, int irq, bool secure);
255
-/**
256
- * armv7m_nvic_raw_execution_priority: return the raw execution priority
257
- * @s: the NVIC
258
- *
259
- * Returns: the raw execution priority as defined by the v8M architecture.
260
- * This is the execution priority minus the effects of AIRCR.PRIS,
261
- * and minus any PRIMASK/FAULTMASK/BASEPRI priority boosting.
262
- * (v8M ARM ARM I_PKLD.)
263
- */
264
-int armv7m_nvic_raw_execution_priority(NVICState *s);
265
-/**
266
- * armv7m_nvic_neg_prio_requested: return true if the requested execution
267
- * priority is negative for the specified security state.
268
- * @s: the NVIC
269
- * @secure: the security state to test
270
- * This corresponds to the pseudocode IsReqExecPriNeg().
271
- */
272
-#ifndef CONFIG_USER_ONLY
273
-bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure);
274
-#else
275
-static inline bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure)
276
-{
277
- return false;
278
-}
279
-#endif
280
-
281
/* Interface for defining coprocessor registers.
282
* Registers are defined in tables of arm_cp_reginfo structs
283
* which are passed to define_arm_cp_regs().
284
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
285
index XXXXXXX..XXXXXXX 100644
286
--- a/target/arm/cpu.c
287
+++ b/target/arm/cpu.c
288
@@ -XXX,XX +XXX,XX @@
289
#if !defined(CONFIG_USER_ONLY)
290
#include "hw/loader.h"
291
#include "hw/boards.h"
292
+#ifdef CONFIG_TCG
293
#include "hw/intc/armv7m_nvic.h"
294
-#endif
295
+#endif /* CONFIG_TCG */
296
+#endif /* !CONFIG_USER_ONLY */
297
#include "sysemu/tcg.h"
298
#include "sysemu/qtest.h"
299
#include "sysemu/hw_accel.h"
300
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
301
index XXXXXXX..XXXXXXX 100644
302
--- a/target/arm/cpu_tcg.c
303
+++ b/target/arm/cpu_tcg.c
304
@@ -XXX,XX +XXX,XX @@
305
#include "hw/boards.h"
306
#endif
307
#include "cpregs.h"
308
+#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
309
+#include "hw/intc/armv7m_nvic.h"
310
+#endif
311
312
313
/* Share AArch32 -cpu max features with AArch64. */
314
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
315
index XXXXXXX..XXXXXXX 100644
316
--- a/target/arm/m_helper.c
317
+++ b/target/arm/m_helper.c
318
@@ -XXX,XX +XXX,XX @@
319
#include "exec/cpu_ldst.h"
320
#include "semihosting/common-semi.h"
321
#endif
322
+#if !defined(CONFIG_USER_ONLY)
323
+#include "hw/intc/armv7m_nvic.h"
324
+#endif
325
326
static void v7m_msr_xpsr(CPUARMState *env, uint32_t mask,
327
uint32_t reg, uint32_t val)
328
--
87
--
329
2.34.1
88
2.34.1
330
331
diff view generated by jsdifflib
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
1
Convert the compare-and-branch-immediate insns CBZ and CBNZ
2
to decodetree.
2
3
3
Addresses targeting the second translation table (TTB1) in the SMMU have
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
all upper bits set. Ensure the IOMMU region covers all 64 bits.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20230512144106.3608981-15-peter.maydell@linaro.org
7
---
8
target/arm/tcg/a64.decode | 5 +++++
9
target/arm/tcg/translate-a64.c | 26 ++++++--------------------
10
2 files changed, 11 insertions(+), 20 deletions(-)
5
11
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
7
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Message-id: 20230214171921.1917916-2-jean-philippe@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/smmu-common.h | 2 --
13
hw/arm/smmu-common.c | 2 +-
14
2 files changed, 1 insertion(+), 3 deletions(-)
15
16
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/smmu-common.h
14
--- a/target/arm/tcg/a64.decode
19
+++ b/include/hw/arm/smmu-common.h
15
+++ b/target/arm/tcg/a64.decode
20
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ EXTR 0 00 100111 0 0 rm:5 0 imm:5 rn:5 rd:5 &extract sf=0
21
#define SMMU_PCI_DEVFN_MAX 256
17
22
#define SMMU_PCI_DEVFN(sid) (sid & 0xFF)
18
B 0 00101 .......................... @branch
23
19
BL 1 00101 .......................... @branch
24
-#define SMMU_MAX_VA_BITS 48
20
+
21
+%imm19 5:s19 !function=times_4
22
+&cbz rt imm sf nz
23
+
24
+CBZ sf:1 011010 nz:1 ................... rt:5 &cbz imm=%imm19
25
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/tcg/translate-a64.c
28
+++ b/target/arm/tcg/translate-a64.c
29
@@ -XXX,XX +XXX,XX @@ static bool trans_BL(DisasContext *s, arg_i *a)
30
return true;
31
}
32
33
-/* Compare and branch (immediate)
34
- * 31 30 25 24 23 5 4 0
35
- * +----+-------------+----+---------------------+--------+
36
- * | sf | 0 1 1 0 1 0 | op | imm19 | Rt |
37
- * +----+-------------+----+---------------------+--------+
38
- */
39
-static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
40
+
41
+static bool trans_CBZ(DisasContext *s, arg_cbz *a)
42
{
43
- unsigned int sf, op, rt;
44
- int64_t diff;
45
DisasLabel match;
46
TCGv_i64 tcg_cmp;
47
48
- sf = extract32(insn, 31, 1);
49
- op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */
50
- rt = extract32(insn, 0, 5);
51
- diff = sextract32(insn, 5, 19) * 4;
25
-
52
-
26
/*
53
- tcg_cmp = read_cpu_reg(s, rt, sf);
27
* Page table walk error types
54
+ tcg_cmp = read_cpu_reg(s, a->rt, a->sf);
28
*/
55
reset_btype(s);
29
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
56
30
index XXXXXXX..XXXXXXX 100644
57
match = gen_disas_label(s);
31
--- a/hw/arm/smmu-common.c
58
- tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
32
+++ b/hw/arm/smmu-common.c
59
+ tcg_gen_brcondi_i64(a->nz ? TCG_COND_NE : TCG_COND_EQ,
33
@@ -XXX,XX +XXX,XX @@ static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn)
60
tcg_cmp, 0, match.label);
34
61
gen_goto_tb(s, 0, 4);
35
memory_region_init_iommu(&sdev->iommu, sizeof(sdev->iommu),
62
set_disas_label(s, match);
36
s->mrtypename,
63
- gen_goto_tb(s, 1, diff);
37
- OBJECT(s), name, 1ULL << SMMU_MAX_VA_BITS);
64
+ gen_goto_tb(s, 1, a->imm);
38
+ OBJECT(s), name, UINT64_MAX);
65
+ return true;
39
address_space_init(&sdev->as,
66
}
40
MEMORY_REGION(&sdev->iommu), name);
67
41
trace_smmu_add_mr(name);
68
/* Test and branch (immediate)
69
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
70
static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
71
{
72
switch (extract32(insn, 25, 7)) {
73
- case 0x1a: case 0x5a: /* Compare & branch (immediate) */
74
- disas_comp_b_imm(s, insn);
75
- break;
76
case 0x1b: case 0x5b: /* Test & branch (immediate) */
77
disas_test_b_imm(s, insn);
78
break;
42
--
79
--
43
2.34.1
80
2.34.1
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Convert the test-and-branch-immediate insns TBZ and TBNZ
2
to decodetree.
2
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20230512144106.3608981-16-peter.maydell@linaro.org
5
Message-id: 20230206223502.25122-8-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
target/arm/cpu.h | 3 ++-
8
target/arm/tcg/a64.decode | 6 ++++++
9
1 file changed, 2 insertions(+), 1 deletion(-)
9
target/arm/tcg/translate-a64.c | 25 +++++--------------------
10
2 files changed, 11 insertions(+), 20 deletions(-)
10
11
11
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
12
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu.h
14
--- a/target/arm/tcg/a64.decode
14
+++ b/target/arm/cpu.h
15
+++ b/target/arm/tcg/a64.decode
15
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
16
@@ -XXX,XX +XXX,XX @@ BL 1 00101 .......................... @branch
16
17
&cbz rt imm sf nz
17
void *nvic;
18
18
const struct arm_boot_info *boot_info;
19
CBZ sf:1 011010 nz:1 ................... rt:5 &cbz imm=%imm19
19
+#if !defined(CONFIG_USER_ONLY)
20
+
20
/* Store GICv3CPUState to access from this struct */
21
+%imm14 5:s14 !function=times_4
21
void *gicv3state;
22
+%imm31_19 31:1 19:5
22
-#if defined(CONFIG_USER_ONLY)
23
+&tbz rt imm nz bitpos
23
+#else /* CONFIG_USER_ONLY */
24
+
24
/* For usermode syscall translation. */
25
+TBZ . 011011 nz:1 ..... .............. rt:5 &tbz imm=%imm14 bitpos=%imm31_19
25
bool eabi;
26
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
26
#endif /* CONFIG_USER_ONLY */
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/tcg/translate-a64.c
29
+++ b/target/arm/tcg/translate-a64.c
30
@@ -XXX,XX +XXX,XX @@ static bool trans_CBZ(DisasContext *s, arg_cbz *a)
31
return true;
32
}
33
34
-/* Test and branch (immediate)
35
- * 31 30 25 24 23 19 18 5 4 0
36
- * +----+-------------+----+-------+-------------+------+
37
- * | b5 | 0 1 1 0 1 1 | op | b40 | imm14 | Rt |
38
- * +----+-------------+----+-------+-------------+------+
39
- */
40
-static void disas_test_b_imm(DisasContext *s, uint32_t insn)
41
+static bool trans_TBZ(DisasContext *s, arg_tbz *a)
42
{
43
- unsigned int bit_pos, op, rt;
44
- int64_t diff;
45
DisasLabel match;
46
TCGv_i64 tcg_cmp;
47
48
- bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
49
- op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */
50
- diff = sextract32(insn, 5, 14) * 4;
51
- rt = extract32(insn, 0, 5);
52
-
53
tcg_cmp = tcg_temp_new_i64();
54
- tcg_gen_andi_i64(tcg_cmp, cpu_reg(s, rt), (1ULL << bit_pos));
55
+ tcg_gen_andi_i64(tcg_cmp, cpu_reg(s, a->rt), 1ULL << a->bitpos);
56
57
reset_btype(s);
58
59
match = gen_disas_label(s);
60
- tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
61
+ tcg_gen_brcondi_i64(a->nz ? TCG_COND_NE : TCG_COND_EQ,
62
tcg_cmp, 0, match.label);
63
gen_goto_tb(s, 0, 4);
64
set_disas_label(s, match);
65
- gen_goto_tb(s, 1, diff);
66
+ gen_goto_tb(s, 1, a->imm);
67
+ return true;
68
}
69
70
/* Conditional branch (immediate)
71
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
72
static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
73
{
74
switch (extract32(insn, 25, 7)) {
75
- case 0x1b: case 0x5b: /* Test & branch (immediate) */
76
- disas_test_b_imm(s, insn);
77
- break;
78
case 0x2a: /* Conditional branch (immediate) */
79
disas_cond_b_imm(s, insn);
80
break;
27
--
81
--
28
2.34.1
82
2.34.1
29
30
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Convert the immediate conditional branch insn B.cond to
2
decodetree.
2
3
3
Although the 'eabi' field is only used in user emulation where
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
CPU reset doesn't occur, it doesn't belong to the area to reset.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Move it after the 'end_reset_fields' for consistency.
6
Message-id: 20230512144106.3608981-17-peter.maydell@linaro.org
7
---
8
target/arm/tcg/a64.decode | 2 ++
9
target/arm/tcg/translate-a64.c | 30 ++++++------------------------
10
2 files changed, 8 insertions(+), 24 deletions(-)
6
11
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20230206223502.25122-7-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 9 ++++-----
13
1 file changed, 4 insertions(+), 5 deletions(-)
14
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
14
--- a/target/arm/tcg/a64.decode
18
+++ b/target/arm/cpu.h
15
+++ b/target/arm/tcg/a64.decode
19
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
16
@@ -XXX,XX +XXX,XX @@ CBZ sf:1 011010 nz:1 ................... rt:5 &cbz imm=%imm19
20
ARMVectorReg zarray[ARM_MAX_VQ * 16];
17
&tbz rt imm nz bitpos
21
#endif
18
22
19
TBZ . 011011 nz:1 ..... .............. rt:5 &tbz imm=%imm14 bitpos=%imm31_19
23
-#if defined(CONFIG_USER_ONLY)
20
+
24
- /* For usermode syscall translation. */
21
+B_cond 0101010 0 ................... 0 cond:4 imm=%imm19
25
- bool eabi;
22
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
26
-#endif
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/tcg/translate-a64.c
25
+++ b/target/arm/tcg/translate-a64.c
26
@@ -XXX,XX +XXX,XX @@ static bool trans_TBZ(DisasContext *s, arg_tbz *a)
27
return true;
28
}
29
30
-/* Conditional branch (immediate)
31
- * 31 25 24 23 5 4 3 0
32
- * +---------------+----+---------------------+----+------+
33
- * | 0 1 0 1 0 1 0 | o1 | imm19 | o0 | cond |
34
- * +---------------+----+---------------------+----+------+
35
- */
36
-static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
37
+static bool trans_B_cond(DisasContext *s, arg_B_cond *a)
38
{
39
- unsigned int cond;
40
- int64_t diff;
27
-
41
-
28
struct CPUBreakpoint *cpu_breakpoint[16];
42
- if ((insn & (1 << 4)) || (insn & (1 << 24))) {
29
struct CPUWatchpoint *cpu_watchpoint[16];
43
- unallocated_encoding(s);
30
44
- return;
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
45
- }
32
const struct arm_boot_info *boot_info;
46
- diff = sextract32(insn, 5, 19) * 4;
33
/* Store GICv3CPUState to access from this struct */
47
- cond = extract32(insn, 0, 4);
34
void *gicv3state;
48
-
35
+#if defined(CONFIG_USER_ONLY)
49
reset_btype(s);
36
+ /* For usermode syscall translation. */
50
- if (cond < 0x0e) {
37
+ bool eabi;
51
+ if (a->cond < 0x0e) {
38
+#endif /* CONFIG_USER_ONLY */
52
/* genuinely conditional branches */
39
53
DisasLabel match = gen_disas_label(s);
40
#ifdef TARGET_TAGGED_ADDRESSES
54
- arm_gen_test_cc(cond, match.label);
41
/* Linux syscall tagged address support */
55
+ arm_gen_test_cc(a->cond, match.label);
56
gen_goto_tb(s, 0, 4);
57
set_disas_label(s, match);
58
- gen_goto_tb(s, 1, diff);
59
+ gen_goto_tb(s, 1, a->imm);
60
} else {
61
/* 0xe and 0xf are both "always" conditions */
62
- gen_goto_tb(s, 0, diff);
63
+ gen_goto_tb(s, 0, a->imm);
64
}
65
+ return true;
66
}
67
68
/* HINT instruction group, including various allocated HINTs */
69
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
70
static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
71
{
72
switch (extract32(insn, 25, 7)) {
73
- case 0x2a: /* Conditional branch (immediate) */
74
- disas_cond_b_imm(s, insn);
75
- break;
76
case 0x6a: /* Exception generation / System */
77
if (insn & (1 << 24)) {
78
if (extract32(insn, 22, 2) == 0) {
42
--
79
--
43
2.34.1
80
2.34.1
44
45
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
Convert the simple (non-pointer-auth) BR, BLR and RET insns
2
to decodetree.
2
3
3
Nuvoton's PSPI is a general purpose SPI module which enables
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
connections to SPI-based peripheral devices.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20230512144106.3608981-18-peter.maydell@linaro.org
7
---
8
target/arm/tcg/a64.decode | 5 ++++
9
target/arm/tcg/translate-a64.c | 55 ++++++++++++++++++++++++++++++----
10
2 files changed, 54 insertions(+), 6 deletions(-)
5
11
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
7
Reviewed-by: Chris Rauer <crauer@google.com>
8
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
9
Message-id: 20230208235433.3989937-3-wuhaotsh@google.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
MAINTAINERS | 6 +-
13
include/hw/ssi/npcm_pspi.h | 53 +++++++++
14
hw/ssi/npcm_pspi.c | 221 +++++++++++++++++++++++++++++++++++++
15
hw/ssi/meson.build | 2 +-
16
hw/ssi/trace-events | 5 +
17
5 files changed, 283 insertions(+), 4 deletions(-)
18
create mode 100644 include/hw/ssi/npcm_pspi.h
19
create mode 100644 hw/ssi/npcm_pspi.c
20
21
diff --git a/MAINTAINERS b/MAINTAINERS
22
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
23
--- a/MAINTAINERS
14
--- a/target/arm/tcg/a64.decode
24
+++ b/MAINTAINERS
15
+++ b/target/arm/tcg/a64.decode
25
@@ -XXX,XX +XXX,XX @@ M: Tyrone Ting <kfting@nuvoton.com>
26
M: Hao Wu <wuhaotsh@google.com>
27
L: qemu-arm@nongnu.org
28
S: Supported
29
-F: hw/*/npcm7xx*
30
-F: include/hw/*/npcm7xx*
31
-F: tests/qtest/npcm7xx*
32
+F: hw/*/npcm*
33
+F: include/hw/*/npcm*
34
+F: tests/qtest/npcm*
35
F: pc-bios/npcm7xx_bootrom.bin
36
F: roms/vbootrom
37
F: docs/system/arm/nuvoton.rst
38
diff --git a/include/hw/ssi/npcm_pspi.h b/include/hw/ssi/npcm_pspi.h
39
new file mode 100644
40
index XXXXXXX..XXXXXXX
41
--- /dev/null
42
+++ b/include/hw/ssi/npcm_pspi.h
43
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
44
+/*
17
# This file is processed by scripts/decodetree.py
45
+ * Nuvoton Peripheral SPI Module
18
#
46
+ *
19
47
+ * Copyright 2023 Google LLC
20
+&r rn
48
+ *
21
&ri rd imm
49
+ * This program is free software; you can redistribute it and/or modify it
22
&rri_sf rd rn imm sf
50
+ * under the terms of the GNU General Public License as published by the
23
&i imm
51
+ * Free Software Foundation; either version 2 of the License, or
24
@@ -XXX,XX +XXX,XX @@ CBZ sf:1 011010 nz:1 ................... rt:5 &cbz imm=%imm19
52
+ * (at your option) any later version.
25
TBZ . 011011 nz:1 ..... .............. rt:5 &tbz imm=%imm14 bitpos=%imm31_19
53
+ *
26
54
+ * This program is distributed in the hope that it will be useful, but WITHOUT
27
B_cond 0101010 0 ................... 0 cond:4 imm=%imm19
55
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
56
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
57
+ * for more details.
58
+ */
59
+#ifndef NPCM_PSPI_H
60
+#define NPCM_PSPI_H
61
+
28
+
62
+#include "hw/ssi/ssi.h"
29
+BR 1101011 0000 11111 000000 rn:5 00000 &r
63
+#include "hw/sysbus.h"
30
+BLR 1101011 0001 11111 000000 rn:5 00000 &r
64
+
31
+RET 1101011 0010 11111 000000 rn:5 00000 &r
65
+/*
32
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
66
+ * Number of registers in our device state structure. Don't change this without
33
index XXXXXXX..XXXXXXX 100644
67
+ * incrementing the version_id in the vmstate.
34
--- a/target/arm/tcg/translate-a64.c
68
+ */
35
+++ b/target/arm/tcg/translate-a64.c
69
+#define NPCM_PSPI_NR_REGS 3
36
@@ -XXX,XX +XXX,XX @@ static bool trans_B_cond(DisasContext *s, arg_B_cond *a)
70
+
37
return true;
71
+/**
38
}
72
+ * NPCMPSPIState - Device state for one Flash Interface Unit.
39
73
+ * @parent: System bus device.
40
+static void set_btype_for_br(DisasContext *s, int rn)
74
+ * @mmio: Memory region for register access.
75
+ * @spi: The SPI bus mastered by this controller.
76
+ * @regs: Register contents.
77
+ * @irq: The interrupt request queue for this module.
78
+ *
79
+ * Each PSPI has a shared bank of registers, and controls up to four chip
80
+ * selects. Each chip select has a dedicated memory region which may be used to
81
+ * read and write the flash connected to that chip select as if it were memory.
82
+ */
83
+typedef struct NPCMPSPIState {
84
+ SysBusDevice parent;
85
+
86
+ MemoryRegion mmio;
87
+
88
+ SSIBus *spi;
89
+ uint16_t regs[NPCM_PSPI_NR_REGS];
90
+ qemu_irq irq;
91
+} NPCMPSPIState;
92
+
93
+#define TYPE_NPCM_PSPI "npcm-pspi"
94
+OBJECT_DECLARE_SIMPLE_TYPE(NPCMPSPIState, NPCM_PSPI)
95
+
96
+#endif /* NPCM_PSPI_H */
97
diff --git a/hw/ssi/npcm_pspi.c b/hw/ssi/npcm_pspi.c
98
new file mode 100644
99
index XXXXXXX..XXXXXXX
100
--- /dev/null
101
+++ b/hw/ssi/npcm_pspi.c
102
@@ -XXX,XX +XXX,XX @@
103
+/*
104
+ * Nuvoton NPCM Peripheral SPI Module (PSPI)
105
+ *
106
+ * Copyright 2023 Google LLC
107
+ *
108
+ * This program is free software; you can redistribute it and/or modify it
109
+ * under the terms of the GNU General Public License as published by the
110
+ * Free Software Foundation; either version 2 of the License, or
111
+ * (at your option) any later version.
112
+ *
113
+ * This program is distributed in the hope that it will be useful, but WITHOUT
114
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
115
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
116
+ * for more details.
117
+ */
118
+
119
+#include "qemu/osdep.h"
120
+
121
+#include "hw/irq.h"
122
+#include "hw/registerfields.h"
123
+#include "hw/ssi/npcm_pspi.h"
124
+#include "migration/vmstate.h"
125
+#include "qapi/error.h"
126
+#include "qemu/error-report.h"
127
+#include "qemu/log.h"
128
+#include "qemu/module.h"
129
+#include "qemu/units.h"
130
+
131
+#include "trace.h"
132
+
133
+REG16(PSPI_DATA, 0x0)
134
+REG16(PSPI_CTL1, 0x2)
135
+ FIELD(PSPI_CTL1, SPIEN, 0, 1)
136
+ FIELD(PSPI_CTL1, MOD, 2, 1)
137
+ FIELD(PSPI_CTL1, EIR, 5, 1)
138
+ FIELD(PSPI_CTL1, EIW, 6, 1)
139
+ FIELD(PSPI_CTL1, SCM, 7, 1)
140
+ FIELD(PSPI_CTL1, SCIDL, 8, 1)
141
+ FIELD(PSPI_CTL1, SCDV, 9, 7)
142
+REG16(PSPI_STAT, 0x4)
143
+ FIELD(PSPI_STAT, BSY, 0, 1)
144
+ FIELD(PSPI_STAT, RBF, 1, 1)
145
+
146
+static void npcm_pspi_update_irq(NPCMPSPIState *s)
147
+{
41
+{
148
+ int level = 0;
42
+ if (dc_isar_feature(aa64_bti, s)) {
149
+
43
+ /* BR to {x16,x17} or !guard -> 1, else 3. */
150
+ /* Only fire IRQ when the module is enabled. */
44
+ set_btype(s, rn == 16 || rn == 17 || !s->guarded_page ? 1 : 3);
151
+ if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, SPIEN)) {
152
+ /* Update interrupt as BSY is cleared. */
153
+ if ((!FIELD_EX16(s->regs[R_PSPI_STAT], PSPI_STAT, BSY)) &&
154
+ FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, EIW)) {
155
+ level = 1;
156
+ }
157
+
158
+ /* Update interrupt as RBF is set. */
159
+ if (FIELD_EX16(s->regs[R_PSPI_STAT], PSPI_STAT, RBF) &&
160
+ FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, EIR)) {
161
+ level = 1;
162
+ }
163
+ }
45
+ }
164
+ qemu_set_irq(s->irq, level);
165
+}
46
+}
166
+
47
+
167
+static uint16_t npcm_pspi_read_data(NPCMPSPIState *s)
48
+static void set_btype_for_blr(DisasContext *s)
168
+{
49
+{
169
+ uint16_t value = s->regs[R_PSPI_DATA];
50
+ if (dc_isar_feature(aa64_bti, s)) {
170
+
51
+ /* BLR sets BTYPE to 2, regardless of source guarded page. */
171
+ /* Clear stat bits as the value are read out. */
52
+ set_btype(s, 2);
172
+ s->regs[R_PSPI_STAT] = 0;
53
+ }
173
+
174
+ return value;
175
+}
54
+}
176
+
55
+
177
+static void npcm_pspi_write_data(NPCMPSPIState *s, uint16_t data)
56
+static bool trans_BR(DisasContext *s, arg_r *a)
178
+{
57
+{
179
+ uint16_t value = 0;
58
+ gen_a64_set_pc(s, cpu_reg(s, a->rn));
180
+
59
+ set_btype_for_br(s, a->rn);
181
+ if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, MOD)) {
60
+ s->base.is_jmp = DISAS_JUMP;
182
+ value = ssi_transfer(s->spi, extract16(data, 8, 8)) << 8;
61
+ return true;
183
+ }
184
+ value |= ssi_transfer(s->spi, extract16(data, 0, 8));
185
+ s->regs[R_PSPI_DATA] = value;
186
+
187
+ /* Mark data as available */
188
+ s->regs[R_PSPI_STAT] = R_PSPI_STAT_BSY_MASK | R_PSPI_STAT_RBF_MASK;
189
+}
62
+}
190
+
63
+
191
+/* Control register read handler. */
64
+static bool trans_BLR(DisasContext *s, arg_r *a)
192
+static uint64_t npcm_pspi_ctrl_read(void *opaque, hwaddr addr,
193
+ unsigned int size)
194
+{
65
+{
195
+ NPCMPSPIState *s = opaque;
66
+ TCGv_i64 dst = cpu_reg(s, a->rn);
196
+ uint16_t value;
67
+ TCGv_i64 lr = cpu_reg(s, 30);
197
+
68
+ if (dst == lr) {
198
+ switch (addr) {
69
+ TCGv_i64 tmp = tcg_temp_new_i64();
199
+ case A_PSPI_DATA:
70
+ tcg_gen_mov_i64(tmp, dst);
200
+ value = npcm_pspi_read_data(s);
71
+ dst = tmp;
201
+ break;
202
+
203
+ case A_PSPI_CTL1:
204
+ value = s->regs[R_PSPI_CTL1];
205
+ break;
206
+
207
+ case A_PSPI_STAT:
208
+ value = s->regs[R_PSPI_STAT];
209
+ break;
210
+
211
+ default:
212
+ qemu_log_mask(LOG_GUEST_ERROR,
213
+ "%s: write to invalid offset 0x%" PRIx64 "\n",
214
+ DEVICE(s)->canonical_path, addr);
215
+ return 0;
216
+ }
72
+ }
217
+ trace_npcm_pspi_ctrl_read(DEVICE(s)->canonical_path, addr, value);
73
+ gen_pc_plus_diff(s, lr, curr_insn_len(s));
218
+ npcm_pspi_update_irq(s);
74
+ gen_a64_set_pc(s, dst);
219
+
75
+ set_btype_for_blr(s);
220
+ return value;
76
+ s->base.is_jmp = DISAS_JUMP;
77
+ return true;
221
+}
78
+}
222
+
79
+
223
+/* Control register write handler. */
80
+static bool trans_RET(DisasContext *s, arg_r *a)
224
+static void npcm_pspi_ctrl_write(void *opaque, hwaddr addr, uint64_t v,
225
+ unsigned int size)
226
+{
81
+{
227
+ NPCMPSPIState *s = opaque;
82
+ gen_a64_set_pc(s, cpu_reg(s, a->rn));
228
+ uint16_t value = v;
83
+ s->base.is_jmp = DISAS_JUMP;
229
+
84
+ return true;
230
+ trace_npcm_pspi_ctrl_write(DEVICE(s)->canonical_path, addr, value);
231
+
232
+ switch (addr) {
233
+ case A_PSPI_DATA:
234
+ npcm_pspi_write_data(s, value);
235
+ break;
236
+
237
+ case A_PSPI_CTL1:
238
+ s->regs[R_PSPI_CTL1] = value;
239
+ break;
240
+
241
+ case A_PSPI_STAT:
242
+ qemu_log_mask(LOG_GUEST_ERROR,
243
+ "%s: write to read-only register PSPI_STAT: 0x%08"
244
+ PRIx64 "\n", DEVICE(s)->canonical_path, v);
245
+ break;
246
+
247
+ default:
248
+ qemu_log_mask(LOG_GUEST_ERROR,
249
+ "%s: write to invalid offset 0x%" PRIx64 "\n",
250
+ DEVICE(s)->canonical_path, addr);
251
+ return;
252
+ }
253
+ npcm_pspi_update_irq(s);
254
+}
85
+}
255
+
86
+
256
+static const MemoryRegionOps npcm_pspi_ctrl_ops = {
87
/* HINT instruction group, including various allocated HINTs */
257
+ .read = npcm_pspi_ctrl_read,
88
static void handle_hint(DisasContext *s, uint32_t insn,
258
+ .write = npcm_pspi_ctrl_write,
89
unsigned int op1, unsigned int op2, unsigned int crm)
259
+ .endianness = DEVICE_LITTLE_ENDIAN,
90
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
260
+ .valid = {
91
btype_mod = opc;
261
+ .min_access_size = 1,
92
switch (op3) {
262
+ .max_access_size = 2,
93
case 0:
263
+ .unaligned = false,
94
- /* BR, BLR, RET */
264
+ },
95
- if (op4 != 0) {
265
+ .impl = {
96
- goto do_unallocated;
266
+ .min_access_size = 2,
97
- }
267
+ .max_access_size = 2,
98
- dst = cpu_reg(s, rn);
268
+ .unaligned = false,
99
- break;
269
+ },
100
+ /* BR, BLR, RET : handled in decodetree */
270
+};
101
+ goto do_unallocated;
271
+
102
272
+static void npcm_pspi_enter_reset(Object *obj, ResetType type)
103
case 2:
273
+{
104
case 3:
274
+ NPCMPSPIState *s = NPCM_PSPI(obj);
275
+
276
+ trace_npcm_pspi_enter_reset(DEVICE(obj)->canonical_path, type);
277
+ memset(s->regs, 0, sizeof(s->regs));
278
+}
279
+
280
+static void npcm_pspi_realize(DeviceState *dev, Error **errp)
281
+{
282
+ NPCMPSPIState *s = NPCM_PSPI(dev);
283
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
284
+ Object *obj = OBJECT(dev);
285
+
286
+ s->spi = ssi_create_bus(dev, "pspi");
287
+ memory_region_init_io(&s->mmio, obj, &npcm_pspi_ctrl_ops, s,
288
+ "mmio", 4 * KiB);
289
+ sysbus_init_mmio(sbd, &s->mmio);
290
+ sysbus_init_irq(sbd, &s->irq);
291
+}
292
+
293
+static const VMStateDescription vmstate_npcm_pspi = {
294
+ .name = "npcm-pspi",
295
+ .version_id = 0,
296
+ .minimum_version_id = 0,
297
+ .fields = (VMStateField[]) {
298
+ VMSTATE_UINT16_ARRAY(regs, NPCMPSPIState, NPCM_PSPI_NR_REGS),
299
+ VMSTATE_END_OF_LIST(),
300
+ },
301
+};
302
+
303
+
304
+static void npcm_pspi_class_init(ObjectClass *klass, void *data)
305
+{
306
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
307
+ DeviceClass *dc = DEVICE_CLASS(klass);
308
+
309
+ dc->desc = "NPCM Peripheral SPI Module";
310
+ dc->realize = npcm_pspi_realize;
311
+ dc->vmsd = &vmstate_npcm_pspi;
312
+ rc->phases.enter = npcm_pspi_enter_reset;
313
+}
314
+
315
+static const TypeInfo npcm_pspi_types[] = {
316
+ {
317
+ .name = TYPE_NPCM_PSPI,
318
+ .parent = TYPE_SYS_BUS_DEVICE,
319
+ .instance_size = sizeof(NPCMPSPIState),
320
+ .class_init = npcm_pspi_class_init,
321
+ },
322
+};
323
+DEFINE_TYPES(npcm_pspi_types);
324
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
325
index XXXXXXX..XXXXXXX 100644
326
--- a/hw/ssi/meson.build
327
+++ b/hw/ssi/meson.build
328
@@ -XXX,XX +XXX,XX @@
329
softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_smc.c'))
330
softmmu_ss.add(when: 'CONFIG_MSF2', if_true: files('mss-spi.c'))
331
-softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c'))
332
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_fiu.c', 'npcm_pspi.c'))
333
softmmu_ss.add(when: 'CONFIG_PL022', if_true: files('pl022.c'))
334
softmmu_ss.add(when: 'CONFIG_SIFIVE_SPI', if_true: files('sifive_spi.c'))
335
softmmu_ss.add(when: 'CONFIG_SSI', if_true: files('ssi.c'))
336
diff --git a/hw/ssi/trace-events b/hw/ssi/trace-events
337
index XXXXXXX..XXXXXXX 100644
338
--- a/hw/ssi/trace-events
339
+++ b/hw/ssi/trace-events
340
@@ -XXX,XX +XXX,XX @@ npcm7xx_fiu_ctrl_write(const char *id, uint64_t addr, uint32_t data) "%s offset:
341
npcm7xx_fiu_flash_read(const char *id, int cs, uint64_t addr, unsigned int size, uint64_t value) "%s[%d] offset: 0x%08" PRIx64 " size: %u value: 0x%" PRIx64
342
npcm7xx_fiu_flash_write(const char *id, unsigned cs, uint64_t addr, unsigned int size, uint64_t value) "%s[%d] offset: 0x%08" PRIx64 " size: %u value: 0x%" PRIx64
343
344
+# npcm_pspi.c
345
+npcm_pspi_enter_reset(const char *id, int reset_type) "%s reset type: %d"
346
+npcm_pspi_ctrl_read(const char *id, uint64_t addr, uint16_t data) "%s offset: 0x%03" PRIx64 " value: 0x%04" PRIx16
347
+npcm_pspi_ctrl_write(const char *id, uint64_t addr, uint16_t data) "%s offset: 0x%03" PRIx64 " value: 0x%04" PRIx16
348
+
349
# ibex_spi_host.c
350
351
ibex_spi_host_reset(const char *msg) "%s"
352
--
105
--
353
2.34.1
106
2.34.1
diff view generated by jsdifflib
1
From: Fabiano Rosas <farosas@suse.de>
1
Convert the single-register pointer-authentication variants of BR,
2
BLR, RET to decodetree. (BRAA/BLRAA are in a different branch of
3
the legacy decoder and will be dealt with in the next commit.)
2
4
3
Signed-off-by: Fabiano Rosas <farosas@suse.de>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Acked-by: Thomas Huth <thuth@redhat.com>
7
Message-id: 20230512144106.3608981-19-peter.maydell@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
---
8
tests/qtest/arm-cpu-features.c | 28 ++++++++++++++++++----------
9
target/arm/tcg/a64.decode | 7 ++
9
1 file changed, 18 insertions(+), 10 deletions(-)
10
target/arm/tcg/translate-a64.c | 132 +++++++++++++++++++--------------
11
2 files changed, 84 insertions(+), 55 deletions(-)
10
12
11
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
13
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/tests/qtest/arm-cpu-features.c
15
--- a/target/arm/tcg/a64.decode
14
+++ b/tests/qtest/arm-cpu-features.c
16
+++ b/target/arm/tcg/a64.decode
15
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ B_cond 0101010 0 ................... 0 cond:4 imm=%imm19
16
#define SVE_MAX_VQ 16
18
BR 1101011 0000 11111 000000 rn:5 00000 &r
17
19
BLR 1101011 0001 11111 000000 rn:5 00000 &r
18
#define MACHINE "-machine virt,gic-version=max -accel tcg "
20
RET 1101011 0010 11111 000000 rn:5 00000 &r
19
-#define MACHINE_KVM "-machine virt,gic-version=max -accel kvm -accel tcg "
21
+
20
+#define MACHINE_KVM "-machine virt,gic-version=max -accel kvm "
22
+&braz rn m
21
#define QUERY_HEAD "{ 'execute': 'query-cpu-model-expansion', " \
23
+BRAZ 1101011 0000 11111 00001 m:1 rn:5 11111 &braz # BRAAZ, BRABZ
22
" 'arguments': { 'type': 'full', "
24
+BLRAZ 1101011 0001 11111 00001 m:1 rn:5 11111 &braz # BLRAAZ, BLRABZ
23
#define QUERY_TAIL "}}"
25
+
24
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
26
+&reta m
25
{
27
+RETA 1101011 0010 11111 00001 m:1 11111 11111 &reta # RETAA, RETAB
26
g_test_init(&argc, &argv, NULL);
28
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
27
29
index XXXXXXX..XXXXXXX 100644
28
- qtest_add_data_func("/arm/query-cpu-model-expansion",
30
--- a/target/arm/tcg/translate-a64.c
29
- NULL, test_query_cpu_model_expansion);
31
+++ b/target/arm/tcg/translate-a64.c
30
+ if (qtest_has_accel("tcg")) {
32
@@ -XXX,XX +XXX,XX @@ static bool trans_RET(DisasContext *s, arg_r *a)
31
+ qtest_add_data_func("/arm/query-cpu-model-expansion",
33
return true;
32
+ NULL, test_query_cpu_model_expansion);
34
}
35
36
+static TCGv_i64 auth_branch_target(DisasContext *s, TCGv_i64 dst,
37
+ TCGv_i64 modifier, bool use_key_a)
38
+{
39
+ TCGv_i64 truedst;
40
+ /*
41
+ * Return the branch target for a BRAA/RETA/etc, which is either
42
+ * just the destination dst, or that value with the pauth check
43
+ * done and the code removed from the high bits.
44
+ */
45
+ if (!s->pauth_active) {
46
+ return dst;
33
+ }
47
+ }
34
+
48
+
35
+ if (!g_str_equal(qtest_get_arch(), "aarch64")) {
49
+ truedst = tcg_temp_new_i64();
36
+ goto out;
50
+ if (use_key_a) {
51
+ gen_helper_autia(truedst, cpu_env, dst, modifier);
52
+ } else {
53
+ gen_helper_autib(truedst, cpu_env, dst, modifier);
37
+ }
54
+ }
38
55
+ return truedst;
39
/*
56
+}
40
* For now we only run KVM specific tests with AArch64 QEMU in
57
+
41
* order avoid attempting to run an AArch32 QEMU with KVM on
58
+static bool trans_BRAZ(DisasContext *s, arg_braz *a)
42
* AArch64 hosts. That won't work and isn't easy to detect.
59
+{
43
*/
60
+ TCGv_i64 dst;
44
- if (g_str_equal(qtest_get_arch(), "aarch64") && qtest_has_accel("kvm")) {
61
+
45
+ if (qtest_has_accel("kvm")) {
62
+ if (!dc_isar_feature(aa64_pauth, s)) {
46
/*
63
+ return false;
47
* This tests target the 'host' CPU type, so register it only if
48
* KVM is available.
49
*/
50
qtest_add_data_func("/arm/kvm/query-cpu-model-expansion",
51
NULL, test_query_cpu_model_expansion_kvm);
52
- }
53
54
- if (g_str_equal(qtest_get_arch(), "aarch64")) {
55
- qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-max-vq-8",
56
- NULL, sve_tests_sve_max_vq_8);
57
- qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-off",
58
- NULL, sve_tests_sve_off);
59
qtest_add_data_func("/arm/kvm/query-cpu-model-expansion/sve-off",
60
NULL, sve_tests_sve_off_kvm);
61
}
62
63
+ if (qtest_has_accel("tcg")) {
64
+ qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-max-vq-8",
65
+ NULL, sve_tests_sve_max_vq_8);
66
+ qtest_add_data_func("/arm/max/query-cpu-model-expansion/sve-off",
67
+ NULL, sve_tests_sve_off);
68
+ }
64
+ }
69
+
65
+
70
+out:
66
+ dst = auth_branch_target(s, cpu_reg(s, a->rn), tcg_constant_i64(0), !a->m);
71
return g_test_run();
67
+ gen_a64_set_pc(s, dst);
72
}
68
+ set_btype_for_br(s, a->rn);
69
+ s->base.is_jmp = DISAS_JUMP;
70
+ return true;
71
+}
72
+
73
+static bool trans_BLRAZ(DisasContext *s, arg_braz *a)
74
+{
75
+ TCGv_i64 dst, lr;
76
+
77
+ if (!dc_isar_feature(aa64_pauth, s)) {
78
+ return false;
79
+ }
80
+
81
+ dst = auth_branch_target(s, cpu_reg(s, a->rn), tcg_constant_i64(0), !a->m);
82
+ lr = cpu_reg(s, 30);
83
+ if (dst == lr) {
84
+ TCGv_i64 tmp = tcg_temp_new_i64();
85
+ tcg_gen_mov_i64(tmp, dst);
86
+ dst = tmp;
87
+ }
88
+ gen_pc_plus_diff(s, lr, curr_insn_len(s));
89
+ gen_a64_set_pc(s, dst);
90
+ set_btype_for_blr(s);
91
+ s->base.is_jmp = DISAS_JUMP;
92
+ return true;
93
+}
94
+
95
+static bool trans_RETA(DisasContext *s, arg_reta *a)
96
+{
97
+ TCGv_i64 dst;
98
+
99
+ dst = auth_branch_target(s, cpu_reg(s, 30), cpu_X[31], !a->m);
100
+ gen_a64_set_pc(s, dst);
101
+ s->base.is_jmp = DISAS_JUMP;
102
+ return true;
103
+}
104
+
105
/* HINT instruction group, including various allocated HINTs */
106
static void handle_hint(DisasContext *s, uint32_t insn,
107
unsigned int op1, unsigned int op2, unsigned int crm)
108
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
109
}
110
111
switch (opc) {
112
- case 0: /* BR */
113
- case 1: /* BLR */
114
- case 2: /* RET */
115
- btype_mod = opc;
116
- switch (op3) {
117
- case 0:
118
- /* BR, BLR, RET : handled in decodetree */
119
- goto do_unallocated;
120
-
121
- case 2:
122
- case 3:
123
- if (!dc_isar_feature(aa64_pauth, s)) {
124
- goto do_unallocated;
125
- }
126
- if (opc == 2) {
127
- /* RETAA, RETAB */
128
- if (rn != 0x1f || op4 != 0x1f) {
129
- goto do_unallocated;
130
- }
131
- rn = 30;
132
- modifier = cpu_X[31];
133
- } else {
134
- /* BRAAZ, BRABZ, BLRAAZ, BLRABZ */
135
- if (op4 != 0x1f) {
136
- goto do_unallocated;
137
- }
138
- modifier = tcg_constant_i64(0);
139
- }
140
- if (s->pauth_active) {
141
- dst = tcg_temp_new_i64();
142
- if (op3 == 2) {
143
- gen_helper_autia(dst, cpu_env, cpu_reg(s, rn), modifier);
144
- } else {
145
- gen_helper_autib(dst, cpu_env, cpu_reg(s, rn), modifier);
146
- }
147
- } else {
148
- dst = cpu_reg(s, rn);
149
- }
150
- break;
151
-
152
- default:
153
- goto do_unallocated;
154
- }
155
- /* BLR also needs to load return address */
156
- if (opc == 1) {
157
- TCGv_i64 lr = cpu_reg(s, 30);
158
- if (dst == lr) {
159
- TCGv_i64 tmp = tcg_temp_new_i64();
160
- tcg_gen_mov_i64(tmp, dst);
161
- dst = tmp;
162
- }
163
- gen_pc_plus_diff(s, lr, curr_insn_len(s));
164
- }
165
- gen_a64_set_pc(s, dst);
166
- break;
167
+ case 0:
168
+ case 1:
169
+ case 2:
170
+ /*
171
+ * BR, BLR, RET, RETAA, RETAB, BRAAZ, BRABZ, BLRAAZ, BLRABZ:
172
+ * handled in decodetree
173
+ */
174
+ goto do_unallocated;
175
176
case 8: /* BRAA */
177
case 9: /* BLRAA */
73
--
178
--
74
2.34.1
179
2.34.1
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Convert the last four BR-with-pointer-auth insns to decodetree.
2
The remaining cases in the outer switch in disas_uncond_b_reg()
3
all return early rather than leaving the case statement, so we
4
can delete the now-unused code at the end of that function.
2
5
3
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20230206223502.25122-3-philmd@linaro.org
8
Message-id: 20230512144106.3608981-20-peter.maydell@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
---
9
target/arm/m_helper.c | 11 ++++++++---
10
target/arm/tcg/a64.decode | 4 ++
10
1 file changed, 8 insertions(+), 3 deletions(-)
11
target/arm/tcg/translate-a64.c | 97 ++++++++++++++--------------------
12
2 files changed, 43 insertions(+), 58 deletions(-)
11
13
12
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
14
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/m_helper.c
16
--- a/target/arm/tcg/a64.decode
15
+++ b/target/arm/m_helper.c
17
+++ b/target/arm/tcg/a64.decode
16
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
18
@@ -XXX,XX +XXX,XX @@ BLRAZ 1101011 0001 11111 00001 m:1 rn:5 11111 &braz # BLRAAZ, BLRABZ
17
return 0;
19
20
&reta m
21
RETA 1101011 0010 11111 00001 m:1 11111 11111 &reta # RETAA, RETAB
22
+
23
+&bra rn rm m
24
+BRA 1101011 1000 11111 00001 m:1 rn:5 rm:5 &bra # BRAA, BRAB
25
+BLRA 1101011 1001 11111 00001 m:1 rn:5 rm:5 &bra # BLRAA, BLRAB
26
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/tcg/translate-a64.c
29
+++ b/target/arm/tcg/translate-a64.c
30
@@ -XXX,XX +XXX,XX @@ static bool trans_RETA(DisasContext *s, arg_reta *a)
31
return true;
18
}
32
}
19
33
20
-#else
34
+static bool trans_BRA(DisasContext *s, arg_bra *a)
21
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
22
+{
35
+{
23
+ return ARMMMUIdx_MUser;
36
+ TCGv_i64 dst;
37
+
38
+ if (!dc_isar_feature(aa64_pauth, s)) {
39
+ return false;
40
+ }
41
+ dst = auth_branch_target(s, cpu_reg(s,a->rn), cpu_reg_sp(s, a->rm), !a->m);
42
+ gen_a64_set_pc(s, dst);
43
+ set_btype_for_br(s, a->rn);
44
+ s->base.is_jmp = DISAS_JUMP;
45
+ return true;
24
+}
46
+}
25
+
47
+
26
+#else /* !CONFIG_USER_ONLY */
48
+static bool trans_BLRA(DisasContext *s, arg_bra *a)
27
49
+{
28
/*
50
+ TCGv_i64 dst, lr;
29
* What kind of stack write are we doing? This affects how exceptions
51
+
30
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
52
+ if (!dc_isar_feature(aa64_pauth, s)) {
31
return tt_resp;
53
+ return false;
54
+ }
55
+ dst = auth_branch_target(s, cpu_reg(s, a->rn), cpu_reg_sp(s, a->rm), !a->m);
56
+ lr = cpu_reg(s, 30);
57
+ if (dst == lr) {
58
+ TCGv_i64 tmp = tcg_temp_new_i64();
59
+ tcg_gen_mov_i64(tmp, dst);
60
+ dst = tmp;
61
+ }
62
+ gen_pc_plus_diff(s, lr, curr_insn_len(s));
63
+ gen_a64_set_pc(s, dst);
64
+ set_btype_for_blr(s);
65
+ s->base.is_jmp = DISAS_JUMP;
66
+ return true;
67
+}
68
+
69
/* HINT instruction group, including various allocated HINTs */
70
static void handle_hint(DisasContext *s, uint32_t insn,
71
unsigned int op1, unsigned int op2, unsigned int crm)
72
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
73
static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
74
{
75
unsigned int opc, op2, op3, rn, op4;
76
- unsigned btype_mod = 2; /* 0: BR, 1: BLR, 2: other */
77
TCGv_i64 dst;
78
TCGv_i64 modifier;
79
80
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
81
case 0:
82
case 1:
83
case 2:
84
+ case 8:
85
+ case 9:
86
/*
87
- * BR, BLR, RET, RETAA, RETAB, BRAAZ, BRABZ, BLRAAZ, BLRABZ:
88
- * handled in decodetree
89
+ * BR, BLR, RET, RETAA, RETAB, BRAAZ, BRABZ, BLRAAZ, BLRABZ,
90
+ * BRAA, BLRAA: handled in decodetree
91
*/
92
goto do_unallocated;
93
94
- case 8: /* BRAA */
95
- case 9: /* BLRAA */
96
- if (!dc_isar_feature(aa64_pauth, s)) {
97
- goto do_unallocated;
98
- }
99
- if ((op3 & ~1) != 2) {
100
- goto do_unallocated;
101
- }
102
- btype_mod = opc & 1;
103
- if (s->pauth_active) {
104
- dst = tcg_temp_new_i64();
105
- modifier = cpu_reg_sp(s, op4);
106
- if (op3 == 2) {
107
- gen_helper_autia(dst, cpu_env, cpu_reg(s, rn), modifier);
108
- } else {
109
- gen_helper_autib(dst, cpu_env, cpu_reg(s, rn), modifier);
110
- }
111
- } else {
112
- dst = cpu_reg(s, rn);
113
- }
114
- /* BLRAA also needs to load return address */
115
- if (opc == 9) {
116
- TCGv_i64 lr = cpu_reg(s, 30);
117
- if (dst == lr) {
118
- TCGv_i64 tmp = tcg_temp_new_i64();
119
- tcg_gen_mov_i64(tmp, dst);
120
- dst = tmp;
121
- }
122
- gen_pc_plus_diff(s, lr, curr_insn_len(s));
123
- }
124
- gen_a64_set_pc(s, dst);
125
- break;
126
-
127
case 4: /* ERET */
128
if (s->current_el == 0) {
129
goto do_unallocated;
130
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
131
unallocated_encoding(s);
132
return;
133
}
134
-
135
- switch (btype_mod) {
136
- case 0: /* BR */
137
- if (dc_isar_feature(aa64_bti, s)) {
138
- /* BR to {x16,x17} or !guard -> 1, else 3. */
139
- set_btype(s, rn == 16 || rn == 17 || !s->guarded_page ? 1 : 3);
140
- }
141
- break;
142
-
143
- case 1: /* BLR */
144
- if (dc_isar_feature(aa64_bti, s)) {
145
- /* BLR sets BTYPE to 2, regardless of source guarded page. */
146
- set_btype(s, 2);
147
- }
148
- break;
149
-
150
- default: /* RET or none of the above. */
151
- /* BTYPE will be set to 0 by normal end-of-insn processing. */
152
- break;
153
- }
154
-
155
- s->base.is_jmp = DISAS_JUMP;
32
}
156
}
33
157
34
-#endif /* !CONFIG_USER_ONLY */
158
/* Branches, exception generating and system instructions */
35
-
36
ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
37
bool secstate, bool priv, bool negpri)
38
{
39
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
40
41
return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
42
}
43
+
44
+#endif /* !CONFIG_USER_ONLY */
45
--
159
--
46
2.34.1
160
2.34.1
47
48
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Convert the exception-return insns ERET, ERETA and ERETB to
2
decodetree. These were the last insns left in the legacy
3
decoder function disas_uncond_reg_b(), which allows us to
4
remove it.
2
5
3
There is no point in using a void pointer to access the NVIC.
6
The old decoder explicitly decoded the DRPS instruction,
4
Use the real type to avoid casting it while debugging.
7
only in order to call unallocated_encoding() on it, exactly
8
as would have happened if it hadn't decoded it. This is
9
because this insn always UNDEFs unless the CPU is in
10
halting-debug state, which we don't emulate. So we list
11
the pattern in a comment in a64.decode, but don't actively
12
decode it.
5
13
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230206223502.25122-11-philmd@linaro.org
16
Message-id: 20230512144106.3608981-21-peter.maydell@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
17
---
11
target/arm/cpu.h | 46 ++++++++++++++++++++++---------------------
18
target/arm/tcg/a64.decode | 8 ++
12
hw/intc/armv7m_nvic.c | 38 ++++++++++++-----------------------
19
target/arm/tcg/translate-a64.c | 163 +++++++++++----------------------
13
target/arm/cpu.c | 1 +
20
2 files changed, 63 insertions(+), 108 deletions(-)
14
target/arm/m_helper.c | 2 +-
15
4 files changed, 39 insertions(+), 48 deletions(-)
16
21
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
18
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
24
--- a/target/arm/tcg/a64.decode
20
+++ b/target/arm/cpu.h
25
+++ b/target/arm/tcg/a64.decode
21
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMTBFlags {
26
@@ -XXX,XX +XXX,XX @@ RETA 1101011 0010 11111 00001 m:1 11111 11111 &reta # RETAA, RETAB
22
27
&bra rn rm m
23
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
28
BRA 1101011 1000 11111 00001 m:1 rn:5 rm:5 &bra # BRAA, BRAB
24
29
BLRA 1101011 1001 11111 00001 m:1 rn:5 rm:5 &bra # BLRAA, BLRAB
25
+typedef struct NVICState NVICState;
30
+
26
+
31
+ERET 1101011 0100 11111 000000 11111 00000
27
typedef struct CPUArchState {
32
+ERETA 1101011 0100 11111 00001 m:1 11111 11111 &reta # ERETAA, ERETAB
28
/* Regs for current mode. */
33
+
29
uint32_t regs[16];
34
+# We don't need to decode DRPS because it always UNDEFs except when
30
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
35
+# the processor is in halting debug state (which we don't implement).
31
} sau;
36
+# The pattern is listed here as documentation.
32
37
+# DRPS 1101011 0101 11111 000000 11111 00000
33
#if !defined(CONFIG_USER_ONLY)
38
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
34
- void *nvic;
39
index XXXXXXX..XXXXXXX 100644
35
+ NVICState *nvic;
40
--- a/target/arm/tcg/translate-a64.c
36
const struct arm_boot_info *boot_info;
41
+++ b/target/arm/tcg/translate-a64.c
37
/* Store GICv3CPUState to access from this struct */
42
@@ -XXX,XX +XXX,XX @@ static bool trans_BLRA(DisasContext *s, arg_bra *a)
38
void *gicv3state;
39
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
40
41
/* Interface between CPU and Interrupt controller. */
42
#ifndef CONFIG_USER_ONLY
43
-bool armv7m_nvic_can_take_pending_exception(void *opaque);
44
+bool armv7m_nvic_can_take_pending_exception(NVICState *s);
45
#else
46
-static inline bool armv7m_nvic_can_take_pending_exception(void *opaque)
47
+static inline bool armv7m_nvic_can_take_pending_exception(NVICState *s)
48
{
49
return true;
43
return true;
50
}
44
}
51
#endif
45
52
/**
46
+static bool trans_ERET(DisasContext *s, arg_ERET *a)
53
* armv7m_nvic_set_pending: mark the specified exception as pending
47
+{
54
- * @opaque: the NVIC
48
+ TCGv_i64 dst;
55
+ * @s: the NVIC
49
+
56
* @irq: the exception number to mark pending
50
+ if (s->current_el == 0) {
57
* @secure: false for non-banked exceptions or for the nonsecure
51
+ return false;
58
* version of a banked exception, true for the secure version of a banked
52
+ }
59
@@ -XXX,XX +XXX,XX @@ static inline bool armv7m_nvic_can_take_pending_exception(void *opaque)
53
+ if (s->fgt_eret) {
60
* if @secure is true and @irq does not specify one of the fixed set
54
+ gen_exception_insn_el(s, 0, EXCP_UDEF, 0, 2);
61
* of architecturally banked exceptions.
55
+ return true;
62
*/
56
+ }
63
-void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
57
+ dst = tcg_temp_new_i64();
64
+void armv7m_nvic_set_pending(NVICState *s, int irq, bool secure);
58
+ tcg_gen_ld_i64(dst, cpu_env,
65
/**
59
+ offsetof(CPUARMState, elr_el[s->current_el]));
66
* armv7m_nvic_set_pending_derived: mark this derived exception as pending
60
+
67
- * @opaque: the NVIC
61
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
68
+ * @s: the NVIC
62
+ gen_io_start();
69
* @irq: the exception number to mark pending
63
+ }
70
* @secure: false for non-banked exceptions or for the nonsecure
64
+
71
* version of a banked exception, true for the secure version of a banked
65
+ gen_helper_exception_return(cpu_env, dst);
72
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
66
+ /* Must exit loop to check un-masked IRQs */
73
* exceptions (exceptions generated in the course of trying to take
67
+ s->base.is_jmp = DISAS_EXIT;
74
* a different exception).
68
+ return true;
75
*/
69
+}
76
-void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
70
+
77
+void armv7m_nvic_set_pending_derived(NVICState *s, int irq, bool secure);
71
+static bool trans_ERETA(DisasContext *s, arg_reta *a)
78
/**
72
+{
79
* armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
73
+ TCGv_i64 dst;
80
- * @opaque: the NVIC
74
+
81
+ * @s: the NVIC
75
+ if (!dc_isar_feature(aa64_pauth, s)) {
82
* @irq: the exception number to mark pending
76
+ return false;
83
* @secure: false for non-banked exceptions or for the nonsecure
77
+ }
84
* version of a banked exception, true for the secure version of a banked
78
+ if (s->current_el == 0) {
85
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
79
+ return false;
86
* Similar to armv7m_nvic_set_pending(), but specifically for exceptions
80
+ }
87
* generated in the course of lazy stacking of FP registers.
81
+ /* The FGT trap takes precedence over an auth trap. */
88
*/
82
+ if (s->fgt_eret) {
89
-void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
83
+ gen_exception_insn_el(s, 0, EXCP_UDEF, a->m ? 3 : 2, 2);
90
+void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure);
84
+ return true;
91
/**
85
+ }
92
* armv7m_nvic_get_pending_irq_info: return highest priority pending
86
+ dst = tcg_temp_new_i64();
93
* exception, and whether it targets Secure state
87
+ tcg_gen_ld_i64(dst, cpu_env,
94
- * @opaque: the NVIC
88
+ offsetof(CPUARMState, elr_el[s->current_el]));
95
+ * @s: the NVIC
89
+
96
* @pirq: set to pending exception number
90
+ dst = auth_branch_target(s, dst, cpu_X[31], !a->m);
97
* @ptargets_secure: set to whether pending exception targets Secure
91
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
98
*
92
+ gen_io_start();
99
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
93
+ }
100
* to true if the current highest priority pending exception should
94
+
101
* be taken to Secure state, false for NS.
95
+ gen_helper_exception_return(cpu_env, dst);
102
*/
96
+ /* Must exit loop to check un-masked IRQs */
103
-void armv7m_nvic_get_pending_irq_info(void *opaque, int *pirq,
97
+ s->base.is_jmp = DISAS_EXIT;
104
+void armv7m_nvic_get_pending_irq_info(NVICState *s, int *pirq,
98
+ return true;
105
bool *ptargets_secure);
99
+}
106
/**
100
+
107
* armv7m_nvic_acknowledge_irq: make highest priority pending exception active
101
/* HINT instruction group, including various allocated HINTs */
108
- * @opaque: the NVIC
102
static void handle_hint(DisasContext *s, uint32_t insn,
109
+ * @s: the NVIC
103
unsigned int op1, unsigned int op2, unsigned int crm)
110
*
104
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
111
* Move the current highest priority pending exception from the pending
112
* state to the active state, and update v7m.exception to indicate that
113
* it is the exception currently being handled.
114
*/
115
-void armv7m_nvic_acknowledge_irq(void *opaque);
116
+void armv7m_nvic_acknowledge_irq(NVICState *s);
117
/**
118
* armv7m_nvic_complete_irq: complete specified interrupt or exception
119
- * @opaque: the NVIC
120
+ * @s: the NVIC
121
* @irq: the exception number to complete
122
* @secure: true if this exception was secure
123
*
124
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
125
* 0 if there is still an irq active after this one was completed
126
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
127
*/
128
-int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
129
+int armv7m_nvic_complete_irq(NVICState *s, int irq, bool secure);
130
/**
131
* armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
132
- * @opaque: the NVIC
133
+ * @s: the NVIC
134
* @irq: the exception number to mark pending
135
* @secure: false for non-banked exceptions or for the nonsecure
136
* version of a banked exception, true for the secure version of a banked
137
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
138
* interrupt the current execution priority. This controls whether the
139
* RDY bit for it in the FPCCR is set.
140
*/
141
-bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure);
142
+bool armv7m_nvic_get_ready_status(NVICState *s, int irq, bool secure);
143
/**
144
* armv7m_nvic_raw_execution_priority: return the raw execution priority
145
- * @opaque: the NVIC
146
+ * @s: the NVIC
147
*
148
* Returns: the raw execution priority as defined by the v8M architecture.
149
* This is the execution priority minus the effects of AIRCR.PRIS,
150
* and minus any PRIMASK/FAULTMASK/BASEPRI priority boosting.
151
* (v8M ARM ARM I_PKLD.)
152
*/
153
-int armv7m_nvic_raw_execution_priority(void *opaque);
154
+int armv7m_nvic_raw_execution_priority(NVICState *s);
155
/**
156
* armv7m_nvic_neg_prio_requested: return true if the requested execution
157
* priority is negative for the specified security state.
158
- * @opaque: the NVIC
159
+ * @s: the NVIC
160
* @secure: the security state to test
161
* This corresponds to the pseudocode IsReqExecPriNeg().
162
*/
163
#ifndef CONFIG_USER_ONLY
164
-bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure);
165
+bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure);
166
#else
167
-static inline bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure)
168
+static inline bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure)
169
{
170
return false;
171
}
172
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/hw/intc/armv7m_nvic.c
175
+++ b/hw/intc/armv7m_nvic.c
176
@@ -XXX,XX +XXX,XX @@ static inline int nvic_exec_prio(NVICState *s)
177
return MIN(running, s->exception_prio);
178
}
179
180
-bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure)
181
+bool armv7m_nvic_neg_prio_requested(NVICState *s, bool secure)
182
{
183
/* Return true if the requested execution priority is negative
184
* for the specified security state, ie that security state
185
@@ -XXX,XX +XXX,XX @@ bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure)
186
* mean we don't allow FAULTMASK_NS to actually make the execution
187
* priority negative). Compare pseudocode IsReqExcPriNeg().
188
*/
189
- NVICState *s = opaque;
190
-
191
if (s->cpu->env.v7m.faultmask[secure]) {
192
return true;
193
}
194
@@ -XXX,XX +XXX,XX @@ bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure)
195
return false;
196
}
197
198
-bool armv7m_nvic_can_take_pending_exception(void *opaque)
199
+bool armv7m_nvic_can_take_pending_exception(NVICState *s)
200
{
201
- NVICState *s = opaque;
202
-
203
return nvic_exec_prio(s) > nvic_pending_prio(s);
204
}
205
206
-int armv7m_nvic_raw_execution_priority(void *opaque)
207
+int armv7m_nvic_raw_execution_priority(NVICState *s)
208
{
209
- NVICState *s = opaque;
210
-
211
return s->exception_prio;
212
}
213
214
@@ -XXX,XX +XXX,XX @@ static void nvic_irq_update(NVICState *s)
215
* if @secure is true and @irq does not specify one of the fixed set
216
* of architecturally banked exceptions.
217
*/
218
-static void armv7m_nvic_clear_pending(void *opaque, int irq, bool secure)
219
+static void armv7m_nvic_clear_pending(NVICState *s, int irq, bool secure)
220
{
221
- NVICState *s = (NVICState *)opaque;
222
VecInfo *vec;
223
224
assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
225
@@ -XXX,XX +XXX,XX @@ static void do_armv7m_nvic_set_pending(void *opaque, int irq, bool secure,
226
}
105
}
227
}
106
}
228
107
229
-void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
108
-/* Unconditional branch (register)
230
+void armv7m_nvic_set_pending(NVICState *s, int irq, bool secure)
109
- * 31 25 24 21 20 16 15 10 9 5 4 0
110
- * +---------------+-------+-------+-------+------+-------+
111
- * | 1 1 0 1 0 1 1 | opc | op2 | op3 | Rn | op4 |
112
- * +---------------+-------+-------+-------+------+-------+
113
- */
114
-static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
115
-{
116
- unsigned int opc, op2, op3, rn, op4;
117
- TCGv_i64 dst;
118
- TCGv_i64 modifier;
119
-
120
- opc = extract32(insn, 21, 4);
121
- op2 = extract32(insn, 16, 5);
122
- op3 = extract32(insn, 10, 6);
123
- rn = extract32(insn, 5, 5);
124
- op4 = extract32(insn, 0, 5);
125
-
126
- if (op2 != 0x1f) {
127
- goto do_unallocated;
128
- }
129
-
130
- switch (opc) {
131
- case 0:
132
- case 1:
133
- case 2:
134
- case 8:
135
- case 9:
136
- /*
137
- * BR, BLR, RET, RETAA, RETAB, BRAAZ, BRABZ, BLRAAZ, BLRABZ,
138
- * BRAA, BLRAA: handled in decodetree
139
- */
140
- goto do_unallocated;
141
-
142
- case 4: /* ERET */
143
- if (s->current_el == 0) {
144
- goto do_unallocated;
145
- }
146
- switch (op3) {
147
- case 0: /* ERET */
148
- if (op4 != 0) {
149
- goto do_unallocated;
150
- }
151
- if (s->fgt_eret) {
152
- gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(op3), 2);
153
- return;
154
- }
155
- dst = tcg_temp_new_i64();
156
- tcg_gen_ld_i64(dst, cpu_env,
157
- offsetof(CPUARMState, elr_el[s->current_el]));
158
- break;
159
-
160
- case 2: /* ERETAA */
161
- case 3: /* ERETAB */
162
- if (!dc_isar_feature(aa64_pauth, s)) {
163
- goto do_unallocated;
164
- }
165
- if (rn != 0x1f || op4 != 0x1f) {
166
- goto do_unallocated;
167
- }
168
- /* The FGT trap takes precedence over an auth trap. */
169
- if (s->fgt_eret) {
170
- gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(op3), 2);
171
- return;
172
- }
173
- dst = tcg_temp_new_i64();
174
- tcg_gen_ld_i64(dst, cpu_env,
175
- offsetof(CPUARMState, elr_el[s->current_el]));
176
- if (s->pauth_active) {
177
- modifier = cpu_X[31];
178
- if (op3 == 2) {
179
- gen_helper_autia(dst, cpu_env, dst, modifier);
180
- } else {
181
- gen_helper_autib(dst, cpu_env, dst, modifier);
182
- }
183
- }
184
- break;
185
-
186
- default:
187
- goto do_unallocated;
188
- }
189
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
190
- gen_io_start();
191
- }
192
-
193
- gen_helper_exception_return(cpu_env, dst);
194
- /* Must exit loop to check un-masked IRQs */
195
- s->base.is_jmp = DISAS_EXIT;
196
- return;
197
-
198
- case 5: /* DRPS */
199
- if (op3 != 0 || op4 != 0 || rn != 0x1f) {
200
- goto do_unallocated;
201
- } else {
202
- unallocated_encoding(s);
203
- }
204
- return;
205
-
206
- default:
207
- do_unallocated:
208
- unallocated_encoding(s);
209
- return;
210
- }
211
-}
212
-
213
/* Branches, exception generating and system instructions */
214
static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
231
{
215
{
232
- do_armv7m_nvic_set_pending(opaque, irq, secure, false);
216
@@ -XXX,XX +XXX,XX @@ static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
233
+ do_armv7m_nvic_set_pending(s, irq, secure, false);
217
disas_exc(s, insn);
234
}
218
}
235
219
break;
236
-void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
220
- case 0x6b: /* Unconditional branch (register) */
237
+void armv7m_nvic_set_pending_derived(NVICState *s, int irq, bool secure)
221
- disas_uncond_b_reg(s, insn);
238
{
222
- break;
239
- do_armv7m_nvic_set_pending(opaque, irq, secure, true);
223
default:
240
+ do_armv7m_nvic_set_pending(s, irq, secure, true);
224
unallocated_encoding(s);
241
}
225
break;
242
243
-void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
244
+void armv7m_nvic_set_pending_lazyfp(NVICState *s, int irq, bool secure)
245
{
246
/*
247
* Pend an exception during lazy FP stacking. This differs
248
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
249
* whether we should escalate depends on the saved context
250
* in the FPCCR register, not on the current state of the CPU/NVIC.
251
*/
252
- NVICState *s = (NVICState *)opaque;
253
bool banked = exc_is_banked(irq);
254
VecInfo *vec;
255
bool targets_secure;
256
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
257
}
258
259
/* Make pending IRQ active. */
260
-void armv7m_nvic_acknowledge_irq(void *opaque)
261
+void armv7m_nvic_acknowledge_irq(NVICState *s)
262
{
263
- NVICState *s = (NVICState *)opaque;
264
CPUARMState *env = &s->cpu->env;
265
const int pending = s->vectpending;
266
const int running = nvic_exec_prio(s);
267
@@ -XXX,XX +XXX,XX @@ static bool vectpending_targets_secure(NVICState *s)
268
exc_targets_secure(s, s->vectpending);
269
}
270
271
-void armv7m_nvic_get_pending_irq_info(void *opaque,
272
+void armv7m_nvic_get_pending_irq_info(NVICState *s,
273
int *pirq, bool *ptargets_secure)
274
{
275
- NVICState *s = (NVICState *)opaque;
276
const int pending = s->vectpending;
277
bool targets_secure;
278
279
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_get_pending_irq_info(void *opaque,
280
*pirq = pending;
281
}
282
283
-int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
284
+int armv7m_nvic_complete_irq(NVICState *s, int irq, bool secure)
285
{
286
- NVICState *s = (NVICState *)opaque;
287
VecInfo *vec = NULL;
288
int ret = 0;
289
290
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
291
return ret;
292
}
293
294
-bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
295
+bool armv7m_nvic_get_ready_status(NVICState *s, int irq, bool secure)
296
{
297
/*
298
* Return whether an exception is "ready", i.e. it is enabled and is
299
@@ -XXX,XX +XXX,XX @@ bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
300
* for non-banked exceptions secure is always false; for banked exceptions
301
* it indicates which of the exceptions is required.
302
*/
303
- NVICState *s = (NVICState *)opaque;
304
bool banked = exc_is_banked(irq);
305
VecInfo *vec;
306
int running = nvic_exec_prio(s);
307
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
308
index XXXXXXX..XXXXXXX 100644
309
--- a/target/arm/cpu.c
310
+++ b/target/arm/cpu.c
311
@@ -XXX,XX +XXX,XX @@
312
#if !defined(CONFIG_USER_ONLY)
313
#include "hw/loader.h"
314
#include "hw/boards.h"
315
+#include "hw/intc/armv7m_nvic.h"
316
#endif
317
#include "sysemu/tcg.h"
318
#include "sysemu/qtest.h"
319
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
320
index XXXXXXX..XXXXXXX 100644
321
--- a/target/arm/m_helper.c
322
+++ b/target/arm/m_helper.c
323
@@ -XXX,XX +XXX,XX @@ static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
324
* that we will need later in order to do lazy FP reg stacking.
325
*/
326
bool is_secure = env->v7m.secure;
327
- void *nvic = env->nvic;
328
+ NVICState *nvic = env->nvic;
329
/*
330
* Some bits are unbanked and live always in fpccr[M_REG_S]; some bits
331
* are banked and we want to update the bit in the bank for the
332
--
226
--
333
2.34.1
227
2.34.1
334
335
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
The IMPDEF sysreg L2CTLR_EL1 found on the Cortex-A35, A53, A57, A72
2
and which we (arguably dubiously) also provide in '-cpu max' has a
3
2 bit field for the number of processors in the cluster. On real
4
hardware this must be sufficient because it can only be configured
5
with up to 4 CPUs in the cluster. However on QEMU if the board code
6
does not explicitly configure the code into clusters with the right
7
CPU count we default to "give the value assuming that all CPUs in
8
the system are in a single cluster", which might be too big to fit
9
in the field.
2
10
3
Havard is no longer working on the Nuvoton systems for a while
11
Instead of just overflowing this 2-bit field, saturate to 3 (meaning
4
and won't be able to do any work on it in the future. So I'll
12
"4 CPUs", so at least we don't overwrite other fields in the register.
5
take over maintaining the Nuvoton system from him.
13
It's unlikely that any guest code really cares about the value in
14
this field; at least, if it does it probably also wants the system
15
to be more closely matching real hardware, i.e. not to have more
16
than 4 CPUs.
6
17
7
Signed-off-by: Hao Wu <wuhaotsh@google.com>
18
This issue has been present since the L2CTLR was first added in
8
Acked-by: Havard Skinnemoen <hskinnemoen@google.com>
19
commit 377a44ec8f2fac5b back in 2014. It was only noticed because
9
Reviewed-by: Philippe Mathieu-Daude <philmd@linaro.org>
20
Coverity complains (CID 1509227) that the shift might overflow 32 bits
10
Message-id: 20230208235433.3989937-2-wuhaotsh@google.com
21
and inadvertently sign extend into the top half of the 64 bit value.
22
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20230512170223.3801643-2-peter.maydell@linaro.org
12
---
26
---
13
MAINTAINERS | 2 +-
27
target/arm/cortex-regs.c | 11 +++++++++--
14
1 file changed, 1 insertion(+), 1 deletion(-)
28
1 file changed, 9 insertions(+), 2 deletions(-)
15
29
16
diff --git a/MAINTAINERS b/MAINTAINERS
30
diff --git a/target/arm/cortex-regs.c b/target/arm/cortex-regs.c
17
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
18
--- a/MAINTAINERS
32
--- a/target/arm/cortex-regs.c
19
+++ b/MAINTAINERS
33
+++ b/target/arm/cortex-regs.c
20
@@ -XXX,XX +XXX,XX @@ F: include/hw/net/mv88w8618_eth.h
34
@@ -XXX,XX +XXX,XX @@ static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
21
F: docs/system/arm/musicpal.rst
35
{
22
36
ARMCPU *cpu = env_archcpu(env);
23
Nuvoton NPCM7xx
37
24
-M: Havard Skinnemoen <hskinnemoen@google.com>
38
- /* Number of cores is in [25:24]; otherwise we RAZ */
25
M: Tyrone Ting <kfting@nuvoton.com>
39
- return (cpu->core_count - 1) << 24;
26
+M: Hao Wu <wuhaotsh@google.com>
40
+ /*
27
L: qemu-arm@nongnu.org
41
+ * Number of cores is in [25:24]; otherwise we RAZ.
28
S: Supported
42
+ * If the board didn't configure the CPUs into clusters,
29
F: hw/*/npcm7xx*
43
+ * we default to "all CPUs in one cluster", which might be
44
+ * more than the 4 that the hardware permits and which is
45
+ * all you can report in this two-bit field. Saturate to
46
+ * 0b11 (== 4 CPUs) rather than overflowing the field.
47
+ */
48
+ return MIN(cpu->core_count - 1, 3) << 24;
49
}
50
51
static const ARMCPRegInfo cortex_a72_a57_a53_cp_reginfo[] = {
30
--
52
--
31
2.34.1
53
2.34.1
diff view generated by jsdifflib
1
From: Claudio Fontana <cfontana@suse.de>
1
In the vexpress board code, we allocate a new MemoryRegion at the top
2
of vexpress_common_init() but only set it up and use it inside the
3
"if (map[VE_NORFLASHALIAS] != -1)" conditional, so we leak it if not.
4
This isn't a very interesting leak as it's a tiny amount of memory
5
once at startup, but it's easy to fix.
2
6
3
make it clearer from the name that this is a tcg-only function.
7
We could silence Coverity simply by moving the g_new() into the
8
if() block, but this use of g_new(MemoryRegion, 1) is a legacy from
9
when this board model was originally written; we wouldn't do that
10
if we wrote it today. The MemoryRegions are conceptually a part of
11
the board and must not go away until the whole board is done with
12
(at the end of the simulation), so they belong in its state struct.
4
13
5
Signed-off-by: Claudio Fontana <cfontana@suse.de>
14
This machine already has a VexpressMachineState struct that extends
6
Signed-off-by: Fabiano Rosas <farosas@suse.de>
15
MachineState, so statically put the MemoryRegions in there instead of
16
dynamically allocating them separately at runtime.
17
18
Spotted by Coverity (CID 1509083).
19
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
22
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
23
Message-id: 20230512170223.3801643-3-peter.maydell@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
24
---
12
target/arm/helper.c | 4 ++--
25
hw/arm/vexpress.c | 40 ++++++++++++++++++++--------------------
13
1 file changed, 2 insertions(+), 2 deletions(-)
26
1 file changed, 20 insertions(+), 20 deletions(-)
14
27
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
16
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
30
--- a/hw/arm/vexpress.c
18
+++ b/target/arm/helper.c
31
+++ b/hw/arm/vexpress.c
19
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
32
@@ -XXX,XX +XXX,XX @@ struct VexpressMachineClass {
20
* trapped to the hypervisor in KVM.
33
21
*/
34
struct VexpressMachineState {
22
#ifdef CONFIG_TCG
35
MachineState parent;
23
-static void handle_semihosting(CPUState *cs)
36
+ MemoryRegion vram;
24
+static void tcg_handle_semihosting(CPUState *cs)
37
+ MemoryRegion sram;
38
+ MemoryRegion flashalias;
39
+ MemoryRegion lowram;
40
+ MemoryRegion a15sram;
41
bool secure;
42
bool virt;
43
};
44
@@ -XXX,XX +XXX,XX @@ struct VexpressMachineState {
45
#define TYPE_VEXPRESS_A15_MACHINE MACHINE_TYPE_NAME("vexpress-a15")
46
OBJECT_DECLARE_TYPE(VexpressMachineState, VexpressMachineClass, VEXPRESS_MACHINE)
47
48
-typedef void DBoardInitFn(const VexpressMachineState *machine,
49
+typedef void DBoardInitFn(VexpressMachineState *machine,
50
ram_addr_t ram_size,
51
const char *cpu_type,
52
qemu_irq *pic);
53
@@ -XXX,XX +XXX,XX @@ static void init_cpus(MachineState *ms, const char *cpu_type,
54
}
55
}
56
57
-static void a9_daughterboard_init(const VexpressMachineState *vms,
58
+static void a9_daughterboard_init(VexpressMachineState *vms,
59
ram_addr_t ram_size,
60
const char *cpu_type,
61
qemu_irq *pic)
25
{
62
{
26
ARMCPU *cpu = ARM_CPU(cs);
63
MachineState *machine = MACHINE(vms);
27
CPUARMState *env = &cpu->env;
64
MemoryRegion *sysmem = get_system_memory();
28
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_interrupt(CPUState *cs)
65
- MemoryRegion *lowram = g_new(MemoryRegion, 1);
66
ram_addr_t low_ram_size;
67
68
if (ram_size > 0x40000000) {
69
@@ -XXX,XX +XXX,XX @@ static void a9_daughterboard_init(const VexpressMachineState *vms,
70
* address space should in theory be remappable to various
71
* things including ROM or RAM; we always map the RAM there.
29
*/
72
*/
30
#ifdef CONFIG_TCG
73
- memory_region_init_alias(lowram, NULL, "vexpress.lowmem", machine->ram,
31
if (cs->exception_index == EXCP_SEMIHOST) {
74
- 0, low_ram_size);
32
- handle_semihosting(cs);
75
- memory_region_add_subregion(sysmem, 0x0, lowram);
33
+ tcg_handle_semihosting(cs);
76
+ memory_region_init_alias(&vms->lowram, NULL, "vexpress.lowmem",
34
return;
77
+ machine->ram, 0, low_ram_size);
78
+ memory_region_add_subregion(sysmem, 0x0, &vms->lowram);
79
memory_region_add_subregion(sysmem, 0x60000000, machine->ram);
80
81
/* 0x1e000000 A9MPCore (SCU) private memory region */
82
@@ -XXX,XX +XXX,XX @@ static VEDBoardInfo a9_daughterboard = {
83
.init = a9_daughterboard_init,
84
};
85
86
-static void a15_daughterboard_init(const VexpressMachineState *vms,
87
+static void a15_daughterboard_init(VexpressMachineState *vms,
88
ram_addr_t ram_size,
89
const char *cpu_type,
90
qemu_irq *pic)
91
{
92
MachineState *machine = MACHINE(vms);
93
MemoryRegion *sysmem = get_system_memory();
94
- MemoryRegion *sram = g_new(MemoryRegion, 1);
95
96
{
97
/* We have to use a separate 64 bit variable here to avoid the gcc
98
@@ -XXX,XX +XXX,XX @@ static void a15_daughterboard_init(const VexpressMachineState *vms,
99
/* 0x2b060000: SP805 watchdog: not modelled */
100
/* 0x2b0a0000: PL341 dynamic memory controller: not modelled */
101
/* 0x2e000000: system SRAM */
102
- memory_region_init_ram(sram, NULL, "vexpress.a15sram", 0x10000,
103
+ memory_region_init_ram(&vms->a15sram, NULL, "vexpress.a15sram", 0x10000,
104
&error_fatal);
105
- memory_region_add_subregion(sysmem, 0x2e000000, sram);
106
+ memory_region_add_subregion(sysmem, 0x2e000000, &vms->a15sram);
107
108
/* 0x7ffb0000: DMA330 DMA controller: not modelled */
109
/* 0x7ffd0000: PL354 static memory controller: not modelled */
110
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
111
I2CBus *i2c;
112
ram_addr_t vram_size, sram_size;
113
MemoryRegion *sysmem = get_system_memory();
114
- MemoryRegion *vram = g_new(MemoryRegion, 1);
115
- MemoryRegion *sram = g_new(MemoryRegion, 1);
116
- MemoryRegion *flashalias = g_new(MemoryRegion, 1);
117
- MemoryRegion *flash0mem;
118
const hwaddr *map = daughterboard->motherboard_map;
119
int i;
120
121
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
122
123
if (map[VE_NORFLASHALIAS] != -1) {
124
/* Map flash 0 as an alias into low memory */
125
+ MemoryRegion *flash0mem;
126
flash0mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(pflash0), 0);
127
- memory_region_init_alias(flashalias, NULL, "vexpress.flashalias",
128
+ memory_region_init_alias(&vms->flashalias, NULL, "vexpress.flashalias",
129
flash0mem, 0, VEXPRESS_FLASH_SIZE);
130
- memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], flashalias);
131
+ memory_region_add_subregion(sysmem, map[VE_NORFLASHALIAS], &vms->flashalias);
35
}
132
}
36
#endif
133
134
dinfo = drive_get(IF_PFLASH, 0, 1);
135
ve_pflash_cfi01_register(map[VE_NORFLASH1], "vexpress.flash1", dinfo);
136
137
sram_size = 0x2000000;
138
- memory_region_init_ram(sram, NULL, "vexpress.sram", sram_size,
139
+ memory_region_init_ram(&vms->sram, NULL, "vexpress.sram", sram_size,
140
&error_fatal);
141
- memory_region_add_subregion(sysmem, map[VE_SRAM], sram);
142
+ memory_region_add_subregion(sysmem, map[VE_SRAM], &vms->sram);
143
144
vram_size = 0x800000;
145
- memory_region_init_ram(vram, NULL, "vexpress.vram", vram_size,
146
+ memory_region_init_ram(&vms->vram, NULL, "vexpress.vram", vram_size,
147
&error_fatal);
148
- memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram);
149
+ memory_region_add_subregion(sysmem, map[VE_VIDEORAM], &vms->vram);
150
151
/* 0x4e000000 LAN9118 Ethernet */
152
if (nd_table[0].used) {
37
--
153
--
38
2.34.1
154
2.34.1
39
155
40
156
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
Convert the u2f.txt file to rST, and place it in the right place
2
2
in our manual layout. The old text didn't fit very well into our
3
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
3
manual style, so the new version ends up looking like a rewrite,
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
although some of the original text is preserved:
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
6
Message-id: 20230206223502.25122-6-philmd@linaro.org
6
* the 'building' section of the old file is removed, since we
7
generally assume that users have already built QEMU
8
* some rather verbose text has been cut back
9
* document the passthrough device first, on the assumption
10
that's most likely to be of interest to users
11
* cut back on the duplication of text between sections
12
* format example command lines etc with rST
13
14
As it's a short document it seemed simplest to do this all
15
in one go rather than try to do a minimal syntactic conversion
16
and then clean up the wording and layout.
17
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Thomas Huth <thuth@redhat.com>
20
Message-id: 20230421163734.1152076-1-peter.maydell@linaro.org
8
---
21
---
9
linux-user/user-internals.h | 2 +-
22
docs/system/device-emulation.rst | 1 +
10
target/arm/cpu.h | 2 +-
23
docs/system/devices/usb-u2f.rst | 93 ++++++++++++++++++++++++++
11
linux-user/arm/cpu_loop.c | 4 ++--
24
docs/system/devices/usb.rst | 2 +-
12
3 files changed, 4 insertions(+), 4 deletions(-)
25
docs/u2f.txt | 110 -------------------------------
13
26
4 files changed, 95 insertions(+), 111 deletions(-)
14
diff --git a/linux-user/user-internals.h b/linux-user/user-internals.h
27
create mode 100644 docs/system/devices/usb-u2f.rst
28
delete mode 100644 docs/u2f.txt
29
30
diff --git a/docs/system/device-emulation.rst b/docs/system/device-emulation.rst
15
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/user-internals.h
32
--- a/docs/system/device-emulation.rst
17
+++ b/linux-user/user-internals.h
33
+++ b/docs/system/device-emulation.rst
18
@@ -XXX,XX +XXX,XX @@ void print_termios(void *arg);
34
@@ -XXX,XX +XXX,XX @@ Emulated Devices
19
#ifdef TARGET_ARM
35
devices/virtio-pmem.rst
20
static inline int regpairs_aligned(CPUArchState *cpu_env, int num)
36
devices/vhost-user-rng.rst
21
{
37
devices/canokey.rst
22
- return cpu_env->eabi == 1;
38
+ devices/usb-u2f.rst
23
+ return cpu_env->eabi;
39
devices/igb.rst
24
}
40
diff --git a/docs/system/devices/usb-u2f.rst b/docs/system/devices/usb-u2f.rst
25
#elif defined(TARGET_MIPS) && defined(TARGET_ABI_MIPSO32)
41
new file mode 100644
26
static inline int regpairs_aligned(CPUArchState *cpu_env, int num) { return 1; }
42
index XXXXXXX..XXXXXXX
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
43
--- /dev/null
44
+++ b/docs/system/devices/usb-u2f.rst
45
@@ -XXX,XX +XXX,XX @@
46
+Universal Second Factor (U2F) USB Key Device
47
+============================================
48
+
49
+U2F is an open authentication standard that enables relying parties
50
+exposed to the internet to offer a strong second factor option for end
51
+user authentication.
52
+
53
+The second factor is provided by a device implementing the U2F
54
+protocol. In case of a USB U2F security key, it is a USB HID device
55
+that implements the U2F protocol.
56
+
57
+QEMU supports both pass-through of a host U2F key device to a VM,
58
+and software emulation of a U2F key.
59
+
60
+``u2f-passthru``
61
+----------------
62
+
63
+The ``u2f-passthru`` device allows you to connect a real hardware
64
+U2F key on your host to a guest VM. All requests made from the guest
65
+are passed through to the physical security key connected to the
66
+host machine and vice versa.
67
+
68
+In addition, the dedicated pass-through allows you to share a single
69
+U2F security key with several guest VMs, which is not possible with a
70
+simple host device assignment pass-through.
71
+
72
+You can specify the host U2F key to use with the ``hidraw``
73
+option, which takes the host path to a Linux ``/dev/hidrawN`` device:
74
+
75
+.. parsed-literal::
76
+ |qemu_system| -usb -device u2f-passthru,hidraw=/dev/hidraw0
77
+
78
+If you don't specify the device, the ``u2f-passthru`` device will
79
+autoscan to take the first U2F device it finds on the host (this
80
+requires a working libudev):
81
+
82
+.. parsed-literal::
83
+ |qemu_system| -usb -device u2f-passthru
84
+
85
+``u2f-emulated``
86
+----------------
87
+
88
+``u2f-emulated`` is a completely software emulated U2F device.
89
+It uses `libu2f-emu <https://github.com/MattGorko/libu2f-emu>`__
90
+for the U2F key emulation. libu2f-emu
91
+provides a complete implementation of the U2F protocol device part for
92
+all specified transports given by the FIDO Alliance.
93
+
94
+To work, an emulated U2F device must have four elements:
95
+
96
+ * ec x509 certificate
97
+ * ec private key
98
+ * counter (four bytes value)
99
+ * 48 bytes of entropy (random bits)
100
+
101
+To use this type of device, these have to be configured, and these
102
+four elements must be passed one way or another.
103
+
104
+Assuming that you have a working libu2f-emu installed on the host,
105
+there are three possible ways to configure the ``u2f-emulated`` device:
106
+
107
+ * ephemeral
108
+ * setup directory
109
+ * manual
110
+
111
+Ephemeral is the simplest way to configure; it lets the device generate
112
+all the elements it needs for a single use of the lifetime of the device.
113
+It is the default if you do not pass any other options to the device.
114
+
115
+.. parsed-literal::
116
+ |qemu_system| -usb -device u2f-emulated
117
+
118
+You can pass the device the path of a setup directory on the host
119
+using the ``dir`` option; the directory must contain these four files:
120
+
121
+ * ``certificate.pem``: ec x509 certificate
122
+ * ``private-key.pem``: ec private key
123
+ * ``counter``: counter value
124
+ * ``entropy``: 48 bytes of entropy
125
+
126
+.. parsed-literal::
127
+ |qemu_system| -usb -device u2f-emulated,dir=$dir
128
+
129
+You can also manually pass the device the paths to each of these files,
130
+if you don't want them all to be in the same directory, using the options
131
+
132
+ * ``cert``
133
+ * ``priv``
134
+ * ``counter``
135
+ * ``entropy``
136
+
137
+.. parsed-literal::
138
+ |qemu_system| -usb -device u2f-emulated,cert=$DIR1/$FILE1,priv=$DIR2/$FILE2,counter=$DIR3/$FILE3,entropy=$DIR4/$FILE4
139
diff --git a/docs/system/devices/usb.rst b/docs/system/devices/usb.rst
28
index XXXXXXX..XXXXXXX 100644
140
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu.h
141
--- a/docs/system/devices/usb.rst
30
+++ b/target/arm/cpu.h
142
+++ b/docs/system/devices/usb.rst
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
143
@@ -XXX,XX +XXX,XX @@ option or the ``device_add`` monitor command. Available devices are:
32
144
USB audio device
33
#if defined(CONFIG_USER_ONLY)
145
34
/* For usermode syscall translation. */
146
``u2f-{emulated,passthru}``
35
- int eabi;
147
- Universal Second Factor device
36
+ bool eabi;
148
+ :doc:`usb-u2f`
37
#endif
149
38
150
``canokey``
39
struct CPUBreakpoint *cpu_breakpoint[16];
151
An Open-source Secure Key implementing FIDO2, OpenPGP, PIV and more.
40
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
152
diff --git a/docs/u2f.txt b/docs/u2f.txt
41
index XXXXXXX..XXXXXXX 100644
153
deleted file mode 100644
42
--- a/linux-user/arm/cpu_loop.c
154
index XXXXXXX..XXXXXXX
43
+++ b/linux-user/arm/cpu_loop.c
155
--- a/docs/u2f.txt
44
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
156
+++ /dev/null
45
break;
157
@@ -XXX,XX +XXX,XX @@
46
case EXCP_SWI:
158
-QEMU U2F Key Device Documentation.
47
{
159
-
48
- env->eabi = 1;
160
-Contents
49
+ env->eabi = true;
161
-1. USB U2F key device
50
/* system call */
162
-2. Building
51
if (env->thumb) {
163
-3. Using u2f-emulated
52
/* Thumb is always EABI style with syscall number in r7 */
164
-4. Using u2f-passthru
53
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
165
-5. Libu2f-emu
54
* > 0xfffff and are handled below as out-of-range.
166
-
55
*/
167
-1. USB U2F key device
56
n ^= ARM_SYSCALL_BASE;
168
-
57
- env->eabi = 0;
169
-U2F is an open authentication standard that enables relying parties
58
+ env->eabi = false;
170
-exposed to the internet to offer a strong second factor option for end
59
}
171
-user authentication.
60
}
172
-
61
173
-The standard brings many advantages to both parties, client and server,
174
-allowing to reduce over-reliance on passwords, it increases authentication
175
-security and simplifies passwords.
176
-
177
-The second factor is materialized by a device implementing the U2F
178
-protocol. In case of a USB U2F security key, it is a USB HID device
179
-that implements the U2F protocol.
180
-
181
-In QEMU, the USB U2F key device offers a dedicated support of U2F, allowing
182
-guest USB FIDO/U2F security keys operating in two possible modes:
183
-pass-through and emulated.
184
-
185
-The pass-through mode consists of passing all requests made from the guest
186
-to the physical security key connected to the host machine and vice versa.
187
-In addition, the dedicated pass-through allows to have a U2F security key
188
-shared on several guests which is not possible with a simple host device
189
-assignment pass-through.
190
-
191
-The emulated mode consists of completely emulating the behavior of an
192
-U2F device through software part. Libu2f-emu is used for that.
193
-
194
-
195
-2. Building
196
-
197
-To ensure the build of the u2f-emulated device variant which depends
198
-on libu2f-emu: configuring and building:
199
-
200
- ./configure --enable-u2f && make
201
-
202
-The pass-through mode is built by default on Linux. To take advantage
203
-of the autoscan option it provides, make sure you have a working libudev
204
-installed on the host.
205
-
206
-
207
-3. Using u2f-emulated
208
-
209
-To work, an emulated U2F device must have four elements:
210
- * ec x509 certificate
211
- * ec private key
212
- * counter (four bytes value)
213
- * 48 bytes of entropy (random bits)
214
-
215
-To use this type of device, this one has to be configured, and these
216
-four elements must be passed one way or another.
217
-
218
-Assuming that you have a working libu2f-emu installed on the host.
219
-There are three possible ways of configurations:
220
- * ephemeral
221
- * setup directory
222
- * manual
223
-
224
-Ephemeral is the simplest way to configure, it lets the device generate
225
-all the elements it needs for a single use of the lifetime of the device.
226
-
227
- qemu -usb -device u2f-emulated
228
-
229
-Setup directory allows to configure the device from a directory containing
230
-four files:
231
- * certificate.pem: ec x509 certificate
232
- * private-key.pem: ec private key
233
- * counter: counter value
234
- * entropy: 48 bytes of entropy
235
-
236
- qemu -usb -device u2f-emulated,dir=$dir
237
-
238
-Manual allows to configure the device more finely by specifying each
239
-of the elements necessary for the device:
240
- * cert
241
- * priv
242
- * counter
243
- * entropy
244
-
245
- qemu -usb -device u2f-emulated,cert=$DIR1/$FILE1,priv=$DIR2/$FILE2,counter=$DIR3/$FILE3,entropy=$DIR4/$FILE4
246
-
247
-
248
-4. Using u2f-passthru
249
-
250
-On the host specify the u2f-passthru device with a suitable hidraw:
251
-
252
- qemu -usb -device u2f-passthru,hidraw=/dev/hidraw0
253
-
254
-Alternately, the u2f-passthru device can autoscan to take the first
255
-U2F device it finds on the host (this requires a working libudev):
256
-
257
- qemu -usb -device u2f-passthru
258
-
259
-
260
-5. Libu2f-emu
261
-
262
-The u2f-emulated device uses libu2f-emu for the U2F key emulation. Libu2f-emu
263
-implements completely the U2F protocol device part for all specified
264
-transport given by the FIDO Alliance.
265
-
266
-For more information about libu2f-emu see this page:
267
-https://github.com/MattGorko/libu2f-emu.
62
--
268
--
63
2.34.1
269
2.34.1
64
65
diff view generated by jsdifflib