1
Hi; this mostly contains the first slice of A64 decodetree
1
The following changes since commit 5767815218efd3cbfd409505ed824d5f356044ae:
2
patches, plus some other minor pieces. It also has the
3
enablement of MTE for KVM guests.
4
2
5
thanks
3
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging (2024-02-14 15:45:52 +0000)
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)
11
4
12
are available in the Git repository at:
5
are available in the Git repository at:
13
6
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230518
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240215
15
8
16
for you to fetch changes up to 91608e2a44f36e79cb83f863b8a7bb57d2c98061:
9
for you to fetch changes up to f780e63fe731b058fe52d43653600d8729a1b5f2:
17
10
18
docs: Convert u2f.txt to rST (2023-05-18 11:40:32 +0100)
11
docs: Add documentation for the mps3-an536 board (2024-02-15 14:32:39 +0000)
19
12
20
----------------------------------------------------------------
13
----------------------------------------------------------------
21
target-arm queue:
14
target-arm queue:
22
* Fix vd == vm overlap in sve_ldff1_z
15
* hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
23
* Add support for MTE with KVM guests
16
* linux-user/aarch64: Choose SYNC as the preferred MTE mode
24
* Add RAZ/WI handling for DBGDTR[TX|RX]
17
* Fix some errors in SVE/SME handling of MTE tags
25
* Start of conversion of A64 decoder to decodetree
18
* hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
26
* Saturate L2CTLR_EL1 core count field rather than overflowing
19
* hw/block/tc58128: Don't emit deprecation warning under qtest
27
* vexpress: Avoid trivial memory leak of 'flashalias'
20
* tests/qtest: Fix handling of npcm7xx and GMAC tests
28
* sbsa-ref: switch default cpu core to Neoverse-N1
21
* hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
29
* sbsa-ref: use Bochs graphics card instead of VGA
22
* tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
30
* MAINTAINERS: Add Marcin Juszkiewicz to sbsa-ref reviewer list
23
* Don't assert on vmload/vmsave of M-profile CPUs
31
* docs: Convert u2f.txt to rST
24
* hw/arm/smmuv3: add support for stage 1 access fault
25
* hw/arm/stellaris: QOM cleanups
26
* Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
27
* Improve Cortex_R52 IMPDEF sysreg modelling
28
* Allow access to SPSR_hyp from hyp mode
29
* New board model mps3-an536 (Cortex-R52)
32
30
33
----------------------------------------------------------------
31
----------------------------------------------------------------
34
Alex Bennée (1):
32
Luc Michel (1):
35
target/arm: add RAZ/WI handling for DBGDTR[TX|RX]
33
hw/arm/smmuv3: add support for stage 1 access fault
36
34
37
Cornelia Huck (1):
35
Nabih Estefan (1):
38
arm/kvm: add support for MTE
36
tests/qtest: Fix GMAC test to run on a machine in upstream QEMU
39
37
40
Marcin Juszkiewicz (3):
38
Peter Maydell (22):
41
sbsa-ref: switch default cpu core to Neoverse-N1
39
hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
42
Maintainers: add myself as reviewer for sbsa-ref
40
hw/block/tc58128: Don't emit deprecation warning under qtest
43
sbsa-ref: use Bochs graphics card instead of VGA
41
tests/qtest/meson.build: Don't include qtests_npcm7xx in qtests_aarch64
42
tests/qtest/bios-tables-test: Allow changes to virt GTDT
43
hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
44
tests/qtest/bios-tables-tests: Update virt golden reference
45
hw/arm/npcm7xx: Call qemu_configure_nic_device() for GMAC modules
46
tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
47
target/arm: Don't get MDCR_EL2 in pmu_counter_enabled() before checking ARM_FEATURE_PMU
48
target/arm: Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
49
target/arm: The Cortex-R52 has a read-only CBAR
50
target/arm: Add Cortex-R52 IMPDEF sysregs
51
target/arm: Allow access to SPSR_hyp from hyp mode
52
hw/misc/mps2-scc: Fix condition for CFG3 register
53
hw/misc/mps2-scc: Factor out which-board conditionals
54
hw/misc/mps2-scc: Make changes needed for AN536 FPGA image
55
hw/arm/mps3r: Initial skeleton for mps3-an536 board
56
hw/arm/mps3r: Add CPUs, GIC, and per-CPU RAM
57
hw/arm/mps3r: Add UARTs
58
hw/arm/mps3r: Add GPIO, watchdog, dual-timer, I2C devices
59
hw/arm/mps3r: Add remaining devices
60
docs: Add documentation for the mps3-an536 board
44
61
45
Peter Maydell (14):
62
Philippe Mathieu-Daudé (5):
46
target/arm: Create decodetree skeleton for A64
63
hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
47
target/arm: Pull calls to disas_sve() and disas_sme() out of legacy decoder
64
hw/arm/stellaris: Convert ADC controller to Resettable interface
48
target/arm: Convert Extract instructions to decodetree
65
hw/arm/stellaris: Convert I2C controller to Resettable interface
49
target/arm: Convert unconditional branch immediate to decodetree
66
hw/arm/stellaris: Add missing QOM 'machine' parent
50
target/arm: Convert CBZ, CBNZ to decodetree
67
hw/arm/stellaris: Add missing QOM 'SoC' parent
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
60
68
61
Richard Henderson (10):
69
Richard Henderson (6):
62
target/arm: Fix vd == vm overlap in sve_ldff1_z
70
linux-user/aarch64: Choose SYNC as the preferred MTE mode
63
target/arm: Split out disas_a64_legacy
71
target/arm: Fix nregs computation in do_{ld,st}_zpa
64
target/arm: Convert PC-rel addressing to decodetree
72
target/arm: Adjust and validate mtedesc sizem1
65
target/arm: Split gen_add_CC and gen_sub_CC
73
target/arm: Split out make_svemte_desc
66
target/arm: Convert Add/subtract (immediate) to decodetree
74
target/arm: Handle mte in do_ldrq, do_ldro
67
target/arm: Convert Add/subtract (immediate with tags) to decodetree
75
target/arm: Fix SVE/SME gross MTE suppression checks
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
72
76
73
MAINTAINERS | 1 +
77
MAINTAINERS | 3 +-
74
docs/system/device-emulation.rst | 1 +
78
docs/system/arm/mps2.rst | 37 +-
75
docs/system/devices/usb-u2f.rst | 93 +++
79
configs/devices/arm-softmmu/default.mak | 1 +
76
docs/system/devices/usb.rst | 2 +-
80
hw/arm/smmuv3-internal.h | 1 +
77
docs/u2f.txt | 110 ----
81
include/hw/arm/smmu-common.h | 1 +
78
target/arm/cpu.h | 4 +
82
include/hw/arm/virt.h | 2 +
79
target/arm/kvm_arm.h | 19 +
83
include/hw/misc/mps2-scc.h | 1 +
80
target/arm/tcg/translate.h | 5 +
84
linux-user/aarch64/target_prctl.h | 29 +-
81
target/arm/tcg/a64.decode | 152 +++++
85
target/arm/internals.h | 2 +-
82
hw/arm/sbsa-ref.c | 4 +-
86
target/arm/tcg/translate-a64.h | 2 +
83
hw/arm/vexpress.c | 40 +-
87
hw/arm/mps3r.c | 640 ++++++++++++++++++++++++++++++++
84
hw/arm/virt.c | 73 ++-
88
hw/arm/npcm7xx.c | 1 +
85
target/arm/cortex-regs.c | 11 +-
89
hw/arm/smmu-common.c | 11 +
86
target/arm/cpu.c | 9 +-
90
hw/arm/smmuv3.c | 1 +
87
target/arm/debug_helper.c | 11 +-
91
hw/arm/stellaris.c | 47 ++-
88
target/arm/kvm.c | 35 +
92
hw/arm/virt-acpi-build.c | 20 +-
89
target/arm/kvm64.c | 5 +
93
hw/arm/virt.c | 60 ++-
90
target/arm/tcg/sve_helper.c | 6 +
94
hw/arm/xilinx_zynq.c | 2 +
91
target/arm/tcg/translate-a64.c | 1321 ++++++++++++++++----------------------
95
hw/block/tc58128.c | 4 +-
92
target/arm/tcg/meson.build | 1 +
96
hw/misc/mps2-scc.c | 138 ++++++-
93
20 files changed, 979 insertions(+), 924 deletions(-)
97
hw/pci-host/raven.c | 1 +
94
create mode 100644 docs/system/devices/usb-u2f.rst
98
target/arm/helper.c | 14 +-
95
delete mode 100644 docs/u2f.txt
99
target/arm/tcg/cpu32.c | 109 ++++++
96
create mode 100644 target/arm/tcg/a64.decode
100
target/arm/tcg/op_helper.c | 43 ++-
101
target/arm/tcg/sme_helper.c | 8 +-
102
target/arm/tcg/sve_helper.c | 12 +-
103
target/arm/tcg/translate-sme.c | 15 +-
104
target/arm/tcg/translate-sve.c | 83 +++--
105
target/arm/tcg/translate.c | 19 +-
106
tests/qtest/npcm7xx_emc-test.c | 5 +-
107
tests/qtest/npcm_gmac-test.c | 84 +----
108
hw/arm/Kconfig | 5 +
109
hw/arm/meson.build | 1 +
110
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
111
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
112
tests/qtest/meson.build | 4 +-
113
36 files changed, 1184 insertions(+), 222 deletions(-)
114
create mode 100644 hw/arm/mps3r.c
97
115
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
2
3
Similarly to commits dadbb58f59..5ae79fe825 for other ARM boards,
4
connect FIQ output of the GIC CPU interfaces to the CPU.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20240130152548.17855-1-philmd@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/xilinx_zynq.c | 2 ++
12
1 file changed, 2 insertions(+)
13
14
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xilinx_zynq.c
17
+++ b/hw/arm/xilinx_zynq.c
18
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
19
sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
20
sysbus_connect_irq(busdev, 0,
21
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
22
+ sysbus_connect_irq(busdev, 1,
23
+ qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ));
24
25
for (n = 0; n < 64; n++) {
26
pic[n] = qdev_get_gpio_in(dev, n);
27
--
28
2.34.1
29
30
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use the bitops.h macro rather than rolling our own here.
3
The API does not generate an error for setting ASYNC | SYNC; that merely
4
constrains the selection vs the per-cpu default. For qemu linux-user,
5
choose SYNC as the default.
4
6
7
Cc: qemu-stable@nongnu.org
8
Reported-by: Gustavo Romero <gustavo.romero@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
11
Message-id: 20240207025210.8837-2-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230512144106.3608981-9-peter.maydell@linaro.org
9
---
13
---
10
target/arm/tcg/translate-a64.c | 11 ++---------
14
linux-user/aarch64/target_prctl.h | 29 +++++++++++++++++------------
11
1 file changed, 2 insertions(+), 9 deletions(-)
15
1 file changed, 17 insertions(+), 12 deletions(-)
12
16
13
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
17
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/tcg/translate-a64.c
19
--- a/linux-user/aarch64/target_prctl.h
16
+++ b/target/arm/tcg/translate-a64.c
20
+++ b/linux-user/aarch64/target_prctl.h
17
@@ -XXX,XX +XXX,XX @@ static uint64_t bitfield_replicate(uint64_t mask, unsigned int e)
21
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
18
return mask;
22
env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE;
19
}
23
20
24
if (cpu_isar_feature(aa64_mte, cpu)) {
21
-/* Return a value with the bottom len bits set (where 0 < len <= 64) */
25
- switch (arg2 & PR_MTE_TCF_MASK) {
22
-static inline uint64_t bitmask64(unsigned int length)
26
- case PR_MTE_TCF_NONE:
23
-{
27
- case PR_MTE_TCF_SYNC:
24
- assert(length > 0 && length <= 64);
28
- case PR_MTE_TCF_ASYNC:
25
- return ~0ULL >> (64 - length);
29
- break;
26
-}
30
- default:
31
- return -EINVAL;
32
- }
27
-
33
-
28
/* Simplified variant of pseudocode DecodeBitMasks() for the case where we
34
/*
29
* only require the wmask. Returns false if the imms/immr/immn are a reserved
35
* Write PR_MTE_TCF to SCTLR_EL1[TCF0].
30
* value (ie should cause a guest UNDEF exception), and true if they are
36
- * Note that the syscall values are consistent with hw.
31
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
37
+ *
32
/* Create the value of one element: s+1 set bits rotated
38
+ * The kernel has a per-cpu configuration for the sysadmin,
33
* by r within the element (which is e bits wide)...
39
+ * /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred,
34
*/
40
+ * which qemu does not implement.
35
- mask = bitmask64(s + 1);
41
+ *
36
+ mask = MAKE_64BIT_MASK(0, s + 1);
42
+ * Because there is no performance difference between the modes, and
37
if (r) {
43
+ * because SYNC is most useful for debugging MTE errors, choose SYNC
38
mask = (mask >> r) | (mask << (e - r));
44
+ * as the preferred mode. With this preference, and the way the API
39
- mask &= bitmask64(e);
45
+ * uses only two bits, there is no way for the program to select
40
+ mask &= MAKE_64BIT_MASK(0, e);
46
+ * ASYMM mode.
41
}
47
*/
42
/* ...then replicate the element over the whole 64 bit value */
48
- env->cp15.sctlr_el[1] =
43
mask = bitfield_replicate(mask, e);
49
- deposit64(env->cp15.sctlr_el[1], 38, 2, arg2 >> PR_MTE_TCF_SHIFT);
50
+ unsigned tcf = 0;
51
+ if (arg2 & PR_MTE_TCF_SYNC) {
52
+ tcf = 1;
53
+ } else if (arg2 & PR_MTE_TCF_ASYNC) {
54
+ tcf = 2;
55
+ }
56
+ env->cp15.sctlr_el[1] = deposit64(env->cp15.sctlr_el[1], 38, 2, tcf);
57
58
/*
59
* Write PR_MTE_TAG to GCR_EL1[Exclude].
44
--
60
--
45
2.34.1
61
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Convert the ADDG and SUBG (immediate) instructions.
3
The field is encoded as [0-3], which is convenient for
4
indexing our array of function pointers, but the true
5
value is [1-4]. Adjust before calling do_mem_zpa.
4
6
7
Add an assert, and move the comment re passing ZT to
8
the helper back next to the relevant code.
9
10
Cc: qemu-stable@nongnu.org
11
Fixes: 206adacfb8d ("target/arm: Add mte helpers for sve scalar + int loads")
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20240207025210.8837-3-richard.henderson@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>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
17
---
13
target/arm/tcg/a64.decode | 8 +++++++
18
target/arm/tcg/translate-sve.c | 16 ++++++++--------
14
target/arm/tcg/translate-a64.c | 38 ++++++++++------------------------
19
1 file changed, 8 insertions(+), 8 deletions(-)
15
2 files changed, 19 insertions(+), 27 deletions(-)
16
20
17
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
21
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
18
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/tcg/a64.decode
23
--- a/target/arm/tcg/translate-sve.c
20
+++ b/target/arm/tcg/a64.decode
24
+++ b/target/arm/tcg/translate-sve.c
21
@@ -XXX,XX +XXX,XX @@ SUB_i . 10 100010 0 ............ ..... ..... @addsub_imm
25
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
22
SUB_i . 10 100010 1 ............ ..... ..... @addsub_imm12
26
TCGv_ptr t_pg;
23
SUBS_i . 11 100010 0 ............ ..... ..... @addsub_imm
27
int desc = 0;
24
SUBS_i . 11 100010 1 ............ ..... ..... @addsub_imm12
28
25
+
29
- /*
26
+# Add/subtract (immediate with tags)
30
- * For e.g. LD4, there are not enough arguments to pass all 4
27
+
31
- * registers as pointers, so encode the regno into the data field.
28
+&rri_tag rd rn uimm6 uimm4
32
- * For consistency, do this even for LD1.
29
+@addsub_imm_tag . .. ...... . uimm6:6 .. uimm4:4 rn:5 rd:5 &rri_tag
33
- */
30
+
34
+ assert(mte_n >= 1 && mte_n <= 4);
31
+ADDG_i 1 00 100011 0 ...... 00 .... ..... ..... @addsub_imm_tag
35
if (s->mte_active[0]) {
32
+SUBG_i 1 10 100011 0 ...... 00 .... ..... ..... @addsub_imm_tag
36
int msz = dtype_msz(dtype);
33
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
37
34
index XXXXXXX..XXXXXXX 100644
38
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
35
--- a/target/arm/tcg/translate-a64.c
39
addr = clean_data_tbi(s, addr);
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;
73
}
40
}
74
41
75
- tcg_rn = cpu_reg_sp(s, rn);
42
+ /*
76
- tcg_rd = cpu_reg_sp(s, rd);
43
+ * For e.g. LD4, there are not enough arguments to pass all 4
77
+ tcg_rn = cpu_reg_sp(s, a->rn);
44
+ * registers as pointers, so encode the regno into the data field.
78
+ tcg_rd = cpu_reg_sp(s, a->rd);
45
+ * For consistency, do this even for LD1.
79
46
+ */
80
if (s->ata) {
47
desc = simd_desc(vsz, vsz, zt | desc);
81
gen_helper_addsubg(tcg_rd, cpu_env, tcg_rn,
48
t_pg = tcg_temp_new_ptr();
82
tcg_constant_i32(imm),
49
83
- tcg_constant_i32(uimm4));
50
@@ -XXX,XX +XXX,XX @@ static void do_ld_zpa(DisasContext *s, int zt, int pg,
84
+ tcg_constant_i32(a->uimm4));
51
* accessible via the instruction encoding.
52
*/
53
assert(fn != NULL);
54
- do_mem_zpa(s, zt, pg, addr, dtype, nreg, false, fn);
55
+ do_mem_zpa(s, zt, pg, addr, dtype, nreg + 1, false, fn);
56
}
57
58
static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a)
59
@@ -XXX,XX +XXX,XX @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
60
if (nreg == 0) {
61
/* ST1 */
62
fn = fn_single[s->mte_active[0]][be][msz][esz];
63
- nreg = 1;
85
} else {
64
} else {
86
tcg_gen_addi_i64(tcg_rd, tcg_rn, imm);
65
/* ST2, ST3, ST4 -- msz == esz, enforced by encoding */
87
gen_address_with_allocation_tag0(tcg_rd, tcg_rd);
66
assert(msz == esz);
67
fn = fn_multiple[s->mte_active[0]][be][nreg - 1][msz];
88
}
68
}
89
+ return true;
69
assert(fn != NULL);
70
- do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg, true, fn);
71
+ do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg + 1, true, fn);
90
}
72
}
91
73
92
+TRANS_FEAT(ADDG_i, aa64_mte_insn_reg, gen_add_sub_imm_with_tags, a, false)
74
static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a)
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;
108
--
75
--
109
2.34.1
76
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Convert the MON, MOVZ, MOVK instructions.
3
When we added SVE_MTEDESC_SHIFT, we effectively limited the
4
maximum size of MTEDESC. Adjust SIZEM1 to consume the remaining
5
bits (32 - 10 - 5 - 12 == 5). Assert that the data to be stored
6
fits within the field (expecting 8 * 4 - 1 == 31, exact fit).
4
7
8
Cc: qemu-stable@nongnu.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20240207025210.8837-4-richard.henderson@linaro.org
8
Message-id: 20230512144106.3608981-11-peter.maydell@linaro.org
9
[PMM: Rebased]
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
14
---
13
target/arm/tcg/a64.decode | 13 ++++++
15
target/arm/internals.h | 2 +-
14
target/arm/tcg/translate-a64.c | 73 ++++++++++++++--------------------
16
target/arm/tcg/translate-sve.c | 7 ++++---
15
2 files changed, 42 insertions(+), 44 deletions(-)
17
2 files changed, 5 insertions(+), 4 deletions(-)
16
18
17
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/tcg/a64.decode
21
--- a/target/arm/internals.h
20
+++ b/target/arm/tcg/a64.decode
22
+++ b/target/arm/internals.h
21
@@ -XXX,XX +XXX,XX @@ EOR_i . 10 100100 . ...... ...... ..... ..... @logic_imm_64
23
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, TBI, 4, 2)
22
EOR_i . 10 100100 . ...... ...... ..... ..... @logic_imm_32
24
FIELD(MTEDESC, TCMA, 6, 2)
23
ANDS_i . 11 100100 . ...... ...... ..... ..... @logic_imm_64
25
FIELD(MTEDESC, WRITE, 8, 1)
24
ANDS_i . 11 100100 . ...... ...... ..... ..... @logic_imm_32
26
FIELD(MTEDESC, ALIGN, 9, 3)
25
+
27
-FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - 12) /* size - 1 */
26
+# Move wide (immediate)
28
+FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - SVE_MTEDESC_SHIFT - 12) /* size - 1 */
27
+
29
28
+&movw rd sf imm hw
30
bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
29
+@movw_64 1 .. ...... hw:2 imm:16 rd:5 &movw sf=1
31
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
30
+@movw_32 0 .. ...... 0 hw:1 imm:16 rd:5 &movw sf=0
32
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
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
33
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/tcg/translate-a64.c
34
--- a/target/arm/tcg/translate-sve.c
41
+++ b/target/arm/tcg/translate-a64.c
35
+++ b/target/arm/tcg/translate-sve.c
42
@@ -XXX,XX +XXX,XX @@ TRANS(ANDS_i, gen_rri_log, a, true, tcg_gen_andi_i64)
36
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
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
{
37
{
60
- int rd = extract32(insn, 0, 5);
38
unsigned vsz = vec_full_reg_size(s);
61
- uint64_t imm = extract32(insn, 5, 16);
39
TCGv_ptr t_pg;
62
- int sf = extract32(insn, 31, 1);
40
+ uint32_t sizem1;
63
- int opc = extract32(insn, 29, 2);
41
int desc = 0;
64
- int pos = extract32(insn, 21, 2) << 4;
42
65
- TCGv_i64 tcg_rd = cpu_reg(s, rd);
43
assert(mte_n >= 1 && mte_n <= 4);
66
+ int pos = a->hw << 4;
44
+ sizem1 = (mte_n << dtype_msz(dtype)) - 1;
67
+ tcg_gen_movi_i64(cpu_reg(s, a->rd), (uint64_t)a->imm << pos);
45
+ assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
68
+ return true;
46
if (s->mte_active[0]) {
69
+}
47
- int msz = dtype_msz(dtype);
70
48
-
71
- if (!sf && (pos >= 32)) {
49
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
72
- unallocated_encoding(s);
50
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
73
- return;
51
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
74
- }
52
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
75
+static bool trans_MOVN(DisasContext *s, arg_movw *a)
53
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (mte_n << msz) - 1);
76
+{
54
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
77
+ int pos = a->hw << 4;
55
desc <<= SVE_MTEDESC_SHIFT;
78
+ uint64_t imm = a->imm;
56
} else {
79
57
addr = clean_data_tbi(s, addr);
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;
134
--
58
--
135
2.34.1
59
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Convert the ADD and SUB (immediate) instructions.
3
Share code that creates mtedesc and embeds within simd_desc.
4
4
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20240207025210.8837-5-richard.henderson@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>
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/tcg/translate.h | 5 +++
12
target/arm/tcg/translate-a64.h | 2 ++
14
target/arm/tcg/a64.decode | 17 ++++++++
13
target/arm/tcg/translate-sme.c | 15 +++--------
15
target/arm/tcg/translate-a64.c | 73 ++++++++++------------------------
14
target/arm/tcg/translate-sve.c | 47 ++++++++++++++++++----------------
16
3 files changed, 42 insertions(+), 53 deletions(-)
15
3 files changed, 31 insertions(+), 33 deletions(-)
17
16
18
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
17
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/tcg/translate.h
19
--- a/target/arm/tcg/translate-a64.h
21
+++ b/target/arm/tcg/translate.h
20
+++ b/target/arm/tcg/translate-a64.h
22
@@ -XXX,XX +XXX,XX @@ static inline int rsub_8(DisasContext *s, int x)
21
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
23
return 8 - x;
22
bool sve_access_check(DisasContext *s);
24
}
23
bool sme_enabled_check(DisasContext *s);
25
24
bool sme_enabled_check_with_svcr(DisasContext *s, unsigned);
26
+static inline int shl_12(DisasContext *s, int x)
25
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
27
+{
26
+ uint32_t msz, bool is_write, uint32_t data);
28
+ return x << 12;
27
28
/* This function corresponds to CheckStreamingSVEEnabled. */
29
static inline bool sme_sm_enabled_check(DisasContext *s)
30
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/tcg/translate-sme.c
33
+++ b/target/arm/tcg/translate-sme.c
34
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
35
36
TCGv_ptr t_za, t_pg;
37
TCGv_i64 addr;
38
- int svl, desc = 0;
39
+ uint32_t desc;
40
bool be = s->be_data == MO_BE;
41
bool mte = s->mte_active[0];
42
43
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
44
tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->esz);
45
tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
46
47
- if (mte) {
48
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
49
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
50
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
51
- desc = FIELD_DP32(desc, MTEDESC, WRITE, a->st);
52
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << a->esz) - 1);
53
- desc <<= SVE_MTEDESC_SHIFT;
54
- } else {
55
+ if (!mte) {
56
addr = clean_data_tbi(s, addr);
57
}
58
- svl = streaming_vec_reg_size(s);
59
- desc = simd_desc(svl, svl, desc);
60
+
61
+ desc = make_svemte_desc(s, streaming_vec_reg_size(s), 1, a->esz, a->st, 0);
62
63
fns[a->esz][be][a->v][mte][a->st](tcg_env, t_za, t_pg, addr,
64
tcg_constant_i32(desc));
65
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/tcg/translate-sve.c
68
+++ b/target/arm/tcg/translate-sve.c
69
@@ -XXX,XX +XXX,XX @@ static const uint8_t dtype_esz[16] = {
70
3, 2, 1, 3
71
};
72
73
-static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
74
- int dtype, uint32_t mte_n, bool is_write,
75
- gen_helper_gvec_mem *fn)
76
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
77
+ uint32_t msz, bool is_write, uint32_t data)
78
{
79
- unsigned vsz = vec_full_reg_size(s);
80
- TCGv_ptr t_pg;
81
uint32_t sizem1;
82
- int desc = 0;
83
+ uint32_t desc = 0;
84
85
- assert(mte_n >= 1 && mte_n <= 4);
86
- sizem1 = (mte_n << dtype_msz(dtype)) - 1;
87
+ /* Assert all of the data fits, with or without MTE enabled. */
88
+ assert(nregs >= 1 && nregs <= 4);
89
+ sizem1 = (nregs << msz) - 1;
90
assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
91
+ assert(data < 1u << SVE_MTEDESC_SHIFT);
92
+
93
if (s->mte_active[0]) {
94
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
95
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
96
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
97
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
98
desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
99
desc <<= SVE_MTEDESC_SHIFT;
100
- } else {
101
+ }
102
+ return simd_desc(vsz, vsz, desc | data);
29
+}
103
+}
30
+
104
+
31
static inline int neon_3same_fp_size(DisasContext *s, int x)
105
+static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
106
+ int dtype, uint32_t nregs, bool is_write,
107
+ gen_helper_gvec_mem *fn)
108
+{
109
+ TCGv_ptr t_pg;
110
+ uint32_t desc;
111
+
112
+ if (!s->mte_active[0]) {
113
addr = clean_data_tbi(s, addr);
114
}
115
116
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
117
* registers as pointers, so encode the regno into the data field.
118
* For consistency, do this even for LD1.
119
*/
120
- desc = simd_desc(vsz, vsz, zt | desc);
121
+ desc = make_svemte_desc(s, vec_full_reg_size(s), nregs,
122
+ dtype_msz(dtype), is_write, zt);
123
t_pg = tcg_temp_new_ptr();
124
125
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
126
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm,
127
int scale, TCGv_i64 scalar, int msz, bool is_write,
128
gen_helper_gvec_mem_scatter *fn)
32
{
129
{
33
/* Convert 0==fp32, 1==fp16 into a MO_* value */
130
- unsigned vsz = vec_full_reg_size(s);
34
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
131
TCGv_ptr t_zm = tcg_temp_new_ptr();
35
index XXXXXXX..XXXXXXX 100644
132
TCGv_ptr t_pg = tcg_temp_new_ptr();
36
--- a/target/arm/tcg/a64.decode
133
TCGv_ptr t_zt = tcg_temp_new_ptr();
37
+++ b/target/arm/tcg/a64.decode
134
- int desc = 0;
38
@@ -XXX,XX +XXX,XX @@
135
-
39
#
136
- if (s->mte_active[0]) {
40
137
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
41
&ri rd imm
138
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
42
+&rri_sf rd rn imm sf
139
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
43
140
- desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
44
141
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << msz) - 1);
45
### Data Processing - Immediate
142
- desc <<= SVE_MTEDESC_SHIFT;
46
@@ -XXX,XX +XXX,XX @@
143
- }
47
144
- desc = simd_desc(vsz, vsz, desc | scale);
48
ADR 0 .. 10000 ................... ..... @pcrel
145
+ uint32_t desc;
49
ADRP 1 .. 10000 ................... ..... @pcrel
146
147
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
148
tcg_gen_addi_ptr(t_zm, tcg_env, vec_full_reg_offset(s, zm));
149
tcg_gen_addi_ptr(t_zt, tcg_env, vec_full_reg_offset(s, zt));
50
+
150
+
51
+# Add/subtract (immediate)
151
+ desc = make_svemte_desc(s, vec_full_reg_size(s), 1, msz, is_write, scale);
52
+
152
fn(tcg_env, t_zt, t_pg, t_zm, scalar, tcg_constant_i32(desc));
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
}
153
}
73
154
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)
78
+{
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);
82
+
83
+ fn(tcg_rd, tcg_rn, tcg_imm);
84
+ if (!a->sf) {
85
+ tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
86
+ }
87
+ return true;
88
+}
89
+
90
/*
91
* PC-rel. addressing
92
*/
93
@@ -XXX,XX +XXX,XX @@ static bool trans_ADRP(DisasContext *s, arg_ri *a)
94
95
/*
96
* Add/subtract (immediate)
97
- *
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)
109
-{
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);
117
-
118
- TCGv_i64 tcg_rn = cpu_reg_sp(s, rn);
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;
124
- }
125
-
126
- tcg_result = tcg_temp_new_i64();
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
- }
140
- }
141
-
142
- if (is_64bit) {
143
- tcg_gen_mov_i64(tcg_rd, tcg_result);
144
- } else {
145
- tcg_gen_ext32u_i64(tcg_rd, tcg_result);
146
- }
147
-}
148
+TRANS(ADD_i, gen_rri, a, 1, 1, tcg_gen_add_i64)
149
+TRANS(SUB_i, gen_rri, a, 1, 1, tcg_gen_sub_i64)
150
+TRANS(ADDS_i, gen_rri, a, 0, 1, a->sf ? gen_add64_CC : gen_add32_CC)
151
+TRANS(SUBS_i, gen_rri, a, 0, 1, a->sf ? gen_sub64_CC : gen_sub32_CC)
152
153
/*
154
* Add/subtract (immediate, with tags)
155
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
156
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
157
{
158
switch (extract32(insn, 23, 6)) {
159
- case 0x22: /* Add/subtract (immediate) */
160
- disas_add_sub_imm(s, insn);
161
- break;
162
case 0x23: /* Add/subtract (immediate, with tags) */
163
disas_add_sub_imm_with_tags(s, insn);
164
break;
165
--
155
--
166
2.34.1
156
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Split out all of the decode stuff from aarch64_tr_translate_insn.
3
These functions "use the standard load helpers", but
4
Call it disas_a64_legacy to indicate it will be replaced.
4
fail to clean_data_tbi or populate mtedesc.
5
5
6
Cc: qemu-stable@nongnu.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20240207025210.8837-6-richard.henderson@linaro.org
9
Message-id: 20230512144106.3608981-2-peter.maydell@linaro.org
10
[PMM: Rebased]
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
12
---
14
target/arm/tcg/translate-a64.c | 82 ++++++++++++++++++----------------
13
target/arm/tcg/translate-sve.c | 15 +++++++++++++--
15
1 file changed, 44 insertions(+), 38 deletions(-)
14
1 file changed, 13 insertions(+), 2 deletions(-)
16
15
17
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
16
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/tcg/translate-a64.c
18
--- a/target/arm/tcg/translate-sve.c
20
+++ b/target/arm/tcg/translate-a64.c
19
+++ b/target/arm/tcg/translate-sve.c
21
@@ -XXX,XX +XXX,XX @@ static bool btype_destination_ok(uint32_t insn, bool bt, int btype)
20
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
22
return false;
21
unsigned vsz = vec_full_reg_size(s);
23
}
22
TCGv_ptr t_pg;
24
23
int poff;
25
+/* C3.1 A64 instruction index by encoding */
24
+ uint32_t desc;
26
+static void disas_a64_legacy(DisasContext *s, uint32_t insn)
25
27
+{
26
/* Load the first quadword using the normal predicated load helpers. */
28
+ switch (extract32(insn, 25, 4)) {
27
+ if (!s->mte_active[0]) {
29
+ case 0x0:
28
+ addr = clean_data_tbi(s, addr);
30
+ if (!extract32(insn, 31, 1) || !disas_sme(s, insn)) {
31
+ unallocated_encoding(s);
32
+ }
33
+ break;
34
+ case 0x1: case 0x3: /* UNALLOCATED */
35
+ unallocated_encoding(s);
36
+ break;
37
+ case 0x2:
38
+ if (!disas_sve(s, insn)) {
39
+ unallocated_encoding(s);
40
+ }
41
+ break;
42
+ case 0x8: case 0x9: /* Data processing - immediate */
43
+ disas_data_proc_imm(s, insn);
44
+ break;
45
+ case 0xa: case 0xb: /* Branch, exception generation and system insns */
46
+ disas_b_exc_sys(s, insn);
47
+ break;
48
+ case 0x4:
49
+ case 0x6:
50
+ case 0xc:
51
+ case 0xe: /* Loads and stores */
52
+ disas_ldst(s, insn);
53
+ break;
54
+ case 0x5:
55
+ case 0xd: /* Data processing - register */
56
+ disas_data_proc_reg(s, insn);
57
+ break;
58
+ case 0x7:
59
+ case 0xf: /* Data processing - SIMD and floating point */
60
+ disas_data_proc_simd_fp(s, insn);
61
+ break;
62
+ default:
63
+ assert(FALSE); /* all 15 cases should be handled above */
64
+ break;
65
+ }
29
+ }
66
+}
67
+
30
+
68
static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
31
poff = pred_full_reg_offset(s, pg);
69
CPUState *cpu)
32
if (vsz > 16) {
70
{
33
/*
71
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
34
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
72
disas_sme_fa64(s, insn);
35
36
gen_helper_gvec_mem *fn
37
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
38
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(16, 16, zt)));
39
+ desc = make_svemte_desc(s, 16, 1, dtype_msz(dtype), false, zt);
40
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
41
42
/* Replicate that first quadword. */
43
if (vsz > 16) {
44
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
45
unsigned vsz_r32;
46
TCGv_ptr t_pg;
47
int poff, doff;
48
+ uint32_t desc;
49
50
if (vsz < 32) {
51
/*
52
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
73
}
53
}
74
54
75
- switch (extract32(insn, 25, 4)) {
55
/* Load the first octaword using the normal predicated load helpers. */
76
- case 0x0:
56
+ if (!s->mte_active[0]) {
77
- if (!extract32(insn, 31, 1) || !disas_sme(s, insn)) {
57
+ addr = clean_data_tbi(s, addr);
78
- unallocated_encoding(s);
58
+ }
79
- }
59
80
- break;
60
poff = pred_full_reg_offset(s, pg);
81
- case 0x1: case 0x3: /* UNALLOCATED */
61
if (vsz > 32) {
82
- unallocated_encoding(s);
62
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
83
- break;
63
84
- case 0x2:
64
gen_helper_gvec_mem *fn
85
- if (!disas_sve(s, insn)) {
65
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
86
- unallocated_encoding(s);
66
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(32, 32, zt)));
87
- }
67
+ desc = make_svemte_desc(s, 32, 1, dtype_msz(dtype), false, zt);
88
- break;
68
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
89
- case 0x8: case 0x9: /* Data processing - immediate */
90
- disas_data_proc_imm(s, insn);
91
- break;
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
69
115
/*
70
/*
116
* After execution of most insns, btype is reset to 0.
71
* Replicate that first octaword.
117
--
72
--
118
2.34.1
73
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
If vd == vm, copy vm to scratch, so that we can pre-zero
3
The TBI and TCMA bits are located within mtedesc, not desc.
4
the output and still access the gather indicies.
5
4
6
Cc: qemu-stable@nongnu.org
5
Cc: qemu-stable@nongnu.org
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1612
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230504104232.1877774-1-richard.henderson@linaro.org
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20240207025210.8837-7-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
target/arm/tcg/sve_helper.c | 6 ++++++
12
target/arm/tcg/sme_helper.c | 8 ++++----
14
1 file changed, 6 insertions(+)
13
target/arm/tcg/sve_helper.c | 12 ++++++------
14
2 files changed, 10 insertions(+), 10 deletions(-)
15
15
16
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/tcg/sme_helper.c
19
+++ b/target/arm/tcg/sme_helper.c
20
@@ -XXX,XX +XXX,XX @@ void sme_ld1_mte(CPUARMState *env, void *za, uint64_t *vg,
21
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
22
23
/* Perform gross MTE suppression early. */
24
- if (!tbi_check(desc, bit55) ||
25
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
26
+ if (!tbi_check(mtedesc, bit55) ||
27
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
28
mtedesc = 0;
29
}
30
31
@@ -XXX,XX +XXX,XX @@ void sme_st1_mte(CPUARMState *env, void *za, uint64_t *vg, target_ulong addr,
32
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
33
34
/* Perform gross MTE suppression early. */
35
- if (!tbi_check(desc, bit55) ||
36
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
37
+ if (!tbi_check(mtedesc, bit55) ||
38
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
39
mtedesc = 0;
40
}
41
16
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
42
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
17
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/tcg/sve_helper.c
44
--- a/target/arm/tcg/sve_helper.c
19
+++ b/target/arm/tcg/sve_helper.c
45
+++ b/target/arm/tcg/sve_helper.c
20
@@ -XXX,XX +XXX,XX @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
46
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
21
intptr_t reg_off;
47
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
22
SVEHostPage info;
48
23
target_ulong addr, in_page;
49
/* Perform gross MTE suppression early. */
24
+ ARMVectorReg scratch;
50
- if (!tbi_check(desc, bit55) ||
25
51
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
26
/* Skip to the first true predicate. */
52
+ if (!tbi_check(mtedesc, bit55) ||
27
reg_off = find_next_active(vg, 0, reg_max, esz);
53
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
28
@@ -XXX,XX +XXX,XX @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
54
mtedesc = 0;
29
return;
30
}
55
}
31
56
32
+ /* Protect against overlap between vd and vm. */
57
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r_mte(CPUARMState *env, void *vg, target_ulong addr,
33
+ if (unlikely(vd == vm)) {
58
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
34
+ vm = memcpy(&scratch, vm, reg_max);
59
35
+ }
60
/* Perform gross MTE suppression early. */
36
+
61
- if (!tbi_check(desc, bit55) ||
37
/*
62
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
38
* Probe the first element, allowing faults.
63
+ if (!tbi_check(mtedesc, bit55) ||
39
*/
64
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
65
mtedesc = 0;
66
}
67
68
@@ -XXX,XX +XXX,XX @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
69
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
70
71
/* Perform gross MTE suppression early. */
72
- if (!tbi_check(desc, bit55) ||
73
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
74
+ if (!tbi_check(mtedesc, bit55) ||
75
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
76
mtedesc = 0;
77
}
78
40
--
79
--
41
2.34.1
80
2.34.1
diff view generated by jsdifflib
New patch
1
The raven_io_ops MemoryRegionOps is the only one in the source tree
2
which sets .valid.unaligned to indicate that it should support
3
unaligned accesses and which does not also set .impl.unaligned to
4
indicate that its read and write functions can do the unaligned
5
handling themselves. This is a problem, because at the moment the
6
core memory system does not implement the support for handling
7
unaligned accesses by doing a series of aligned accesses and
8
combining them (system/memory.c:access_with_adjusted_size() has a
9
TODO comment noting this).
1
10
11
Fortunately raven_io_read() and raven_io_write() will correctly deal
12
with the case of being passed an unaligned address, so we can fix the
13
missing unaligned access support by setting .impl.unaligned in the
14
MemoryRegionOps struct.
15
16
Fixes: 9a1839164c9c8f06 ("raven: Implement non-contiguous I/O region")
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Tested-by: Cédric Le Goater <clg@redhat.com>
19
Reviewed-by: Cédric Le Goater <clg@redhat.com>
20
Message-id: 20240112134640.1775041-1-peter.maydell@linaro.org
21
---
22
hw/pci-host/raven.c | 1 +
23
1 file changed, 1 insertion(+)
24
25
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/pci-host/raven.c
28
+++ b/hw/pci-host/raven.c
29
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps raven_io_ops = {
30
.write = raven_io_write,
31
.endianness = DEVICE_LITTLE_ENDIAN,
32
.impl.max_access_size = 4,
33
+ .impl.unaligned = true,
34
.valid.unaligned = true,
35
};
36
37
--
38
2.34.1
39
40
diff view generated by jsdifflib
1
Convert the u2f.txt file to rST, and place it in the right place
1
Suppress the deprecation warning when we're running under qtest,
2
in our manual layout. The old text didn't fit very well into our
2
to avoid "make check" including warning messages in its output.
3
manual style, so the new version ends up looking like a rewrite,
4
although some of the original text is preserved:
5
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
3
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
20
Message-id: 20230421163734.1152076-1-peter.maydell@linaro.org
6
Message-id: 20240206154151.155620-1-peter.maydell@linaro.org
21
---
7
---
22
docs/system/device-emulation.rst | 1 +
8
hw/block/tc58128.c | 4 +++-
23
docs/system/devices/usb-u2f.rst | 93 ++++++++++++++++++++++++++
9
1 file changed, 3 insertions(+), 1 deletion(-)
24
docs/system/devices/usb.rst | 2 +-
25
docs/u2f.txt | 110 -------------------------------
26
4 files changed, 95 insertions(+), 111 deletions(-)
27
create mode 100644 docs/system/devices/usb-u2f.rst
28
delete mode 100644 docs/u2f.txt
29
10
30
diff --git a/docs/system/device-emulation.rst b/docs/system/device-emulation.rst
11
diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c
31
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
32
--- a/docs/system/device-emulation.rst
13
--- a/hw/block/tc58128.c
33
+++ b/docs/system/device-emulation.rst
14
+++ b/hw/block/tc58128.c
34
@@ -XXX,XX +XXX,XX @@ Emulated Devices
15
@@ -XXX,XX +XXX,XX @@ static sh7750_io_device tc58128 = {
35
devices/virtio-pmem.rst
16
36
devices/vhost-user-rng.rst
17
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2)
37
devices/canokey.rst
18
{
38
+ devices/usb-u2f.rst
19
- warn_report_once("The TC58128 flash device is deprecated");
39
devices/igb.rst
20
+ if (!qtest_enabled()) {
40
diff --git a/docs/system/devices/usb-u2f.rst b/docs/system/devices/usb-u2f.rst
21
+ warn_report_once("The TC58128 flash device is deprecated");
41
new file mode 100644
22
+ }
42
index XXXXXXX..XXXXXXX
23
init_dev(&tc58128_devs[0], zone1);
43
--- /dev/null
24
init_dev(&tc58128_devs[1], zone2);
44
+++ b/docs/system/devices/usb-u2f.rst
25
return sh7750_register_io_device(s, &tc58128);
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
140
index XXXXXXX..XXXXXXX 100644
141
--- a/docs/system/devices/usb.rst
142
+++ b/docs/system/devices/usb.rst
143
@@ -XXX,XX +XXX,XX @@ option or the ``device_add`` monitor command. Available devices are:
144
USB audio device
145
146
``u2f-{emulated,passthru}``
147
- Universal Second Factor device
148
+ :doc:`usb-u2f`
149
150
``canokey``
151
An Open-source Secure Key implementing FIDO2, OpenPGP, PIV and more.
152
diff --git a/docs/u2f.txt b/docs/u2f.txt
153
deleted file mode 100644
154
index XXXXXXX..XXXXXXX
155
--- a/docs/u2f.txt
156
+++ /dev/null
157
@@ -XXX,XX +XXX,XX @@
158
-QEMU U2F Key Device Documentation.
159
-
160
-Contents
161
-1. USB U2F key device
162
-2. Building
163
-3. Using u2f-emulated
164
-4. Using u2f-passthru
165
-5. Libu2f-emu
166
-
167
-1. USB U2F key device
168
-
169
-U2F is an open authentication standard that enables relying parties
170
-exposed to the internet to offer a strong second factor option for end
171
-user authentication.
172
-
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.
268
--
26
--
269
2.34.1
27
2.34.1
28
29
diff view generated by jsdifflib
New patch
1
We deliberately don't include qtests_npcm7xx in qtests_aarch64,
2
because we already get the coverage of those tests via qtests_arm,
3
and we don't want to use extra CI minutes testing them twice.
1
4
5
In commit 327b680877b79c4b we added it to qtests_aarch64; revert
6
that change.
7
8
Fixes: 327b680877b79c4b ("tests/qtest: Creating qtest for GMAC Module")
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20240206163043.315535-1-peter.maydell@linaro.org
12
---
13
tests/qtest/meson.build | 1 -
14
1 file changed, 1 deletion(-)
15
16
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
17
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/qtest/meson.build
19
+++ b/tests/qtest/meson.build
20
@@ -XXX,XX +XXX,XX @@ qtests_aarch64 = \
21
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
22
(config_all_accel.has_key('CONFIG_TCG') and \
23
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
24
- (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
25
['arm-cpu-features',
26
'numa-test',
27
'boot-serial-test',
28
--
29
2.34.1
30
31
diff view generated by jsdifflib
1
The IMPDEF sysreg L2CTLR_EL1 found on the Cortex-A35, A53, A57, A72
1
Allow changes to the virt GTDT -- we are going to add the IRQ
2
and which we (arguably dubiously) also provide in '-cpu max' has a
2
entry for a new timer to it.
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.
10
11
Instead of just overflowing this 2-bit field, saturate to 3 (meaning
12
"4 CPUs", so at least we don't overwrite other fields in the register.
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.
17
18
This issue has been present since the L2CTLR was first added in
19
commit 377a44ec8f2fac5b back in 2014. It was only noticed because
20
Coverity complains (CID 1509227) that the shift might overflow 32 bits
21
and inadvertently sign extend into the top half of the 64 bit value.
22
3
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
25
Message-id: 20230512170223.3801643-2-peter.maydell@linaro.org
6
Message-id: 20240122143537.233498-2-peter.maydell@linaro.org
26
---
7
---
27
target/arm/cortex-regs.c | 11 +++++++++--
8
tests/qtest/bios-tables-test-allowed-diff.h | 2 ++
28
1 file changed, 9 insertions(+), 2 deletions(-)
9
1 file changed, 2 insertions(+)
29
10
30
diff --git a/target/arm/cortex-regs.c b/target/arm/cortex-regs.c
11
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
31
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cortex-regs.c
13
--- a/tests/qtest/bios-tables-test-allowed-diff.h
33
+++ b/target/arm/cortex-regs.c
14
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
34
@@ -XXX,XX +XXX,XX @@ static uint64_t l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
15
@@ -1 +1,3 @@
35
{
16
/* List of comma-separated changed AML files to ignore */
36
ARMCPU *cpu = env_archcpu(env);
17
+"tests/data/acpi/virt/FACP",
37
18
+"tests/data/acpi/virt/GTDT",
38
- /* Number of cores is in [25:24]; otherwise we RAZ */
39
- return (cpu->core_count - 1) << 24;
40
+ /*
41
+ * Number of cores is in [25:24]; otherwise we RAZ.
42
+ * If the board didn't configure the CPUs into clusters,
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[] = {
52
--
19
--
53
2.34.1
20
2.34.1
diff view generated by jsdifflib
1
From: Cornelia Huck <cohuck@redhat.com>
1
Armv8.1+ CPUs have the Virtual Host Extension (VHE) which adds a
2
2
non-secure EL2 virtual timer. We implemented the timer itself in the
3
Extend the 'mte' property for the virt machine to cover KVM as
3
CPU model, but never wired up its IRQ line to the GIC.
4
well. For KVM, we don't allocate tag memory, but instead enable the
4
5
capability.
5
Wire up the IRQ line (this is always safe whether the CPU has the
6
6
interrupt or not, since it always creates the outbound IRQ line).
7
If MTE has been enabled, we need to disable migration, as we do not
7
Report it to the guest via dtb and ACPI if the CPU has the feature.
8
yet have a way to migrate the tags as well. Therefore, MTE will stay
8
9
off with KVM unless requested explicitly.
9
The DTB binding is documented in the kernel's
10
10
Documentation/devicetree/bindings/timer/arm\,arch_timer.yaml
11
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
11
and the ACPI table entries are documented in the ACPI specification
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
version 6.3 or later.
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
14
Message-id: 20230428095533.21747-2-cohuck@redhat.com
14
Because the IRQ line ACPI binding is new in 6.3, we need to bump the
15
FADT table rev to show that we might be using 6.3 features.
16
17
Note that exposing this IRQ in the DTB will trigger a bug in EDK2
18
versions prior to edk2-stable202311, for users who use the virt board
19
with 'virtualization=on' to enable EL2 emulation and are booting an
20
EDK2 guest BIOS, if that EDK2 has assertions enabled. The effect is
21
that EDK2 will assert on bootup:
22
23
ASSERT [ArmTimerDxe] /home/kraxel/projects/qemu/roms/edk2/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.c(72): PropSize == 36 || PropSize == 48
24
25
If you see that assertion you should do one of:
26
* update your EDK2 binaries to edk2-stable202311 or newer
27
* use the 'virt-8.2' versioned machine type
28
* not use 'virtualization=on'
29
30
(The versions shipped with QEMU itself have the fix.)
31
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
34
Message-id: 20240122143537.233498-3-peter.maydell@linaro.org
16
---
35
---
17
target/arm/cpu.h | 4 +++
36
include/hw/arm/virt.h | 2 ++
18
target/arm/kvm_arm.h | 19 ++++++++++++
37
hw/arm/virt-acpi-build.c | 20 ++++++++++----
19
hw/arm/virt.c | 73 +++++++++++++++++++++++++-------------------
38
hw/arm/virt.c | 60 ++++++++++++++++++++++++++++++++++------
20
target/arm/cpu.c | 9 +++---
39
3 files changed, 67 insertions(+), 15 deletions(-)
21
target/arm/kvm.c | 35 +++++++++++++++++++++
40
22
target/arm/kvm64.c | 5 +++
41
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
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
42
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu.h
43
--- a/include/hw/arm/virt.h
28
+++ b/target/arm/cpu.h
44
+++ b/include/hw/arm/virt.h
29
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
45
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
30
*/
46
/* Machines < 6.2 have no support for describing cpu topology to guest */
31
uint32_t psci_conduit;
47
bool no_cpu_topology;
32
48
bool no_tcg_lpa2;
33
+ /* CPU has Memory Tag Extension */
49
+ bool no_ns_el2_virt_timer_irq;
34
+ bool has_mte;
50
};
35
+
51
36
/* For v8M, initial value of the Secure VTOR */
52
struct VirtMachineState {
37
uint32_t init_svtor;
53
@@ -XXX,XX +XXX,XX @@ struct VirtMachineState {
38
/* For v8M, initial value of the Non-secure VTOR */
54
PCIBus *bus;
39
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
55
char *oem_id;
40
bool prop_pauth;
56
char *oem_table_id;
41
bool prop_pauth_impdef;
57
+ bool ns_el2_virt_timer_irq;
42
bool prop_lpa2;
58
};
43
+ OnOffAuto prop_mte;
59
44
60
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
45
/* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
61
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
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
62
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/kvm_arm.h
63
--- a/hw/arm/virt-acpi-build.c
50
+++ b/target/arm/kvm_arm.h
64
+++ b/hw/arm/virt-acpi-build.c
51
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_pmu_supported(void);
65
@@ -XXX,XX +XXX,XX @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
66
}
67
68
/*
69
- * ACPI spec, Revision 5.1
70
- * 5.2.24 Generic Timer Description Table (GTDT)
71
+ * ACPI spec, Revision 6.5
72
+ * 5.2.25 Generic Timer Description Table (GTDT)
52
*/
73
*/
53
bool kvm_arm_sve_supported(void);
74
static void
54
75
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
55
+/**
76
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
56
+ * kvm_arm_mte_supported:
77
uint32_t irqflags = vmc->claim_edge_triggered_timers ?
57
+ *
78
1 : /* Interrupt is Edge triggered */
58
+ * Returns: true if KVM can enable MTE, and false otherwise.
79
0; /* Interrupt is Level triggered */
59
+ */
80
- AcpiTable table = { .sig = "GTDT", .rev = 2, .oem_id = vms->oem_id,
60
+bool kvm_arm_mte_supported(void);
81
+ AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id,
61
+
82
.oem_table_id = vms->oem_table_id };
62
/**
83
63
* kvm_arm_get_max_vm_ipa_size:
84
acpi_table_begin(&table, table_data);
64
* @ms: Machine state handle
85
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
65
@@ -XXX,XX +XXX,XX @@ void kvm_arm_pvtime_init(CPUState *cs, uint64_t ipa);
86
build_append_int_noprefix(table_data, 0, 4);
66
87
/* Platform Timer Offset */
67
int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level);
88
build_append_int_noprefix(table_data, 0, 4);
68
89
-
69
+void kvm_arm_enable_mte(Object *cpuobj, Error **errp);
90
+ if (vms->ns_el2_virt_timer_irq) {
70
+
91
+ /* Virtual EL2 Timer GSIV */
71
#else
92
+ build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL2_VIRT_IRQ, 4);
72
93
+ /* Virtual EL2 Timer Flags */
73
/*
94
+ build_append_int_noprefix(table_data, irqflags, 4);
74
@@ -XXX,XX +XXX,XX @@ static inline bool kvm_arm_steal_time_supported(void)
95
+ } else {
75
return false;
96
+ build_append_int_noprefix(table_data, 0, 4);
76
}
97
+ build_append_int_noprefix(table_data, 0, 4);
77
98
+ }
78
+static inline bool kvm_arm_mte_supported(void)
99
acpi_table_end(linker, &table);
79
+{
100
}
80
+ return false;
101
81
+}
102
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
82
+
103
static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker,
83
/*
104
VirtMachineState *vms, unsigned dsdt_tbl_offset)
84
* These functions should never actually be called without KVM support.
105
{
85
*/
106
- /* ACPI v6.0 */
86
@@ -XXX,XX +XXX,XX @@ static inline uint32_t kvm_arm_sve_get_vls(CPUState *cs)
107
+ /* ACPI v6.3 */
87
g_assert_not_reached();
108
AcpiFadtData fadt = {
88
}
109
.rev = 6,
89
110
- .minor_ver = 0,
90
+static inline void kvm_arm_enable_mte(Object *cpuobj, Error **errp)
111
+ .minor_ver = 3,
91
+{
112
.flags = 1 << ACPI_FADT_F_HW_REDUCED_ACPI,
92
+ g_assert_not_reached();
113
.xdsdt_tbl_offset = &dsdt_tbl_offset,
93
+}
114
};
94
+
95
#endif
96
97
static inline const char *gic_class_name(void)
98
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
115
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
99
index XXXXXXX..XXXXXXX 100644
116
index XXXXXXX..XXXXXXX 100644
100
--- a/hw/arm/virt.c
117
--- a/hw/arm/virt.c
101
+++ b/hw/arm/virt.c
118
+++ b/hw/arm/virt.c
119
@@ -XXX,XX +XXX,XX @@ static void create_randomness(MachineState *ms, const char *node)
120
qemu_fdt_setprop(ms->fdt, node, "rng-seed", seed.rng, sizeof(seed.rng));
121
}
122
123
+/*
124
+ * The CPU object always exposes the NS EL2 virt timer IRQ line,
125
+ * but we don't want to advertise it to the guest in the dtb or ACPI
126
+ * table unless it's really going to do something.
127
+ */
128
+static bool ns_el2_virt_timer_present(void)
129
+{
130
+ ARMCPU *cpu = ARM_CPU(qemu_get_cpu(0));
131
+ CPUARMState *env = &cpu->env;
132
+
133
+ return arm_feature(env, ARM_FEATURE_AARCH64) &&
134
+ arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu);
135
+}
136
+
137
static void create_fdt(VirtMachineState *vms)
138
{
139
MachineState *ms = MACHINE(vms);
140
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
141
"arm,armv7-timer");
142
}
143
qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0);
144
- qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
145
- GIC_FDT_IRQ_TYPE_PPI,
146
- INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
147
- GIC_FDT_IRQ_TYPE_PPI,
148
- INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
149
- GIC_FDT_IRQ_TYPE_PPI,
150
- INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
151
- GIC_FDT_IRQ_TYPE_PPI,
152
- INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
153
+ if (vms->ns_el2_virt_timer_irq) {
154
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
155
+ GIC_FDT_IRQ_TYPE_PPI,
156
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
157
+ GIC_FDT_IRQ_TYPE_PPI,
158
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
159
+ GIC_FDT_IRQ_TYPE_PPI,
160
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
161
+ GIC_FDT_IRQ_TYPE_PPI,
162
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags,
163
+ GIC_FDT_IRQ_TYPE_PPI,
164
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_VIRT_IRQ), irqflags);
165
+ } else {
166
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
167
+ GIC_FDT_IRQ_TYPE_PPI,
168
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
169
+ GIC_FDT_IRQ_TYPE_PPI,
170
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
171
+ GIC_FDT_IRQ_TYPE_PPI,
172
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
173
+ GIC_FDT_IRQ_TYPE_PPI,
174
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
175
+ }
176
}
177
178
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
179
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
180
[GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
181
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
182
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
183
+ [GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
184
};
185
186
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
102
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
187
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
103
exit(1);
188
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
189
object_unref(cpuobj);
104
}
190
}
105
191
+
106
- if (vms->mte && (kvm_enabled() || hvf_enabled())) {
192
+ /* Now we've created the CPUs we can see if they have the hypvirt timer */
107
+ if (vms->mte && hvf_enabled()) {
193
+ vms->ns_el2_virt_timer_irq = ns_el2_virt_timer_present() &&
108
error_report("mach-virt: %s does not support providing "
194
+ !vmc->no_ns_el2_virt_timer_irq;
109
"MTE to the guest CPU",
195
+
110
current_accel_name());
196
fdt_add_timer_nodes(vms);
111
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
197
fdt_add_cpu_nodes(vms);
112
}
198
113
199
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(9, 0)
114
if (vms->mte) {
200
115
- /* Create the memory region only once, but link to all cpus. */
201
static void virt_machine_8_2_options(MachineClass *mc)
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;
200
}
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
{
202
{
241
}
203
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
242
+
204
+
243
+void kvm_arm_enable_mte(Object *cpuobj, Error **errp)
205
virt_machine_9_0_options(mc);
244
+{
206
compat_props_add(mc->compat_props, hw_compat_8_2, hw_compat_8_2_len);
245
+ static bool tried_to_enable;
207
+ /*
246
+ static bool succeeded_to_enable;
208
+ * Don't expose NS_EL2_VIRT timer IRQ in DTB on ACPI on 8.2 and
247
+ Error *mte_migration_blocker = NULL;
209
+ * earlier machines. (Exposing it tickles a bug in older EDK2
248
+ int ret;
210
+ * guest BIOS binaries.)
249
+
211
+ */
250
+ if (!tried_to_enable) {
212
+ vmc->no_ns_el2_virt_timer_irq = true;
251
+ /*
213
}
252
+ * MTE on KVM is enabled on a per-VM basis (and retrying doesn't make
214
DEFINE_VIRT_MACHINE(8, 2)
253
+ * sense), and we only want a single migration blocker as well.
215
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)
292
--
216
--
293
2.34.1
217
2.34.1
diff view generated by jsdifflib
1
Convert the last four BR-with-pointer-auth insns to decodetree.
1
Update the virt golden reference files to say that the FACP is ACPI
2
The remaining cases in the outer switch in disas_uncond_b_reg()
2
v6.3, and the GTDT table is a revision 3 table with space for the
3
all return early rather than leaving the case statement, so we
3
virtual EL2 timer.
4
can delete the now-unused code at the end of that function.
4
5
Diffs from iasl:
6
7
@@ -XXX,XX +XXX,XX @@
8
/*
9
* Intel ACPI Component Architecture
10
* AML/ASL+ Disassembler version 20200925 (64-bit version)
11
* Copyright (c) 2000 - 2020 Intel Corporation
12
*
13
- * Disassembly of tests/data/acpi/virt/FACP, Mon Jan 22 13:48:40 2024
14
+ * Disassembly of /tmp/aml-W8RZH2, Mon Jan 22 13:48:40 2024
15
*
16
* ACPI Data Table [FACP]
17
*
18
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
19
*/
20
21
[000h 0000 4] Signature : "FACP" [Fixed ACPI Description Table (FADT)]
22
[004h 0004 4] Table Length : 00000114
23
[008h 0008 1] Revision : 06
24
-[009h 0009 1] Checksum : 15
25
+[009h 0009 1] Checksum : 12
26
[00Ah 0010 6] Oem ID : "BOCHS "
27
[010h 0016 8] Oem Table ID : "BXPC "
28
[018h 0024 4] Oem Revision : 00000001
29
[01Ch 0028 4] Asl Compiler ID : "BXPC"
30
[020h 0032 4] Asl Compiler Revision : 00000001
31
32
[024h 0036 4] FACS Address : 00000000
33
[028h 0040 4] DSDT Address : 00000000
34
[02Ch 0044 1] Model : 00
35
[02Dh 0045 1] PM Profile : 00 [Unspecified]
36
[02Eh 0046 2] SCI Interrupt : 0000
37
[030h 0048 4] SMI Command Port : 00000000
38
[034h 0052 1] ACPI Enable Value : 00
39
[035h 0053 1] ACPI Disable Value : 00
40
[036h 0054 1] S4BIOS Command : 00
41
[037h 0055 1] P-State Control : 00
42
@@ -XXX,XX +XXX,XX @@
43
Use APIC Physical Destination Mode (V4) : 0
44
Hardware Reduced (V5) : 1
45
Low Power S0 Idle (V5) : 0
46
47
[074h 0116 12] Reset Register : [Generic Address Structure]
48
[074h 0116 1] Space ID : 00 [SystemMemory]
49
[075h 0117 1] Bit Width : 00
50
[076h 0118 1] Bit Offset : 00
51
[077h 0119 1] Encoded Access Width : 00 [Undefined/Legacy]
52
[078h 0120 8] Address : 0000000000000000
53
54
[080h 0128 1] Value to cause reset : 00
55
[081h 0129 2] ARM Flags (decoded below) : 0003
56
PSCI Compliant : 1
57
Must use HVC for PSCI : 1
58
59
-[083h 0131 1] FADT Minor Revision : 00
60
+[083h 0131 1] FADT Minor Revision : 03
61
[084h 0132 8] FACS Address : 0000000000000000
62
[08Ch 0140 8] DSDT Address : 0000000000000000
63
[094h 0148 12] PM1A Event Block : [Generic Address Structure]
64
[094h 0148 1] Space ID : 00 [SystemMemory]
65
[095h 0149 1] Bit Width : 00
66
[096h 0150 1] Bit Offset : 00
67
[097h 0151 1] Encoded Access Width : 00 [Undefined/Legacy]
68
[098h 0152 8] Address : 0000000000000000
69
70
[0A0h 0160 12] PM1B Event Block : [Generic Address Structure]
71
[0A0h 0160 1] Space ID : 00 [SystemMemory]
72
[0A1h 0161 1] Bit Width : 00
73
[0A2h 0162 1] Bit Offset : 00
74
[0A3h 0163 1] Encoded Access Width : 00 [Undefined/Legacy]
75
[0A4h 0164 8] Address : 0000000000000000
76
77
@@ -XXX,XX +XXX,XX @@
78
[0F5h 0245 1] Bit Width : 00
79
[0F6h 0246 1] Bit Offset : 00
80
[0F7h 0247 1] Encoded Access Width : 00 [Undefined/Legacy]
81
[0F8h 0248 8] Address : 0000000000000000
82
83
[100h 0256 12] Sleep Status Register : [Generic Address Structure]
84
[100h 0256 1] Space ID : 00 [SystemMemory]
85
[101h 0257 1] Bit Width : 00
86
[102h 0258 1] Bit Offset : 00
87
[103h 0259 1] Encoded Access Width : 00 [Undefined/Legacy]
88
[104h 0260 8] Address : 0000000000000000
89
90
[10Ch 0268 8] Hypervisor ID : 00000000554D4551
91
92
Raw Table Data: Length 276 (0x114)
93
94
- 0000: 46 41 43 50 14 01 00 00 06 15 42 4F 43 48 53 20 // FACP......BOCHS
95
+ 0000: 46 41 43 50 14 01 00 00 06 12 42 4F 43 48 53 20 // FACP......BOCHS
96
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
97
0020: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
98
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
99
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
100
0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
101
0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
102
0070: 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
103
- 0080: 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
104
+ 0080: 00 03 00 03 00 00 00 00 00 00 00 00 00 00 00 00 // ................
105
0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
106
00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
107
00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
108
00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
109
00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
110
00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
111
00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
112
0100: 00 00 00 00 00 00 00 00 00 00 00 00 51 45 4D 55 // ............QEMU
113
0110: 00 00 00 00 // ....
114
115
@@ -XXX,XX +XXX,XX @@
116
/*
117
* Intel ACPI Component Architecture
118
* AML/ASL+ Disassembler version 20200925 (64-bit version)
119
* Copyright (c) 2000 - 2020 Intel Corporation
120
*
121
- * Disassembly of tests/data/acpi/virt/GTDT, Mon Jan 22 13:48:40 2024
122
+ * Disassembly of /tmp/aml-XDSZH2, Mon Jan 22 13:48:40 2024
123
*
124
* ACPI Data Table [GTDT]
125
*
126
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
127
*/
128
129
[000h 0000 4] Signature : "GTDT" [Generic Timer Description Table]
130
-[004h 0004 4] Table Length : 00000060
131
-[008h 0008 1] Revision : 02
132
-[009h 0009 1] Checksum : 9C
133
+[004h 0004 4] Table Length : 00000068
134
+[008h 0008 1] Revision : 03
135
+[009h 0009 1] Checksum : 93
136
[00Ah 0010 6] Oem ID : "BOCHS "
137
[010h 0016 8] Oem Table ID : "BXPC "
138
[018h 0024 4] Oem Revision : 00000001
139
[01Ch 0028 4] Asl Compiler ID : "BXPC"
140
[020h 0032 4] Asl Compiler Revision : 00000001
141
142
[024h 0036 8] Counter Block Address : FFFFFFFFFFFFFFFF
143
[02Ch 0044 4] Reserved : 00000000
144
145
[030h 0048 4] Secure EL1 Interrupt : 0000001D
146
[034h 0052 4] EL1 Flags (decoded below) : 00000000
147
Trigger Mode : 0
148
Polarity : 0
149
Always On : 0
150
151
[038h 0056 4] Non-Secure EL1 Interrupt : 0000001E
152
@@ -XXX,XX +XXX,XX @@
153
154
[040h 0064 4] Virtual Timer Interrupt : 0000001B
155
[044h 0068 4] VT Flags (decoded below) : 00000000
156
Trigger Mode : 0
157
Polarity : 0
158
Always On : 0
159
160
[048h 0072 4] Non-Secure EL2 Interrupt : 0000001A
161
[04Ch 0076 4] NEL2 Flags (decoded below) : 00000000
162
Trigger Mode : 0
163
Polarity : 0
164
Always On : 0
165
[050h 0080 8] Counter Read Block Address : FFFFFFFFFFFFFFFF
166
167
[058h 0088 4] Platform Timer Count : 00000000
168
[05Ch 0092 4] Platform Timer Offset : 00000000
169
+[060h 0096 4] Virtual EL2 Timer GSIV : 00000000
170
+[064h 0100 4] Virtual EL2 Timer Flags : 00000000
171
172
-Raw Table Data: Length 96 (0x60)
173
+Raw Table Data: Length 104 (0x68)
174
175
- 0000: 47 54 44 54 60 00 00 00 02 9C 42 4F 43 48 53 20 // GTDT`.....BOCHS
176
+ 0000: 47 54 44 54 68 00 00 00 03 93 42 4F 43 48 53 20 // GTDTh.....BOCHS
177
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
178
0020: 01 00 00 00 FF FF FF FF FF FF FF FF 00 00 00 00 // ................
179
0030: 1D 00 00 00 00 00 00 00 1E 00 00 00 04 00 00 00 // ................
180
0040: 1B 00 00 00 00 00 00 00 1A 00 00 00 00 00 00 00 // ................
181
0050: FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 // ................
182
+ 0060: 00 00 00 00 00 00 00 00 // ........
5
183
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
184
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
185
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
8
Message-id: 20230512144106.3608981-20-peter.maydell@linaro.org
186
Message-id: 20240122143537.233498-4-peter.maydell@linaro.org
9
---
187
---
10
target/arm/tcg/a64.decode | 4 ++
188
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
11
target/arm/tcg/translate-a64.c | 97 ++++++++++++++--------------------
189
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
12
2 files changed, 43 insertions(+), 58 deletions(-)
190
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
13
191
3 files changed, 2 deletions(-)
14
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
192
193
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
15
index XXXXXXX..XXXXXXX 100644
194
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/tcg/a64.decode
195
--- a/tests/qtest/bios-tables-test-allowed-diff.h
17
+++ b/target/arm/tcg/a64.decode
196
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
18
@@ -XXX,XX +XXX,XX @@ BLRAZ 1101011 0001 11111 00001 m:1 rn:5 11111 &braz # BLRAAZ, BLRABZ
197
@@ -1,3 +1 @@
19
198
/* List of comma-separated changed AML files to ignore */
20
&reta m
199
-"tests/data/acpi/virt/FACP",
21
RETA 1101011 0010 11111 00001 m:1 11111 11111 &reta # RETAA, RETAB
200
-"tests/data/acpi/virt/GTDT",
22
+
201
diff --git a/tests/data/acpi/virt/FACP b/tests/data/acpi/virt/FACP
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
202
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/tcg/translate-a64.c
203
GIT binary patch
29
+++ b/target/arm/tcg/translate-a64.c
204
delta 25
30
@@ -XXX,XX +XXX,XX @@ static bool trans_RETA(DisasContext *s, arg_reta *a)
205
gcmbQjG=+)F&CxkPgpq-PO=u!l<;2F$$vli407<0<)c^nh
31
return true;
206
32
}
207
delta 28
33
208
kcmbQjG=+)F&CxkPgpq-PO>`nx<-|!<6Akz$^DuG%0AAS!ssI20
34
+static bool trans_BRA(DisasContext *s, arg_bra *a)
209
35
+{
210
diff --git a/tests/data/acpi/virt/GTDT b/tests/data/acpi/virt/GTDT
36
+ TCGv_i64 dst;
211
index XXXXXXX..XXXXXXX 100644
37
+
212
GIT binary patch
38
+ if (!dc_isar_feature(aa64_pauth, s)) {
213
delta 25
39
+ return false;
214
bcmYeu;BpUf3CUn!U|^m+kt>V?$N&QXMtB4L
40
+ }
215
41
+ dst = auth_branch_target(s, cpu_reg(s,a->rn), cpu_reg_sp(s, a->rm), !a->m);
216
delta 16
42
+ gen_a64_set_pc(s, dst);
217
Xcmc~u;BpUf2}xjJU|^avkt+-UB60)u
43
+ set_btype_for_br(s, a->rn);
218
44
+ s->base.is_jmp = DISAS_JUMP;
45
+ return true;
46
+}
47
+
48
+static bool trans_BLRA(DisasContext *s, arg_bra *a)
49
+{
50
+ TCGv_i64 dst, lr;
51
+
52
+ if (!dc_isar_feature(aa64_pauth, s)) {
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;
156
}
157
158
/* Branches, exception generating and system instructions */
159
--
219
--
160
2.34.1
220
2.34.1
diff view generated by jsdifflib
New patch
1
The patchset adding the GMAC ethernet to this SoC crossed in the
2
mail with the patchset cleaning up the NIC handling. When we
3
create the GMAC modules we must call qemu_configure_nic_device()
4
so that the user has the opportunity to use the -nic commandline
5
option to create a network backend and connect it to the GMACs.
1
6
7
Add the missing call.
8
9
Fixes: 21e5326a7c ("hw/arm: Add GMAC devices to NPCM7XX SoC")
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
12
Message-id: 20240206171231.396392-2-peter.maydell@linaro.org
13
---
14
hw/arm/npcm7xx.c | 1 +
15
1 file changed, 1 insertion(+)
16
17
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/npcm7xx.c
20
+++ b/hw/arm/npcm7xx.c
21
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
22
for (i = 0; i < ARRAY_SIZE(s->gmac); i++) {
23
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->gmac[i]);
24
25
+ qemu_configure_nic_device(DEVICE(sbd), false, NULL);
26
/*
27
* The device exists regardless of whether it's connected to a QEMU
28
* netdev backend. So always instantiate it even if there is no
29
--
30
2.34.1
diff view generated by jsdifflib
1
Convert the immediate conditional branch insn B.cond to
1
Currently QEMU will warn if there is a NIC on the board that
2
decodetree.
2
is not connected to a backend. By default the '-nic user' will
3
get used for all NICs, but if you manually connect a specific
4
NIC to a specific backend, then the other NICs on the board
5
have no backend and will be warned about:
6
7
qemu-system-arm: warning: nic npcm7xx-emc.1 has no peer
8
qemu-system-arm: warning: nic npcm-gmac.0 has no peer
9
qemu-system-arm: warning: nic npcm-gmac.1 has no peer
10
11
So suppress those warnings by manually connecting every NIC
12
on the board to some backend.
3
13
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
6
Message-id: 20230512144106.3608981-17-peter.maydell@linaro.org
16
Reviewed-by: Thomas Huth <thuth@redhat.com>
17
Message-id: 20240206171231.396392-3-peter.maydell@linaro.org
7
---
18
---
8
target/arm/tcg/a64.decode | 2 ++
19
tests/qtest/npcm7xx_emc-test.c | 5 ++++-
9
target/arm/tcg/translate-a64.c | 30 ++++++------------------------
20
1 file changed, 4 insertions(+), 1 deletion(-)
10
2 files changed, 8 insertions(+), 24 deletions(-)
11
21
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
22
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
13
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/a64.decode
24
--- a/tests/qtest/npcm7xx_emc-test.c
15
+++ b/target/arm/tcg/a64.decode
25
+++ b/tests/qtest/npcm7xx_emc-test.c
16
@@ -XXX,XX +XXX,XX @@ CBZ sf:1 011010 nz:1 ................... rt:5 &cbz imm=%imm19
26
@@ -XXX,XX +XXX,XX @@ static int *packet_test_init(int module_num, GString *cmd_line)
17
&tbz rt imm nz bitpos
27
* KISS and use -nic. The driver accepts 'emc0' and 'emc1' as aliases
18
28
* in the 'model' field to specify the device to match.
19
TBZ . 011011 nz:1 ..... .............. rt:5 &tbz imm=%imm14 bitpos=%imm31_19
29
*/
20
+
30
- g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d ",
21
+B_cond 0101010 0 ................... 0 cond:4 imm=%imm19
31
+ g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d "
22
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
32
+ "-nic user,model=npcm7xx-emc "
23
index XXXXXXX..XXXXXXX 100644
33
+ "-nic user,model=npcm-gmac "
24
--- a/target/arm/tcg/translate-a64.c
34
+ "-nic user,model=npcm-gmac",
25
+++ b/target/arm/tcg/translate-a64.c
35
test_sockets[1], module_num);
26
@@ -XXX,XX +XXX,XX @@ static bool trans_TBZ(DisasContext *s, arg_tbz *a)
36
27
return true;
37
g_test_queue_destroy(packet_test_clear, test_sockets);
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;
41
-
42
- if ((insn & (1 << 4)) || (insn & (1 << 24))) {
43
- unallocated_encoding(s);
44
- return;
45
- }
46
- diff = sextract32(insn, 5, 19) * 4;
47
- cond = extract32(insn, 0, 4);
48
-
49
reset_btype(s);
50
- if (cond < 0x0e) {
51
+ if (a->cond < 0x0e) {
52
/* genuinely conditional branches */
53
DisasLabel match = gen_disas_label(s);
54
- arm_gen_test_cc(cond, match.label);
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) {
79
--
38
--
80
2.34.1
39
2.34.1
diff view generated by jsdifflib
New patch
1
It doesn't make sense to read the value of MDCR_EL2 on a non-A-profile
2
CPU, and in fact if you try to do it we will assert:
1
3
4
#6 0x00007ffff4b95e96 in __GI___assert_fail
5
(assertion=0x5555565a8c70 "!arm_feature(env, ARM_FEATURE_M)", file=0x5555565a6e5c "../../target/arm/helper.c", line=12600, function=0x5555565a9560 <__PRETTY_FUNCTION__.0> "arm_security_space_below_el3") at ./assert/assert.c:101
6
#7 0x0000555555ebf412 in arm_security_space_below_el3 (env=0x555557bc8190) at ../../target/arm/helper.c:12600
7
#8 0x0000555555ea6f89 in arm_is_el2_enabled (env=0x555557bc8190) at ../../target/arm/cpu.h:2595
8
#9 0x0000555555ea942f in arm_mdcr_el2_eff (env=0x555557bc8190) at ../../target/arm/internals.h:1512
9
10
We might call pmu_counter_enabled() on an M-profile CPU (for example
11
from the migration pre/post hooks in machine.c); this should always
12
return false because these CPUs don't set ARM_FEATURE_PMU.
13
14
Avoid the assertion by not calling arm_mdcr_el2_eff() before we
15
have done the early return for "PMU not present".
16
17
This fixes an assertion failure if you try to do a loadvm or
18
savevm for an M-profile board.
19
20
Cc: qemu-stable@nongnu.org
21
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2155
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20240208153346.970021-1-peter.maydell@linaro.org
26
---
27
target/arm/helper.c | 12 ++++++++++--
28
1 file changed, 10 insertions(+), 2 deletions(-)
29
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.c
33
+++ b/target/arm/helper.c
34
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
35
bool enabled, prohibited = false, filtered;
36
bool secure = arm_is_secure(env);
37
int el = arm_current_el(env);
38
- uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
39
- uint8_t hpmn = mdcr_el2 & MDCR_HPMN;
40
+ uint64_t mdcr_el2;
41
+ uint8_t hpmn;
42
43
+ /*
44
+ * We might be called for M-profile cores where MDCR_EL2 doesn't
45
+ * exist and arm_mdcr_el2_eff() will assert, so this early-exit check
46
+ * must be before we read that value.
47
+ */
48
if (!arm_feature(env, ARM_FEATURE_PMU)) {
49
return false;
50
}
51
52
+ mdcr_el2 = arm_mdcr_el2_eff(env);
53
+ hpmn = mdcr_el2 & MDCR_HPMN;
54
+
55
if (!arm_feature(env, ARM_FEATURE_EL2) ||
56
(counter < hpmn || counter == 31)) {
57
e = env->cp15.c9_pmcr & PMCRE;
58
--
59
2.34.1
60
61
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Nabih Estefan <nabihestefan@google.com>
2
2
3
Convert the ADD, ORR, EOR, ANDS (immediate) instructions.
3
Fix the nocm_gmac-test.c file to run on a nuvoton 7xx machine instead
4
of 8xx. Also fix comments referencing this and values expecting 8xx.
4
5
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Change-Id: Iabd0fba14910c3f1e883c4a9521350f3db9ffab8
7
Signed-Off-By: Nabih Estefan <nabihestefan@google.com>
8
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
9
Message-id: 20240208194759.2858582-2-nabihestefan@google.com
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
[PMM: commit message tweaks]
8
Message-id: 20230512144106.3608981-10-peter.maydell@linaro.org
9
[PMM: rebased]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
target/arm/tcg/a64.decode | 15 ++++++
14
tests/qtest/npcm_gmac-test.c | 84 +-----------------------------------
13
target/arm/tcg/translate-a64.c | 94 +++++++++++-----------------------
15
tests/qtest/meson.build | 3 +-
14
2 files changed, 44 insertions(+), 65 deletions(-)
16
2 files changed, 4 insertions(+), 83 deletions(-)
15
17
16
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
18
diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/tcg/a64.decode
20
--- a/tests/qtest/npcm_gmac-test.c
19
+++ b/target/arm/tcg/a64.decode
21
+++ b/tests/qtest/npcm_gmac-test.c
20
@@ -XXX,XX +XXX,XX @@ SUBS_i . 11 100010 1 ............ ..... ..... @addsub_imm12
22
@@ -XXX,XX +XXX,XX @@ typedef struct TestData {
21
23
const GMACModule *module;
22
ADDG_i 1 00 100011 0 ...... 00 .... ..... ..... @addsub_imm_tag
24
} TestData;
23
SUBG_i 1 10 100011 0 ...... 00 .... ..... ..... @addsub_imm_tag
25
24
+
26
-/* Values extracted from hw/arm/npcm8xx.c */
25
+# Logical (immediate)
27
+/* Values extracted from hw/arm/npcm7xx.c */
26
+
28
static const GMACModule gmac_module_list[] = {
27
+&rri_log rd rn sf dbm
29
{
28
+@logic_imm_64 1 .. ...... dbm:13 rn:5 rd:5 &rri_log sf=1
30
.irq = 14,
29
+@logic_imm_32 0 .. ...... 0 dbm:12 rn:5 rd:5 &rri_log sf=0
31
@@ -XXX,XX +XXX,XX @@ static const GMACModule gmac_module_list[] = {
30
+
32
.irq = 15,
31
+AND_i . 00 100100 . ...... ...... ..... ..... @logic_imm_64
33
.base_addr = 0xf0804000
32
+AND_i . 00 100100 . ...... ...... ..... ..... @logic_imm_32
34
},
33
+ORR_i . 01 100100 . ...... ...... ..... ..... @logic_imm_64
35
- {
34
+ORR_i . 01 100100 . ...... ...... ..... ..... @logic_imm_32
36
- .irq = 16,
35
+EOR_i . 10 100100 . ...... ...... ..... ..... @logic_imm_64
37
- .base_addr = 0xf0806000
36
+EOR_i . 10 100100 . ...... ...... ..... ..... @logic_imm_32
38
- },
37
+ANDS_i . 11 100100 . ...... ...... ..... ..... @logic_imm_64
39
- {
38
+ANDS_i . 11 100100 . ...... ...... ..... ..... @logic_imm_32
40
- .irq = 17,
39
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
41
- .base_addr = 0xf0808000
40
index XXXXXXX..XXXXXXX 100644
42
- }
41
--- a/target/arm/tcg/translate-a64.c
43
};
42
+++ b/target/arm/tcg/translate-a64.c
44
43
@@ -XXX,XX +XXX,XX @@ static uint64_t bitfield_replicate(uint64_t mask, unsigned int e)
45
/* Returns the index of the GMAC module. */
44
return mask;
46
@@ -XXX,XX +XXX,XX @@ static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
47
return qtest_readl(qts, mod->base_addr + regno);
45
}
48
}
46
49
47
-/* Simplified variant of pseudocode DecodeBitMasks() for the case where we
50
-static uint16_t pcs_read(QTestState *qts, const GMACModule *mod,
48
+/*
51
- NPCMRegister regno)
49
+ * Logical (immediate)
52
-{
50
+ */
53
- uint32_t write_value = (regno & 0x3ffe00) >> 9;
51
+
54
- qtest_writel(qts, PCS_BASE_ADDRESS + NPCM_PCS_IND_AC_BA, write_value);
52
+/*
55
- uint32_t read_offset = regno & 0x1ff;
53
+ * Simplified variant of pseudocode DecodeBitMasks() for the case where we
56
- return qtest_readl(qts, PCS_BASE_ADDRESS + read_offset);
54
* only require the wmask. Returns false if the imms/immr/immn are a reserved
57
-}
55
* value (ie should cause a guest UNDEF exception), and true if they are
58
-
56
* valid, in which case the decoded bit pattern is written to result.
59
/* Check that GMAC registers are reset to default value */
57
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
60
static void test_init(gconstpointer test_data)
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
{
61
{
71
- unsigned int sf, opc, is_n, immr, imms, rn, rd;
62
const TestData *td = test_data;
72
TCGv_i64 tcg_rd, tcg_rn;
63
const GMACModule *mod = td->module;
73
- uint64_t wmask;
64
- QTestState *qts = qtest_init("-machine npcm845-evb");
74
- bool is_and = false;
65
+ QTestState *qts = qtest_init("-machine npcm750-evb");
75
+ uint64_t imm;
66
76
67
#define CHECK_REG32(regno, value) \
77
- sf = extract32(insn, 31, 1);
68
do { \
78
- opc = extract32(insn, 29, 2);
69
g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \
79
- is_n = extract32(insn, 22, 1);
70
} while (0)
80
- immr = extract32(insn, 16, 6);
71
81
- imms = extract32(insn, 10, 6);
72
-#define CHECK_REG_PCS(regno, value) \
82
- rn = extract32(insn, 5, 5);
73
- do { \
83
- rd = extract32(insn, 0, 5);
74
- g_assert_cmphex(pcs_read(qts, mod, (regno)), ==, (value)); \
75
- } while (0)
84
-
76
-
85
- if (!sf && is_n) {
77
CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100);
86
- unallocated_encoding(s);
78
CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0);
87
- return;
79
CHECK_REG32(NPCM_DMA_RCV_POLL_DEMAND, 0);
88
+ /* Some immediate field values are reserved. */
80
@@ -XXX,XX +XXX,XX @@ static void test_init(gconstpointer test_data)
89
+ if (!logic_imm_decode_wmask(&imm, extract32(a->dbm, 12, 1),
81
CHECK_REG32(NPCM_GMAC_PTP_TAR, 0);
90
+ extract32(a->dbm, 0, 6),
82
CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0);
91
+ extract32(a->dbm, 6, 6))) {
83
92
+ return false;
84
- /* TODO Add registers PCS */
93
+ }
85
- if (mod->base_addr == 0xf0802000) {
94
+ if (!a->sf) {
86
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID1, 0x699e);
95
+ imm &= 0xffffffffull;
87
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID2, 0);
96
}
88
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_STS, 0x8000);
97
98
- if (opc == 0x3) { /* ANDS */
99
- tcg_rd = cpu_reg(s, rd);
100
- } else {
101
- tcg_rd = cpu_reg_sp(s, rd);
102
- }
103
- tcg_rn = cpu_reg(s, rn);
104
+ tcg_rd = set_cc ? cpu_reg(s, a->rd) : cpu_reg_sp(s, a->rd);
105
+ tcg_rn = cpu_reg(s, a->rn);
106
107
- if (!logic_imm_decode_wmask(&wmask, is_n, imms, immr)) {
108
- /* some immediate field values are reserved */
109
- unallocated_encoding(s);
110
- return;
111
+ fn(tcg_rd, tcg_rn, imm);
112
+ if (set_cc) {
113
+ gen_logic_CC(a->sf, tcg_rd);
114
}
115
-
89
-
116
- if (!sf) {
90
- CHECK_REG_PCS(NPCM_PCS_SR_MII_CTRL, 0x1140);
117
- wmask &= 0xffffffff;
91
- CHECK_REG_PCS(NPCM_PCS_SR_MII_STS, 0x0109);
92
- CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID1, 0x699e);
93
- CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID2, 0x0ced0);
94
- CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_ADV, 0x0020);
95
- CHECK_REG_PCS(NPCM_PCS_SR_MII_LP_BABL, 0);
96
- CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_EXPN, 0);
97
- CHECK_REG_PCS(NPCM_PCS_SR_MII_EXT_STS, 0xc000);
98
-
99
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_ABL, 0x0003);
100
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR, 0x0038);
101
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR, 0);
102
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR, 0x0038);
103
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR, 0);
104
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR, 0x0058);
105
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_UPR, 0);
106
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR, 0x0048);
107
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_UPR, 0);
108
-
109
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MMD_DIG_CTRL1, 0x2400);
110
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_CTRL, 0);
111
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_INTR_STS, 0x000a);
112
- CHECK_REG_PCS(NPCM_PCS_VR_MII_TC, 0);
113
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DBG_CTRL, 0);
114
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL0, 0x899c);
115
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_TXTIMER, 0);
116
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_RXTIMER, 0);
117
- CHECK_REG_PCS(NPCM_PCS_VR_MII_LINK_TIMER_CTRL, 0);
118
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL1, 0);
119
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_STS, 0x0010);
120
- CHECK_REG_PCS(NPCM_PCS_VR_MII_ICG_ERRCNT1, 0);
121
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MISC_STS, 0);
122
- CHECK_REG_PCS(NPCM_PCS_VR_MII_RX_LSTS, 0);
123
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_BSTCTRL0, 0x00a);
124
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_LVLCTRL0, 0x007f);
125
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL0, 0x0001);
126
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL1, 0);
127
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_STS, 0);
128
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL0, 0x0100);
129
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL1, 0x1100);
130
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_LOS_CTRL0, 0x000e);
131
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL0, 0x0100);
132
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL1, 0x0032);
133
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_STS, 0x0001);
134
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL2, 0);
135
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_LVL_CTRL, 0x0019);
136
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL0, 0);
137
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL1, 0);
138
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_CTRL2, 0);
139
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_ERRCNT_SEL, 0);
118
- }
140
- }
119
-
141
-
120
- switch (opc) {
142
qtest_quit(qts);
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);
143
}
144
-
145
- if (opc == 3) { /* ANDS */
146
- gen_logic_CC(sf, tcg_rd);
147
- }
148
+ return true;
149
}
143
}
150
144
151
+TRANS(AND_i, gen_rri_log, a, false, tcg_gen_andi_i64)
145
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
152
+TRANS(ORR_i, gen_rri_log, a, false, tcg_gen_ori_i64)
146
index XXXXXXX..XXXXXXX 100644
153
+TRANS(EOR_i, gen_rri_log, a, false, tcg_gen_xori_i64)
147
--- a/tests/qtest/meson.build
154
+TRANS(ANDS_i, gen_rri_log, a, true, tcg_gen_andi_i64)
148
+++ b/tests/qtest/meson.build
155
+
149
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
156
/*
150
'npcm7xx_sdhci-test',
157
* Move wide (immediate)
151
'npcm7xx_smbus-test',
158
*
152
'npcm7xx_timer-test',
159
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
153
- 'npcm7xx_watchdog_timer-test'] + \
160
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
154
+ 'npcm7xx_watchdog_timer-test',
161
{
155
+ 'npcm_gmac-test'] + \
162
switch (extract32(insn, 23, 6)) {
156
(slirp.found() ? ['npcm7xx_emc-test'] : [])
163
- case 0x24: /* Logical (immediate) */
157
qtests_aspeed = \
164
- disas_logic_imm(s, insn);
158
['aspeed_hace-test',
165
- break;
166
case 0x25: /* Move wide (immediate) */
167
disas_movw_imm(s, insn);
168
break;
169
--
159
--
170
2.34.1
160
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Luc Michel <luc.michel@amd.com>
2
2
3
Convert the BFM, SBFM, UBFM instructions.
3
An access fault is raised when the Access Flag is not set in the
4
looked-up PTE and the AFFD field is not set in the corresponding context
5
descriptor. This was already implemented for stage 2. Implement it for
6
stage 1 as well.
4
7
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Luc Michel <luc.michel@amd.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Mostafa Saleh <smostafa@google.com>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Message-id: 20230512144106.3608981-12-peter.maydell@linaro.org
11
Tested-by: Mostafa Saleh <smostafa@google.com>
9
[PMM: Rebased]
12
Message-id: 20240213082211.3330400-1-luc.michel@amd.com
13
[PMM: tweaked comment text]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
target/arm/tcg/a64.decode | 13 +++
16
hw/arm/smmuv3-internal.h | 1 +
13
target/arm/tcg/translate-a64.c | 144 ++++++++++++++++++---------------
17
include/hw/arm/smmu-common.h | 1 +
14
2 files changed, 94 insertions(+), 63 deletions(-)
18
hw/arm/smmu-common.c | 11 +++++++++++
19
hw/arm/smmuv3.c | 1 +
20
4 files changed, 14 insertions(+)
15
21
16
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
22
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
17
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/tcg/a64.decode
24
--- a/hw/arm/smmuv3-internal.h
19
+++ b/target/arm/tcg/a64.decode
25
+++ b/hw/arm/smmuv3-internal.h
20
@@ -XXX,XX +XXX,XX @@ MOVZ . 10 100101 .. ................ ..... @movw_64
26
@@ -XXX,XX +XXX,XX @@ static inline int pa_range(STE *ste)
21
MOVZ . 10 100101 .. ................ ..... @movw_32
27
#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
22
MOVK . 11 100101 .. ................ ..... @movw_64
28
#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
23
MOVK . 11 100101 .. ................ ..... @movw_32
29
#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
30
+#define CD_AFFD(x) extract32((x)->word[1], 3 , 1)
31
#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
32
#define CD_HD(x) extract32((x)->word[1], 10 , 1)
33
#define CD_HA(x) extract32((x)->word[1], 11 , 1)
34
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/arm/smmu-common.h
37
+++ b/include/hw/arm/smmu-common.h
38
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
39
bool disabled; /* smmu is disabled */
40
bool bypassed; /* translation is bypassed */
41
bool aborted; /* translation is aborted */
42
+ bool affd; /* AF fault disable */
43
uint32_t iotlb_hits; /* counts IOTLB hits */
44
uint32_t iotlb_misses; /* counts IOTLB misses*/
45
/* Used by stage-1 only. */
46
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/smmu-common.c
49
+++ b/hw/arm/smmu-common.c
50
@@ -XXX,XX +XXX,XX @@ static int smmu_ptw_64_s1(SMMUTransCfg *cfg,
51
pte_addr, pte, iova, gpa,
52
block_size >> 20);
53
}
24
+
54
+
25
+# Bitfield
55
+ /*
26
+
56
+ * QEMU does not currently implement HTTU, so if AFFD and PTE.AF
27
+&bitfield rd rn sf immr imms
57
+ * are 0 we take an Access flag fault. (5.4. Context Descriptor)
28
+@bitfield_64 1 .. ...... 1 immr:6 imms:6 rn:5 rd:5 &bitfield sf=1
58
+ * An Access flag fault takes priority over a Permission fault.
29
+@bitfield_32 0 .. ...... 0 0 immr:5 0 imms:5 rn:5 rd:5 &bitfield sf=0
59
+ */
30
+
60
+ if (!PTE_AF(pte) && !cfg->affd) {
31
+SBFM . 00 100110 . ...... ...... ..... ..... @bitfield_64
61
+ info->type = SMMU_PTW_ERR_ACCESS;
32
+SBFM . 00 100110 . ...... ...... ..... ..... @bitfield_32
62
+ goto error;
33
+BFM . 01 100110 . ...... ...... ..... ..... @bitfield_64
34
+BFM . 01 100110 . ...... ...... ..... ..... @bitfield_32
35
+UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_64
36
+UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_32
37
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/tcg/translate-a64.c
40
+++ b/target/arm/tcg/translate-a64.c
41
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVK(DisasContext *s, arg_movw *a)
42
return true;
43
}
44
45
-/* Bitfield
46
- * 31 30 29 28 23 22 21 16 15 10 9 5 4 0
47
- * +----+-----+-------------+---+------+------+------+------+
48
- * | sf | opc | 1 0 0 1 1 0 | N | immr | imms | Rn | Rd |
49
- * +----+-----+-------------+---+------+------+------+------+
50
+/*
51
+ * Bitfield
52
*/
53
-static void disas_bitfield(DisasContext *s, uint32_t insn)
54
+
55
+static bool trans_SBFM(DisasContext *s, arg_SBFM *a)
56
{
57
- unsigned int sf, n, opc, ri, si, rn, rd, bitsize, pos, len;
58
- TCGv_i64 tcg_rd, tcg_tmp;
59
+ TCGv_i64 tcg_rd = cpu_reg(s, a->rd);
60
+ TCGv_i64 tcg_tmp = read_cpu_reg(s, a->rn, 1);
61
+ unsigned int bitsize = a->sf ? 64 : 32;
62
+ unsigned int ri = a->immr;
63
+ unsigned int si = a->imms;
64
+ unsigned int pos, len;
65
66
- sf = extract32(insn, 31, 1);
67
- opc = extract32(insn, 29, 2);
68
- n = extract32(insn, 22, 1);
69
- ri = extract32(insn, 16, 6);
70
- si = extract32(insn, 10, 6);
71
- rn = extract32(insn, 5, 5);
72
- rd = extract32(insn, 0, 5);
73
- bitsize = sf ? 64 : 32;
74
-
75
- if (sf != n || ri >= bitsize || si >= bitsize || opc > 2) {
76
- unallocated_encoding(s);
77
- return;
78
- }
79
-
80
- tcg_rd = cpu_reg(s, rd);
81
-
82
- /* Suppress the zero-extend for !sf. Since RI and SI are constrained
83
- to be smaller than bitsize, we'll never reference data outside the
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
+ }
63
+ }
116
+
64
+
117
+ /*
65
ap = PTE_AP(pte);
118
+ * We start with zero, and we haven't modified any bits outside
66
if (is_permission_fault(ap, perm)) {
119
+ * bitsize, therefore no final zero-extension is unneeded for !sf.
67
info->type = SMMU_PTW_ERR_PERMISSION;
120
+ */
68
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
121
+ tcg_gen_deposit_z_i64(tcg_rd, tcg_tmp, pos, len);
69
index XXXXXXX..XXXXXXX 100644
122
+ }
70
--- a/hw/arm/smmuv3.c
123
+ return true;
71
+++ b/hw/arm/smmuv3.c
124
+}
72
@@ -XXX,XX +XXX,XX @@ static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
125
+
73
cfg->oas = MIN(oas2bits(SMMU_IDR5_OAS), cfg->oas);
126
+static bool trans_UBFM(DisasContext *s, arg_UBFM *a)
74
cfg->tbi = CD_TBI(cd);
127
+{
75
cfg->asid = CD_ASID(cd);
128
+ TCGv_i64 tcg_rd = cpu_reg(s, a->rd);
76
+ cfg->affd = CD_AFFD(cd);
129
+ TCGv_i64 tcg_tmp = read_cpu_reg(s, a->rn, 1);
77
130
+ unsigned int bitsize = a->sf ? 64 : 32;
78
trace_smmuv3_decode_cd(cfg->oas);
131
+ unsigned int ri = a->immr;
79
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);
175
}
176
177
- if (opc == 0 && len < ri) {
178
- /* SBFM: sign extend the destination field from len to fill
179
- the balance of the word. Let the deposit below insert all
180
- of those sign bits. */
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;
202
}
203
204
/* Extract
205
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
206
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
207
{
208
switch (extract32(insn, 23, 6)) {
209
- case 0x26: /* Bitfield */
210
- disas_bitfield(s, insn);
211
- break;
212
case 0x27: /* Extract */
213
disas_extract(s, insn);
214
break;
215
--
80
--
216
2.34.1
81
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Convert the ADR and ADRP instructions.
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230512144106.3608981-5-peter.maydell@linaro.org
5
Message-id: 20240213155214.13619-2-philmd@linaro.org
9
[PMM: Rebased]
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
7
---
13
target/arm/tcg/a64.decode | 13 ++++++++++++
8
hw/arm/stellaris.c | 6 ++++--
14
target/arm/tcg/translate-a64.c | 38 +++++++++++++---------------------
9
1 file changed, 4 insertions(+), 2 deletions(-)
15
2 files changed, 27 insertions(+), 24 deletions(-)
16
10
17
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/tcg/a64.decode
13
--- a/hw/arm/stellaris.c
20
+++ b/target/arm/tcg/a64.decode
14
+++ b/hw/arm/stellaris.c
21
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_trigger(void *opaque, int irq, int level)
22
#
23
# This file is processed by scripts/decodetree.py
24
#
25
+
26
+&ri rd imm
27
+
28
+
29
+### Data Processing - Immediate
30
+
31
+# PC-rel addressing
32
+
33
+%imm_pcrel 5:s19 29:2
34
+@pcrel . .. ..... ................... rd:5 &ri imm=%imm_pcrel
35
+
36
+ADR 0 .. 10000 ................... ..... @pcrel
37
+ADRP 1 .. 10000 ................... ..... @pcrel
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 @@ static void disas_ldst(DisasContext *s, uint32_t insn)
43
}
16
}
44
}
17
}
45
18
46
-/* PC-rel. addressing
19
-static void stellaris_adc_reset(StellarisADCState *s)
47
- * 31 30 29 28 24 23 5 4 0
20
+static void stellaris_adc_reset_hold(Object *obj)
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
{
21
{
58
- unsigned int page, rd;
22
+ StellarisADCState *s = STELLARIS_ADC(obj);
59
- int64_t offset;
23
int n;
60
+ gen_pc_plus_diff(s, cpu_reg(s, a->rd), a->imm);
24
61
+ return true;
25
for (n = 0; n < 4; n++) {
62
+}
26
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_init(Object *obj)
63
27
memory_region_init_io(&s->iomem, obj, &stellaris_adc_ops, s,
64
- page = extract32(insn, 31, 1);
28
"adc", 0x1000);
65
- /* SignExtend(immhi:immlo) -> offset */
29
sysbus_init_mmio(sbd, &s->iomem);
66
- offset = sextract64(insn, 5, 19);
30
- stellaris_adc_reset(s);
67
- offset = offset << 2 | extract32(insn, 29, 2);
31
qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
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
}
32
}
86
33
87
/*
34
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stellaris_i2c_info = {
88
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
35
static void stellaris_adc_class_init(ObjectClass *klass, void *data)
89
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
90
{
36
{
91
switch (extract32(insn, 23, 6)) {
37
DeviceClass *dc = DEVICE_CLASS(klass);
92
- case 0x20: case 0x21: /* PC-rel. addressing */
38
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
93
- disas_pc_rel_adr(s, insn);
39
94
- break;
40
+ rc->phases.hold = stellaris_adc_reset_hold;
95
case 0x22: /* Add/subtract (immediate) */
41
dc->vmsd = &vmstate_stellaris_adc;
96
disas_add_sub_imm(s, insn);
42
}
97
break;
43
98
--
44
--
99
2.34.1
45
2.34.1
46
47
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Split out specific 32-bit and 64-bit functions.
3
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
4
These carry the same signature as tcg_gen_add_i64,
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
and so will be easier to pass as callbacks.
5
Message-id: 20240213155214.13619-3-philmd@linaro.org
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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
8
---
17
target/arm/tcg/translate-a64.c | 149 +++++++++++++++++++--------------
9
hw/arm/stellaris.c | 26 ++++++++++++++++++++++----
18
1 file changed, 84 insertions(+), 65 deletions(-)
10
1 file changed, 22 insertions(+), 4 deletions(-)
19
11
20
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
12
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/tcg/translate-a64.c
14
--- a/hw/arm/stellaris.c
23
+++ b/target/arm/tcg/translate-a64.c
15
+++ b/hw/arm/stellaris.c
24
@@ -XXX,XX +XXX,XX @@ static inline void gen_logic_CC(int sf, TCGv_i64 result)
16
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_instance_init(Object *obj)
17
s->sysclk = qdev_init_clock_out(DEVICE(s), "SYSCLK");
25
}
18
}
26
19
27
/* dest = T0 + T1; compute C, N, V and Z flags */
20
-/* I2C controller. */
28
+static void gen_add64_CC(TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
21
+/*
29
+{
22
+ * I2C controller.
30
+ TCGv_i64 result, flag, tmp;
23
+ * ??? For now we only implement the master interface.
31
+ result = tcg_temp_new_i64();
24
+ */
32
+ flag = tcg_temp_new_i64();
25
33
+ tmp = tcg_temp_new_i64();
26
#define TYPE_STELLARIS_I2C "stellaris-i2c"
27
OBJECT_DECLARE_SIMPLE_TYPE(stellaris_i2c_state, STELLARIS_I2C)
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_write(void *opaque, hwaddr offset,
29
stellaris_i2c_update(s);
30
}
31
32
-static void stellaris_i2c_reset(stellaris_i2c_state *s)
33
+static void stellaris_i2c_reset_enter(Object *obj, ResetType type)
34
{
35
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
34
+
36
+
35
+ tcg_gen_movi_i64(tmp, 0);
37
if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
36
+ tcg_gen_add2_i64(result, flag, t0, tmp, t1, tmp);
38
i2c_end_transfer(s->bus);
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
+}
39
+}
49
+
40
+
50
+static void gen_add32_CC(TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
41
+static void stellaris_i2c_reset_hold(Object *obj)
51
+{
42
+{
52
+ TCGv_i32 t0_32 = tcg_temp_new_i32();
43
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
53
+ TCGv_i32 t1_32 = tcg_temp_new_i32();
44
54
+ TCGv_i32 tmp = tcg_temp_new_i32();
45
s->msa = 0;
55
+
46
s->mcs = 0;
56
+ tcg_gen_movi_i32(tmp, 0);
47
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_reset(stellaris_i2c_state *s)
57
+ tcg_gen_extrl_i64_i32(t0_32, t0);
48
s->mimr = 0;
58
+ tcg_gen_extrl_i64_i32(t1_32, t1);
49
s->mris = 0;
59
+ tcg_gen_add2_i32(cpu_NF, cpu_CF, t0_32, tmp, t1_32, tmp);
50
s->mcr = 0;
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
+}
51
+}
66
+
52
+
67
static void gen_add_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
53
+static void stellaris_i2c_reset_exit(Object *obj)
54
+{
55
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
56
+
57
stellaris_i2c_update(s);
58
}
59
60
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_init(Object *obj)
61
memory_region_init_io(&s->iomem, obj, &stellaris_i2c_ops, s,
62
"i2c", 0x1000);
63
sysbus_init_mmio(sbd, &s->iomem);
64
- /* ??? For now we only implement the master interface. */
65
- stellaris_i2c_reset(s);
66
}
67
68
/* Analogue to Digital Converter. This is only partially implemented,
69
@@ -XXX,XX +XXX,XX @@ type_init(stellaris_machine_init)
70
static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
68
{
71
{
69
if (sf) {
72
DeviceClass *dc = DEVICE_CLASS(klass);
70
- TCGv_i64 result, flag, tmp;
73
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
71
- result = tcg_temp_new_i64();
74
72
- flag = tcg_temp_new_i64();
75
+ rc->phases.enter = stellaris_i2c_reset_enter;
73
- tmp = tcg_temp_new_i64();
76
+ rc->phases.hold = stellaris_i2c_reset_hold;
74
-
77
+ rc->phases.exit = stellaris_i2c_reset_exit;
75
- tcg_gen_movi_i64(tmp, 0);
78
dc->vmsd = &vmstate_stellaris_i2c;
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);
105
}
106
}
79
}
107
108
/* dest = T0 - T1; compute C, N, V and Z flags */
109
+static void gen_sub64_CC(TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
110
+{
111
+ /* 64 bit arithmetic */
112
+ TCGv_i64 result, flag, tmp;
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
}
190
}
191
80
192
--
81
--
193
2.34.1
82
2.34.1
83
84
diff view generated by jsdifflib
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Bochs card is normal PCI Express card so it fits better in system with
3
QDev objects created with qdev_new() need to manually add
4
PCI Express bus. VGA is simple legacy PCI card.
4
their parent relationship with object_property_add_child().
5
5
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
6
This commit plug the devices which aren't part of the SoC;
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
7
they will be plugged into a SoC container in the next one.
8
Message-id: 20230505120936.1097060-1-marcin.juszkiewicz@linaro.org
8
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20240213155214.13619-4-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
hw/arm/sbsa-ref.c | 2 +-
14
hw/arm/stellaris.c | 4 ++++
12
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 4 insertions(+)
13
16
14
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
17
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/sbsa-ref.c
19
--- a/hw/arm/stellaris.c
17
+++ b/hw/arm/sbsa-ref.c
20
+++ b/hw/arm/stellaris.c
18
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms)
21
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
22
&error_fatal);
23
24
ssddev = qdev_new("ssd0323");
25
+ object_property_add_child(OBJECT(ms), "oled", OBJECT(ssddev));
26
qdev_prop_set_uint8(ssddev, "cs", 1);
27
qdev_realize_and_unref(ssddev, bus, &error_fatal);
28
29
gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
30
+ object_property_add_child(OBJECT(ms), "splitter",
31
+ OBJECT(gpio_d_splitter));
32
qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
33
qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
34
qdev_connect_gpio_out(
35
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
36
DeviceState *gpad;
37
38
gpad = qdev_new(TYPE_STELLARIS_GAMEPAD);
39
+ object_property_add_child(OBJECT(ms), "gamepad", OBJECT(gpad));
40
for (i = 0; i < ARRAY_SIZE(gpad_keycode); i++) {
41
qlist_append_int(gpad_keycode_list, gpad_keycode[i]);
19
}
42
}
20
}
21
22
- pci_create_simple(pci->bus, -1, "VGA");
23
+ pci_create_simple(pci->bus, -1, "bochs-display");
24
25
create_smmu(sms, pci->bus);
26
}
27
--
43
--
28
2.34.1
44
2.34.1
45
46
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
The commit b3aa2f2128 (target/arm: provide stubs for more external
3
QDev objects created with qdev_new() need to manually add
4
debug registers) was added to handle HyperV's unconditional usage of
4
their parent relationship with object_property_add_child().
5
Debug Communications Channel. It turns out that Linux will similarly
6
break if you enable CONFIG_HVC_DCC "ARM JTAG DCC console".
7
5
8
Extend the registers we RAZ/WI set to avoid this.
6
Since we don't model the SoC, just use a QOM container.
9
7
10
Cc: Anders Roxell <anders.roxell@linaro.org>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Cc: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20240213155214.13619-5-philmd@linaro.org
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20230516104420.407912-1-alex.bennee@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
12
---
17
target/arm/debug_helper.c | 11 +++++++++--
13
hw/arm/stellaris.c | 11 ++++++++++-
18
1 file changed, 9 insertions(+), 2 deletions(-)
14
1 file changed, 10 insertions(+), 1 deletion(-)
19
15
20
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
16
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/debug_helper.c
18
--- a/hw/arm/stellaris.c
23
+++ b/target/arm/debug_helper.c
19
+++ b/hw/arm/stellaris.c
24
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
20
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
25
.access = PL0_R, .accessfn = access_tdcc,
21
* 400fe000 system control
26
.type = ARM_CP_CONST, .resetvalue = 0 },
22
*/
23
24
+ Object *soc_container;
25
DeviceState *gpio_dev[7], *nvic;
26
qemu_irq gpio_in[7][8];
27
qemu_irq gpio_out[7][8];
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
29
flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
30
sram_size = ((board->dc0 >> 18) + 1) * 1024;
31
32
+ soc_container = object_new("container");
33
+ object_property_add_child(OBJECT(ms), "soc", soc_container);
34
+
35
/* Flash programming is done via the SCU, so pretend it is ROM. */
36
memory_region_init_rom(flash, NULL, "stellaris.flash", flash_size,
37
&error_fatal);
38
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
39
* need its sysclk output.
40
*/
41
ssys_dev = qdev_new(TYPE_STELLARIS_SYS);
42
+ object_property_add_child(soc_container, "sys", OBJECT(ssys_dev));
43
27
/*
44
/*
28
- * OSDTRRX_EL1/OSDTRTX_EL1 are used for save and restore of DBGDTRRX_EL0.
45
* Most devices come preprogrammed with a MAC address in the user data.
29
- * It is a component of the Debug Communications Channel, which is not implemented.
46
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
30
+ * These registers belong to the Debug Communications Channel,
47
sysbus_realize_and_unref(SYS_BUS_DEVICE(ssys_dev), &error_fatal);
31
+ * which is not implemented. However we implement RAZ/WI behaviour
48
32
+ * with trapping to prevent spurious SIGILLs if the guest OS does
49
nvic = qdev_new(TYPE_ARMV7M);
33
+ * access them as the support cannot be probed for.
50
+ object_property_add_child(soc_container, "v7m", OBJECT(nvic));
34
*/
51
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
35
{ .name = "OSDTRRX_EL1", .state = ARM_CP_STATE_BOTH, .cp = 14,
52
qdev_prop_set_uint8(nvic, "num-prio-bits", NUM_PRIO_BITS);
36
.opc0 = 2, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 2,
53
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
37
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo debug_cp_reginfo[] = {
54
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
38
.opc0 = 2, .opc1 = 0, .crn = 0, .crm = 3, .opc2 = 2,
55
39
.access = PL1_RW, .accessfn = access_tdcc,
56
dev = qdev_new(TYPE_STELLARIS_GPTM);
40
.type = ARM_CP_CONST, .resetvalue = 0 },
57
sbd = SYS_BUS_DEVICE(dev);
41
+ /* DBGDTRTX_EL0/DBGDTRRX_EL0 depend on direction */
58
+ object_property_add_child(soc_container, "gptm[*]", OBJECT(dev));
42
+ { .name = "DBGDTR_EL0", .state = ARM_CP_STATE_BOTH, .cp = 14,
59
qdev_connect_clock_in(dev, "clk",
43
+ .opc0 = 2, .opc1 = 3, .crn = 0, .crm = 5, .opc2 = 0,
60
qdev_get_clock_out(ssys_dev, "SYSCLK"));
44
+ .access = PL0_RW, .accessfn = access_tdcc,
61
sysbus_realize_and_unref(sbd, &error_fatal);
45
+ .type = ARM_CP_CONST, .resetvalue = 0 },
62
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
46
/*
63
47
* OSECCR_EL1 provides a mechanism for an operating system
64
if (board->dc1 & (1 << 3)) { /* watchdog present */
48
* to access the contents of EDECCR. EDECCR is not implemented though,
65
dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
66
-
67
+ object_property_add_child(soc_container, "wdg", OBJECT(dev));
68
qdev_connect_clock_in(dev, "WDOGCLK",
69
qdev_get_clock_out(ssys_dev, "SYSCLK"));
70
71
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
72
SysBusDevice *sbd;
73
74
dev = qdev_new("pl011_luminary");
75
+ object_property_add_child(soc_container, "uart[*]", OBJECT(dev));
76
sbd = SYS_BUS_DEVICE(dev);
77
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
78
sysbus_realize_and_unref(sbd, &error_fatal);
79
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
80
DeviceState *enet;
81
82
enet = qdev_new("stellaris_enet");
83
+ object_property_add_child(soc_container, "enet", OBJECT(enet));
84
if (nd) {
85
qdev_set_nic_properties(enet, nd);
86
} else {
49
--
87
--
50
2.34.1
88
2.34.1
51
89
52
90
diff view generated by jsdifflib
1
Convert the test-and-branch-immediate insns TBZ and TBNZ
1
We support two different encodings for the AArch32 IMPDEF
2
to decodetree.
2
CBAR register -- older cores like the Cortex A9, A7, A15
3
have this at 4, c15, c0, 0; newer cores like the
4
Cortex A35, A53, A57 and A72 have it at 1 c15 c0 0.
5
6
When we implemented this we picked which encoding to
7
use based on whether the CPU set ARM_FEATURE_AARCH64.
8
However this isn't right for three cases:
9
* the qemu-system-arm 'max' CPU, which is supposed to be
10
a variant on a Cortex-A57; it ought to use the same
11
encoding the A57 does and which the AArch64 'max'
12
exposes to AArch32 guest code
13
* the Cortex-R52, which is AArch32-only but has the CBAR
14
at the newer encoding (and where we incorrectly are
15
not yet setting ARM_FEATURE_CBAR_RO anyway)
16
* any possible future support for other v8 AArch32
17
only CPUs, or for supporting "boot the CPU into
18
AArch32 mode" on our existing cores like the A57 etc
19
20
Make the decision of the encoding be based on whether
21
the CPU implements the ARM_FEATURE_V8 flag instead.
22
23
This changes the behaviour only for the qemu-system-arm
24
'-cpu max'. We don't expect anybody to be relying on the
25
old behaviour because:
26
* it's not what the real hardware Cortex-A57 does
27
(and that's what our ID register claims we are)
28
* we don't implement the memory-mapped GICv3 support
29
which is the only thing that exists at the peripheral
30
base address pointed to by the register
3
31
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20230512144106.3608981-16-peter.maydell@linaro.org
34
Message-id: 20240206132931.38376-2-peter.maydell@linaro.org
7
---
35
---
8
target/arm/tcg/a64.decode | 6 ++++++
36
target/arm/helper.c | 2 +-
9
target/arm/tcg/translate-a64.c | 25 +++++--------------------
37
1 file changed, 1 insertion(+), 1 deletion(-)
10
2 files changed, 11 insertions(+), 20 deletions(-)
11
38
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/a64.decode
41
--- a/target/arm/helper.c
15
+++ b/target/arm/tcg/a64.decode
42
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ BL 1 00101 .......................... @branch
43
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
17
&cbz rt imm sf nz
44
* AArch64 cores we might need to add a specific feature flag
18
45
* to indicate cores with "flavour 2" CBAR.
19
CBZ sf:1 011010 nz:1 ................... rt:5 &cbz imm=%imm19
46
*/
20
+
47
- if (arm_feature(env, ARM_FEATURE_AARCH64)) {
21
+%imm14 5:s14 !function=times_4
48
+ if (arm_feature(env, ARM_FEATURE_V8)) {
22
+%imm31_19 31:1 19:5
49
/* 32 bit view is [31:18] 0...0 [43:32]. */
23
+&tbz rt imm nz bitpos
50
uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18)
24
+
51
| extract64(cpu->reset_cbar, 32, 12);
25
+TBZ . 011011 nz:1 ..... .............. rt:5 &tbz imm=%imm14 bitpos=%imm31_19
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_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;
81
--
52
--
82
2.34.1
53
2.34.1
diff view generated by jsdifflib
1
Convert the compare-and-branch-immediate insns CBZ and CBNZ
1
The Cortex-R52 implements the Configuration Base Address Register
2
to decodetree.
2
(CBAR), as a read-only register. Add ARM_FEATURE_CBAR_RO to this CPU
3
type, so that our implementation provides the register and the
4
associated qdev property.
3
5
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20230512144106.3608981-15-peter.maydell@linaro.org
8
Message-id: 20240206132931.38376-3-peter.maydell@linaro.org
7
---
9
---
8
target/arm/tcg/a64.decode | 5 +++++
10
target/arm/tcg/cpu32.c | 1 +
9
target/arm/tcg/translate-a64.c | 26 ++++++--------------------
11
1 file changed, 1 insertion(+)
10
2 files changed, 11 insertions(+), 20 deletions(-)
11
12
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/a64.decode
15
--- a/target/arm/tcg/cpu32.c
15
+++ b/target/arm/tcg/a64.decode
16
+++ b/target/arm/tcg/cpu32.c
16
@@ -XXX,XX +XXX,XX @@ EXTR 0 00 100111 0 0 rm:5 0 imm:5 rn:5 rd:5 &extract sf=0
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
17
18
set_feature(&cpu->env, ARM_FEATURE_PMSA);
18
B 0 00101 .......................... @branch
19
set_feature(&cpu->env, ARM_FEATURE_NEON);
19
BL 1 00101 .......................... @branch
20
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
20
+
21
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
21
+%imm19 5:s19 !function=times_4
22
cpu->midr = 0x411fd133; /* r1p3 */
22
+&cbz rt imm sf nz
23
cpu->revidr = 0x00000000;
23
+
24
cpu->reset_fpsid = 0x41034023;
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;
52
-
53
- tcg_cmp = read_cpu_reg(s, rt, sf);
54
+ tcg_cmp = read_cpu_reg(s, a->rt, a->sf);
55
reset_btype(s);
56
57
match = gen_disas_label(s);
58
- tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
59
+ tcg_gen_brcondi_i64(a->nz ? TCG_COND_NE : TCG_COND_EQ,
60
tcg_cmp, 0, match.label);
61
gen_goto_tb(s, 0, 4);
62
set_disas_label(s, match);
63
- gen_goto_tb(s, 1, diff);
64
+ gen_goto_tb(s, 1, a->imm);
65
+ return true;
66
}
67
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;
79
--
25
--
80
2.34.1
26
2.34.1
diff view generated by jsdifflib
1
The A64 translator uses a hand-written decoder for everything except
1
Add the Cortex-R52 IMPDEF sysregs, by defining them here and
2
SVE or SME. It's fairly well structured, but it's becoming obvious
2
also by enabling the AUXCR feature which defines the ACTLR
3
that it's still more painful to add instructions to than the A32
3
and HACTLR registers. As is our usual practice, we make these
4
translator, because putting a new instruction into the right place in
4
simple reads-as-zero stubs for now.
5
a hand-written decoder is much harder than adding new instruction
6
patterns to a decodetree file.
7
8
As the first step in conversion to decodetree, create the skeleton of
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).
12
5
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20230512144106.3608981-3-peter.maydell@linaro.org
8
Message-id: 20240206132931.38376-4-peter.maydell@linaro.org
16
---
9
---
17
target/arm/tcg/a64.decode | 20 ++++++++++++++++++++
10
target/arm/tcg/cpu32.c | 108 +++++++++++++++++++++++++++++++++++++++++
18
target/arm/tcg/translate-a64.c | 18 +++++++++++-------
11
1 file changed, 108 insertions(+)
19
target/arm/tcg/meson.build | 1 +
20
3 files changed, 32 insertions(+), 7 deletions(-)
21
create mode 100644 target/arm/tcg/a64.decode
22
12
23
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
24
new file mode 100644
14
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX
15
--- a/target/arm/tcg/cpu32.c
26
--- /dev/null
16
+++ b/target/arm/tcg/cpu32.c
27
+++ b/target/arm/tcg/a64.decode
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
28
@@ -XXX,XX +XXX,XX @@
18
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
29
+# AArch64 A64 allowed instruction decoding
19
}
30
+#
20
31
+# Copyright (c) 2023 Linaro, Ltd
21
+static const ARMCPRegInfo cortex_r52_cp_reginfo[] = {
32
+#
22
+ { .name = "CPUACTLR", .cp = 15, .opc1 = 0, .crm = 15,
33
+# This library is free software; you can redistribute it and/or
23
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
34
+# modify it under the terms of the GNU Lesser General Public
24
+ { .name = "IMP_ATCMREGIONR",
35
+# License as published by the Free Software Foundation; either
25
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
36
+# version 2.1 of the License, or (at your option) any later version.
26
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
37
+#
27
+ { .name = "IMP_BTCMREGIONR",
38
+# This library is distributed in the hope that it will be useful,
28
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
39
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
29
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
40
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30
+ { .name = "IMP_CTCMREGIONR",
41
+# Lesser General Public License for more details.
31
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 2,
42
+#
32
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
43
+# You should have received a copy of the GNU Lesser General Public
33
+ { .name = "IMP_CSCTLR",
44
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
34
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 0,
35
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
36
+ { .name = "IMP_BPCTLR",
37
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 1,
38
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
39
+ { .name = "IMP_MEMPROTCLR",
40
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 2,
41
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
42
+ { .name = "IMP_SLAVEPCTLR",
43
+ .cp = 15, .opc1 = 0, .crn = 11, .crm = 0, .opc2 = 0,
44
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
45
+ { .name = "IMP_PERIPHREGIONR",
46
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 0,
47
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
48
+ { .name = "IMP_FLASHIFREGIONR",
49
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 1,
50
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
51
+ { .name = "IMP_BUILDOPTR",
52
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 0,
53
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
54
+ { .name = "IMP_PINOPTR",
55
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 7,
56
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
57
+ { .name = "IMP_QOSR",
58
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 1,
59
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
60
+ { .name = "IMP_BUSTIMEOUTR",
61
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 2,
62
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
63
+ { .name = "IMP_INTMONR",
64
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 4,
65
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
66
+ { .name = "IMP_ICERR0",
67
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 0,
68
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
69
+ { .name = "IMP_ICERR1",
70
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 1,
71
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
72
+ { .name = "IMP_DCERR0",
73
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 0,
74
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
75
+ { .name = "IMP_DCERR1",
76
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 1,
77
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
78
+ { .name = "IMP_TCMERR0",
79
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 0,
80
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
81
+ { .name = "IMP_TCMERR1",
82
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 1,
83
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
84
+ { .name = "IMP_TCMSYNDR0",
85
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 2,
86
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
87
+ { .name = "IMP_TCMSYNDR1",
88
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 3,
89
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
90
+ { .name = "IMP_FLASHERR0",
91
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 0,
92
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
93
+ { .name = "IMP_FLASHERR1",
94
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 1,
95
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
96
+ { .name = "IMP_CDBGDR0",
97
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 0,
98
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
99
+ { .name = "IMP_CBDGBR1",
100
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 1,
101
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
102
+ { .name = "IMP_TESTR0",
103
+ .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 0,
104
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
105
+ { .name = "IMP_TESTR1",
106
+ .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 1,
107
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
108
+ { .name = "IMP_CDBGDCI",
109
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 15, .opc2 = 0,
110
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
111
+ { .name = "IMP_CDBGDCT",
112
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 0,
113
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
114
+ { .name = "IMP_CDBGICT",
115
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 1,
116
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
117
+ { .name = "IMP_CDBGDCD",
118
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 0,
119
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
120
+ { .name = "IMP_CDBGICD",
121
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 1,
122
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
123
+};
45
+
124
+
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
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/tcg/translate-a64.c
52
+++ b/target/arm/tcg/translate-a64.c
53
@@ -XXX,XX +XXX,XX @@ enum a64_shift_type {
54
A64_SHIFT_TYPE_ROR = 3
55
};
56
57
+/*
58
+ * Include the generated decoders.
59
+ */
60
+
125
+
61
+#include "decode-sme-fa64.c.inc"
126
static void cortex_r52_initfn(Object *obj)
62
+#include "decode-a64.c.inc"
127
{
128
ARMCPU *cpu = ARM_CPU(obj);
129
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
130
set_feature(&cpu->env, ARM_FEATURE_NEON);
131
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
132
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
133
+ set_feature(&cpu->env, ARM_FEATURE_AUXCR);
134
cpu->midr = 0x411fd133; /* r1p3 */
135
cpu->revidr = 0x00000000;
136
cpu->reset_fpsid = 0x41034023;
137
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
138
139
cpu->pmsav7_dregion = 16;
140
cpu->pmsav8r_hdregion = 16;
63
+
141
+
64
/* Table based decoder typedefs - used when the relevant bits for decode
142
+ define_arm_cp_regs(cpu, cortex_r52_cp_reginfo);
65
* are too awkwardly scattered across the instruction (eg SIMD).
66
*/
67
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
68
}
69
}
143
}
70
144
71
-/*
145
static void cortex_r5f_initfn(Object *obj)
72
- * Include the generated SME FA64 decoder.
73
- */
74
-
75
-#include "decode-sme-fa64.c.inc"
76
-
77
static bool trans_OK(DisasContext *s, arg_OK *a)
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)
104
--
146
--
105
2.34.1
147
2.34.1
diff view generated by jsdifflib
1
Convert the unconditional branch immediate insns B and BL to
1
Architecturally, the AArch32 MSR/MRS to/from banked register
2
decodetree.
2
instructions are UNPREDICTABLE for attempts to access a banked
3
register that the guest could access in a more direct way (e.g.
4
using this insn to access r8_fiq when already in FIQ mode). QEMU has
5
chosen to UNDEF on all of these.
6
7
However, for the case of accessing SPSR_hyp from hyp mode, it turns
8
out that real hardware permits this, with the same effect as if the
9
guest had directly written to SPSR. Further, there is some
10
guest code out there that assumes it can do this, because it
11
happens to work on hardware: an example Cortex-R52 startup code
12
fragment uses this, and it got copied into various other places,
13
including Zephyr. Zephyr was fixed to not use this:
14
https://github.com/zephyrproject-rtos/zephyr/issues/47330
15
but other examples are still out there, like the selftest
16
binary for the MPS3-AN536.
17
18
For convenience of being able to run guest code, permit
19
this UNPREDICTABLE access instead of UNDEFing it.
3
20
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20230512144106.3608981-14-peter.maydell@linaro.org
23
Message-id: 20240206132931.38376-5-peter.maydell@linaro.org
7
---
24
---
8
target/arm/tcg/a64.decode | 9 +++++++++
25
target/arm/tcg/op_helper.c | 43 ++++++++++++++++++++++++++------------
9
target/arm/tcg/translate-a64.c | 31 +++++++++++--------------------
26
target/arm/tcg/translate.c | 19 +++++++++++------
10
2 files changed, 20 insertions(+), 20 deletions(-)
27
2 files changed, 43 insertions(+), 19 deletions(-)
11
28
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
29
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
13
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/a64.decode
31
--- a/target/arm/tcg/op_helper.c
15
+++ b/target/arm/tcg/a64.decode
32
+++ b/target/arm/tcg/op_helper.c
16
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
17
34
*/
18
&ri rd imm
35
int curmode = env->uncached_cpsr & CPSR_M;
19
&rri_sf rd rn imm sf
36
20
+&i imm
37
- if (regno == 17) {
21
38
- /* ELR_Hyp: a special case because access from tgtmode is OK */
22
39
- if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
23
### Data Processing - Immediate
40
- goto undef;
24
@@ -XXX,XX +XXX,XX @@ UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_32
41
+ if (tgtmode == ARM_CPU_MODE_HYP) {
25
42
+ /*
26
EXTR 1 00 100111 1 0 rm:5 imm:6 rn:5 rd:5 &extract sf=1
43
+ * Handle Hyp target regs first because some are special cases
27
EXTR 0 00 100111 0 0 rm:5 0 imm:5 rn:5 rd:5 &extract sf=0
44
+ * which don't want the usual "not accessible from tgtmode" check.
28
+
45
+ */
29
+# Branches
46
+ switch (regno) {
30
+
47
+ case 16 ... 17: /* ELR_Hyp, SPSR_Hyp */
31
+%imm26 0:s26 !function=times_4
48
+ if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
32
+@branch . ..... .......................... &i imm=%imm26
49
+ goto undef;
33
+
50
+ }
34
+B 0 00101 .......................... @branch
51
+ break;
35
+BL 1 00101 .......................... @branch
52
+ case 13:
36
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
53
+ if (curmode != ARM_CPU_MODE_MON) {
37
index XXXXXXX..XXXXXXX 100644
54
+ goto undef;
38
--- a/target/arm/tcg/translate-a64.c
55
+ }
39
+++ b/target/arm/tcg/translate-a64.c
56
+ break;
40
@@ -XXX,XX +XXX,XX @@ static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table,
57
+ default:
41
* match up with those in the manual.
58
+ g_assert_not_reached();
42
*/
59
}
43
60
return;
44
-/* Unconditional branch (immediate)
61
}
45
- * 31 30 26 25 0
62
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
46
- * +----+-----------+-------------------------------------+
63
}
47
- * | op | 0 0 1 0 1 | imm26 |
64
}
48
- * +----+-----------+-------------------------------------+
65
49
- */
66
- if (tgtmode == ARM_CPU_MODE_HYP) {
50
-static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
67
- /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
51
+static bool trans_B(DisasContext *s, arg_i *a)
68
- if (curmode != ARM_CPU_MODE_MON) {
52
{
69
- goto undef;
53
- int64_t diff = sextract32(insn, 0, 26) * 4;
70
- }
54
-
55
- if (insn & (1U << 31)) {
56
- /* BL Branch with link */
57
- gen_pc_plus_diff(s, cpu_reg(s, 30), curr_insn_len(s));
58
- }
71
- }
59
-
72
-
60
- /* B Branch / BL Branch with link */
73
return;
61
reset_btype(s);
74
62
- gen_goto_tb(s, 0, diff);
75
undef:
63
+ gen_goto_tb(s, 0, a->imm);
76
@@ -XXX,XX +XXX,XX @@ void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
64
+ return true;
77
65
+}
78
switch (regno) {
66
+
79
case 16: /* SPSRs */
67
+static bool trans_BL(DisasContext *s, arg_i *a)
80
- env->banked_spsr[bank_number(tgtmode)] = value;
68
+{
81
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
69
+ gen_pc_plus_diff(s, cpu_reg(s, 30), curr_insn_len(s));
82
+ /* Only happens for SPSR_Hyp access in Hyp mode */
70
+ reset_btype(s);
83
+ env->spsr = value;
71
+ gen_goto_tb(s, 0, a->imm);
84
+ } else {
72
+ return true;
85
+ env->banked_spsr[bank_number(tgtmode)] = value;
73
}
86
+ }
74
87
break;
75
/* Compare and branch (immediate)
88
case 17: /* ELR_Hyp */
76
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
89
env->elr_el[2] = value;
77
static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
90
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
78
{
91
79
switch (extract32(insn, 25, 7)) {
92
switch (regno) {
80
- case 0x0a: case 0x0b:
93
case 16: /* SPSRs */
81
- case 0x4a: case 0x4b: /* Unconditional branch (immediate) */
94
- return env->banked_spsr[bank_number(tgtmode)];
82
- disas_uncond_b_imm(s, insn);
95
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
83
- break;
96
+ /* Only happens for SPSR_Hyp access in Hyp mode */
84
case 0x1a: case 0x5a: /* Compare & branch (immediate) */
97
+ return env->spsr;
85
disas_comp_b_imm(s, insn);
98
+ } else {
99
+ return env->banked_spsr[bank_number(tgtmode)];
100
+ }
101
case 17: /* ELR_Hyp */
102
return env->elr_el[2];
103
case 13:
104
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/target/arm/tcg/translate.c
107
+++ b/target/arm/tcg/translate.c
108
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
109
break;
110
case ARM_CPU_MODE_HYP:
111
/*
112
- * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
113
- * (and so we can forbid accesses from EL2 or below). elr_hyp
114
- * can be accessed also from Hyp mode, so forbid accesses from
115
- * EL0 or EL1.
116
+ * r13_hyp can only be accessed from Monitor mode, and so we
117
+ * can forbid accesses from EL2 or below.
118
+ * elr_hyp can be accessed also from Hyp mode, so forbid
119
+ * accesses from EL0 or EL1.
120
+ * SPSR_hyp is supposed to be in the same category as r13_hyp
121
+ * and UNPREDICTABLE if accessed from anything except Monitor
122
+ * mode. However there is some real-world code that will do
123
+ * it because at least some hardware happens to permit the
124
+ * access. (Notably a standard Cortex-R52 startup code fragment
125
+ * does this.) So we permit SPSR_hyp from Hyp mode also, to allow
126
+ * this (incorrect) guest code to run.
127
*/
128
- if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
129
- (s->current_el < 3 && *regno != 17)) {
130
+ if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2
131
+ || (s->current_el < 3 && *regno != 16 && *regno != 17)) {
132
goto undef;
133
}
86
break;
134
break;
87
--
135
--
88
2.34.1
136
2.34.1
diff view generated by jsdifflib
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
1
We currently guard the CFG3 register read with
2
(scc_partno(s) == 0x524 && scc_partno(s) == 0x547)
3
which is clearly wrong as it is never true.
2
4
3
The world outside moves to newer and newer cpu cores. Let move SBSA
5
This register is present on all board types except AN524
4
Reference Platform to something newer as well.
6
and AN527; correct the condition.
5
7
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
8
Fixes: 6ac80818941829c0 ("hw/misc/mps2-scc: Implement changes for AN547")
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
8
Message-id: 20230506183417.1360427-1-marcin.juszkiewicz@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20240206132931.38376-6-peter.maydell@linaro.org
10
---
13
---
11
hw/arm/sbsa-ref.c | 2 +-
14
hw/misc/mps2-scc.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 1 insertion(+), 1 deletion(-)
13
16
14
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
17
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/sbsa-ref.c
19
--- a/hw/misc/mps2-scc.c
17
+++ b/hw/arm/sbsa-ref.c
20
+++ b/hw/misc/mps2-scc.c
18
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_class_init(ObjectClass *oc, void *data)
21
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
19
22
r = s->cfg2;
20
mc->init = sbsa_ref_init;
23
break;
21
mc->desc = "QEMU 'SBSA Reference' ARM Virtual Machine";
24
case A_CFG3:
22
- mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a57");
25
- if (scc_partno(s) == 0x524 && scc_partno(s) == 0x547) {
23
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("neoverse-n1");
26
+ if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
24
mc->max_cpus = 512;
27
/* CFG3 reserved on AN524 */
25
mc->pci_allow_0_address = true;
28
goto bad_offset;
26
mc->minimum_page_bits = 12;
29
}
27
--
30
--
28
2.34.1
31
2.34.1
32
33
diff view generated by jsdifflib
1
Convert the single-register pointer-authentication variants of BR,
1
The MPS SCC device has a lot of different flavours for the various
2
BLR, RET to decodetree. (BRAA/BLRAA are in a different branch of
2
different MPS FPGA images, which look mostly similar but have
3
the legacy decoder and will be dealt with in the next commit.)
3
differences in how particular registers are handled. Currently we
4
deal with this with a lot of open-coded checks on scc_partno(), but
5
as we add more board types this is getting a bit hard to read.
6
7
Factor out the conditions into some functions which we can
8
give more descriptive names to.
4
9
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20230512144106.3608981-19-peter.maydell@linaro.org
13
Message-id: 20240206132931.38376-7-peter.maydell@linaro.org
8
---
14
---
9
target/arm/tcg/a64.decode | 7 ++
15
hw/misc/mps2-scc.c | 45 +++++++++++++++++++++++++++++++--------------
10
target/arm/tcg/translate-a64.c | 132 +++++++++++++++++++--------------
16
1 file changed, 31 insertions(+), 14 deletions(-)
11
2 files changed, 84 insertions(+), 55 deletions(-)
12
17
13
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
18
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/tcg/a64.decode
20
--- a/hw/misc/mps2-scc.c
16
+++ b/target/arm/tcg/a64.decode
21
+++ b/hw/misc/mps2-scc.c
17
@@ -XXX,XX +XXX,XX @@ B_cond 0101010 0 ................... 0 cond:4 imm=%imm19
22
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
18
BR 1101011 0000 11111 000000 rn:5 00000 &r
23
return extract32(s->id, 4, 8);
19
BLR 1101011 0001 11111 000000 rn:5 00000 &r
20
RET 1101011 0010 11111 000000 rn:5 00000 &r
21
+
22
+&braz rn m
23
+BRAZ 1101011 0000 11111 00001 m:1 rn:5 11111 &braz # BRAAZ, BRABZ
24
+BLRAZ 1101011 0001 11111 00001 m:1 rn:5 11111 &braz # BLRAAZ, BLRABZ
25
+
26
+&reta m
27
+RETA 1101011 0010 11111 00001 m:1 11111 11111 &reta # RETAA, RETAB
28
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/tcg/translate-a64.c
31
+++ b/target/arm/tcg/translate-a64.c
32
@@ -XXX,XX +XXX,XX @@ static bool trans_RET(DisasContext *s, arg_r *a)
33
return true;
34
}
24
}
35
25
36
+static TCGv_i64 auth_branch_target(DisasContext *s, TCGv_i64 dst,
26
+/* Is CFG_REG2 present? */
37
+ TCGv_i64 modifier, bool use_key_a)
27
+static bool have_cfg2(MPS2SCC *s)
38
+{
28
+{
39
+ TCGv_i64 truedst;
29
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
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;
47
+ }
48
+
49
+ truedst = tcg_temp_new_i64();
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);
54
+ }
55
+ return truedst;
56
+}
30
+}
57
+
31
+
58
+static bool trans_BRAZ(DisasContext *s, arg_braz *a)
32
+/* Is CFG_REG3 present? */
33
+static bool have_cfg3(MPS2SCC *s)
59
+{
34
+{
60
+ TCGv_i64 dst;
35
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
61
+
62
+ if (!dc_isar_feature(aa64_pauth, s)) {
63
+ return false;
64
+ }
65
+
66
+ dst = auth_branch_target(s, cpu_reg(s, a->rn), tcg_constant_i64(0), !a->m);
67
+ gen_a64_set_pc(s, dst);
68
+ set_btype_for_br(s, a->rn);
69
+ s->base.is_jmp = DISAS_JUMP;
70
+ return true;
71
+}
36
+}
72
+
37
+
73
+static bool trans_BLRAZ(DisasContext *s, arg_braz *a)
38
+/* Is CFG_REG5 present? */
39
+static bool have_cfg5(MPS2SCC *s)
74
+{
40
+{
75
+ TCGv_i64 dst, lr;
41
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
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
+}
42
+}
94
+
43
+
95
+static bool trans_RETA(DisasContext *s, arg_reta *a)
44
+/* Is CFG_REG6 present? */
45
+static bool have_cfg6(MPS2SCC *s)
96
+{
46
+{
97
+ TCGv_i64 dst;
47
+ return scc_partno(s) == 0x524;
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
+}
48
+}
104
+
49
+
105
/* HINT instruction group, including various allocated HINTs */
50
/* Handle a write via the SYS_CFG channel to the specified function/device.
106
static void handle_hint(DisasContext *s, uint32_t insn,
51
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
107
unsigned int op1, unsigned int op2, unsigned int crm)
52
*/
108
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
53
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
109
}
54
r = s->cfg1;
110
55
break;
111
switch (opc) {
56
case A_CFG2:
112
- case 0: /* BR */
57
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
113
- case 1: /* BLR */
58
- /* CFG2 reserved on other boards */
114
- case 2: /* RET */
59
+ if (!have_cfg2(s)) {
115
- btype_mod = opc;
60
goto bad_offset;
116
- switch (op3) {
61
}
117
- case 0:
62
r = s->cfg2;
118
- /* BR, BLR, RET : handled in decodetree */
63
break;
119
- goto do_unallocated;
64
case A_CFG3:
120
-
65
- if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
121
- case 2:
66
- /* CFG3 reserved on AN524 */
122
- case 3:
67
+ if (!have_cfg3(s)) {
123
- if (!dc_isar_feature(aa64_pauth, s)) {
68
goto bad_offset;
124
- goto do_unallocated;
69
}
125
- }
70
/* These are user-settable DIP switches on the board. We don't
126
- if (opc == 2) {
71
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
127
- /* RETAA, RETAB */
72
r = s->cfg4;
128
- if (rn != 0x1f || op4 != 0x1f) {
73
break;
129
- goto do_unallocated;
74
case A_CFG5:
130
- }
75
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
131
- rn = 30;
76
- /* CFG5 reserved on other boards */
132
- modifier = cpu_X[31];
77
+ if (!have_cfg5(s)) {
133
- } else {
78
goto bad_offset;
134
- /* BRAAZ, BRABZ, BLRAAZ, BLRABZ */
79
}
135
- if (op4 != 0x1f) {
80
r = s->cfg5;
136
- goto do_unallocated;
81
break;
137
- }
82
case A_CFG6:
138
- modifier = tcg_constant_i64(0);
83
- if (scc_partno(s) != 0x524) {
139
- }
84
- /* CFG6 reserved on other boards */
140
- if (s->pauth_active) {
85
+ if (!have_cfg6(s)) {
141
- dst = tcg_temp_new_i64();
86
goto bad_offset;
142
- if (op3 == 2) {
87
}
143
- gen_helper_autia(dst, cpu_env, cpu_reg(s, rn), modifier);
88
r = s->cfg6;
144
- } else {
89
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
145
- gen_helper_autib(dst, cpu_env, cpu_reg(s, rn), modifier);
90
}
146
- }
91
break;
147
- } else {
92
case A_CFG2:
148
- dst = cpu_reg(s, rn);
93
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
149
- }
94
- /* CFG2 reserved on other boards */
150
- break;
95
+ if (!have_cfg2(s)) {
151
-
96
goto bad_offset;
152
- default:
97
}
153
- goto do_unallocated;
98
/* AN524: QSPI Select signal */
154
- }
99
s->cfg2 = value;
155
- /* BLR also needs to load return address */
100
break;
156
- if (opc == 1) {
101
case A_CFG5:
157
- TCGv_i64 lr = cpu_reg(s, 30);
102
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
158
- if (dst == lr) {
103
- /* CFG5 reserved on other boards */
159
- TCGv_i64 tmp = tcg_temp_new_i64();
104
+ if (!have_cfg5(s)) {
160
- tcg_gen_mov_i64(tmp, dst);
105
goto bad_offset;
161
- dst = tmp;
106
}
162
- }
107
/* AN524: ACLK frequency in Hz */
163
- gen_pc_plus_diff(s, lr, curr_insn_len(s));
108
s->cfg5 = value;
164
- }
109
break;
165
- gen_a64_set_pc(s, dst);
110
case A_CFG6:
166
- break;
111
- if (scc_partno(s) != 0x524) {
167
+ case 0:
112
- /* CFG6 reserved on other boards */
168
+ case 1:
113
+ if (!have_cfg6(s)) {
169
+ case 2:
114
goto bad_offset;
170
+ /*
115
}
171
+ * BR, BLR, RET, RETAA, RETAB, BRAAZ, BRABZ, BLRAAZ, BLRABZ:
116
/* AN524: Clock divider for BRAM */
172
+ * handled in decodetree
173
+ */
174
+ goto do_unallocated;
175
176
case 8: /* BRAA */
177
case 9: /* BLRAA */
178
--
117
--
179
2.34.1
118
2.34.1
119
120
diff view generated by jsdifflib
1
The SVE and SME decode is already done by decodetree. Pull the calls
1
The MPS2 SCC device is broadly the same for all FPGA images, but has
2
to these decoders out of the legacy decoder. This doesn't change
2
minor differences in the behaviour of the CFG registers depending on
3
behaviour because all the patterns in sve.decode and sme.decode
3
the image. In many cases we don't really care about the functionality
4
already require the bits that the legacy decoder is decoding to have
4
controlled by these registers and a reads-as-written or similar
5
the correct values.
5
behaviour is sufficient for the moment.
6
7
For the AN536 the required behaviour is:
8
9
* A_CFG0 has CPU reset and halt bits
10
- implement as reads-as-written for the moment
11
* A_CFG1 has flash or ATCM address 0 remap handling
12
- QEMU doesn't model this; implement as reads-as-written
13
* A_CFG2 has QSPI select (like AN524)
14
- implemented (no behaviour, as with AN524)
15
* A_CFG3 is MCC_MSB_ADDR "additional MCC addressing bits"
16
- QEMU doesn't care about these, so use the existing
17
RAZ behaviour for convenience
18
* A_CFG4 is board rev (like all other images)
19
- no change needed
20
* A_CFG5 is ACLK frq in hz (like AN524)
21
- implemented as reads-as-written, as for other boards
22
* A_CFG6 is core 0 vector table base address
23
- implemented as reads-as-written for the moment
24
* A_CFG7 is core 1 vector table base address
25
- implemented as reads-as-written for the moment
26
27
Make the changes necessary for this; leave TODO comments where
28
appropriate to indicate where we might want to come back and
29
implement things like CPU reset.
30
31
The other aspects of the device specific to this FPGA image (like the
32
values of the board ID and similar registers) will be set via the
33
device's qdev properties.
6
34
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
36
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230512144106.3608981-4-peter.maydell@linaro.org
37
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
38
Message-id: 20240206132931.38376-8-peter.maydell@linaro.org
10
---
39
---
11
target/arm/tcg/translate-a64.c | 20 ++++----------------
40
include/hw/misc/mps2-scc.h | 1 +
12
1 file changed, 4 insertions(+), 16 deletions(-)
41
hw/misc/mps2-scc.c | 101 +++++++++++++++++++++++++++++++++----
13
42
2 files changed, 92 insertions(+), 10 deletions(-)
14
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
43
44
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
15
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/tcg/translate-a64.c
46
--- a/include/hw/misc/mps2-scc.h
17
+++ b/target/arm/tcg/translate-a64.c
47
+++ b/include/hw/misc/mps2-scc.h
18
@@ -XXX,XX +XXX,XX @@ static bool btype_destination_ok(uint32_t insn, bool bt, int btype)
48
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
19
static void disas_a64_legacy(DisasContext *s, uint32_t insn)
49
uint32_t cfg4;
20
{
50
uint32_t cfg5;
21
switch (extract32(insn, 25, 4)) {
51
uint32_t cfg6;
22
- case 0x0:
52
+ uint32_t cfg7;
23
- if (!extract32(insn, 31, 1) || !disas_sme(s, insn)) {
53
uint32_t cfgdata_rtn;
24
- unallocated_encoding(s);
54
uint32_t cfgdata_out;
25
- }
55
uint32_t cfgctrl;
26
- break;
56
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
27
- case 0x1: case 0x3: /* UNALLOCATED */
57
index XXXXXXX..XXXXXXX 100644
28
- unallocated_encoding(s);
58
--- a/hw/misc/mps2-scc.c
29
- break;
59
+++ b/hw/misc/mps2-scc.c
30
- case 0x2:
60
@@ -XXX,XX +XXX,XX @@ REG32(CFG3, 0xc)
31
- if (!disas_sve(s, insn)) {
61
REG32(CFG4, 0x10)
32
- unallocated_encoding(s);
62
REG32(CFG5, 0x14)
33
- }
63
REG32(CFG6, 0x18)
34
- break;
64
+REG32(CFG7, 0x1c)
35
case 0x8: case 0x9: /* Data processing - immediate */
65
REG32(CFGDATA_RTN, 0xa0)
36
disas_data_proc_imm(s, insn);
66
REG32(CFGDATA_OUT, 0xa4)
37
break;
67
REG32(CFGCTRL, 0xa8)
38
@@ -XXX,XX +XXX,XX @@ static void disas_a64_legacy(DisasContext *s, uint32_t insn)
68
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
39
disas_data_proc_simd_fp(s, insn);
69
/* Is CFG_REG2 present? */
40
break;
70
static bool have_cfg2(MPS2SCC *s)
41
default:
71
{
42
- assert(FALSE); /* all 15 cases should be handled above */
72
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
43
+ unallocated_encoding(s);
73
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
44
break;
74
+ scc_partno(s) == 0x536;
75
}
76
77
/* Is CFG_REG3 present? */
78
static bool have_cfg3(MPS2SCC *s)
79
{
80
- return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
81
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547 &&
82
+ scc_partno(s) != 0x536;
83
}
84
85
/* Is CFG_REG5 present? */
86
static bool have_cfg5(MPS2SCC *s)
87
{
88
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
89
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
90
+ scc_partno(s) == 0x536;
91
}
92
93
/* Is CFG_REG6 present? */
94
static bool have_cfg6(MPS2SCC *s)
95
{
96
- return scc_partno(s) == 0x524;
97
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x536;
98
+}
99
+
100
+/* Is CFG_REG7 present? */
101
+static bool have_cfg7(MPS2SCC *s)
102
+{
103
+ return scc_partno(s) == 0x536;
104
+}
105
+
106
+/* Does CFG_REG0 drive the 'remap' GPIO output? */
107
+static bool cfg0_is_remap(MPS2SCC *s)
108
+{
109
+ return scc_partno(s) != 0x536;
110
+}
111
+
112
+/* Is CFG_REG1 driving a set of LEDs? */
113
+static bool cfg1_is_leds(MPS2SCC *s)
114
+{
115
+ return scc_partno(s) != 0x536;
116
}
117
118
/* Handle a write via the SYS_CFG channel to the specified function/device.
119
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
120
if (!have_cfg3(s)) {
121
goto bad_offset;
122
}
123
- /* These are user-settable DIP switches on the board. We don't
124
+ /*
125
+ * These are user-settable DIP switches on the board. We don't
126
* model that, so just return zeroes.
127
+ *
128
+ * TODO: for AN536 this is MCC_MSB_ADDR "additional MCC addressing
129
+ * bits". These change which part of the DDR4 the motherboard
130
+ * configuration controller can see in its memory map (see the
131
+ * appnote section 2.4). QEMU doesn't model the MCC at all, so these
132
+ * bits are not interesting to us; read-as-zero is as good as anything
133
+ * else.
134
*/
135
r = 0;
136
break;
137
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
138
}
139
r = s->cfg6;
140
break;
141
+ case A_CFG7:
142
+ if (!have_cfg7(s)) {
143
+ goto bad_offset;
144
+ }
145
+ r = s->cfg7;
146
+ break;
147
case A_CFGDATA_RTN:
148
r = s->cfgdata_rtn;
149
break;
150
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
151
* we always reflect bit 0 in the 'remap' GPIO output line,
152
* and let the board wire it up or not as it chooses.
153
* TODO on some boards bit 1 is CPU_WAIT.
154
+ *
155
+ * TODO: on the AN536 this register controls reset and halt
156
+ * for both CPUs. For the moment we don't implement this, so the
157
+ * register just reads as written.
158
*/
159
s->cfg0 = value;
160
- qemu_set_irq(s->remap, s->cfg0 & 1);
161
+ if (cfg0_is_remap(s)) {
162
+ qemu_set_irq(s->remap, s->cfg0 & 1);
163
+ }
164
break;
165
case A_CFG1:
166
s->cfg1 = value;
167
- for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
168
- led_set_state(s->led[i], extract32(value, i, 1));
169
+ /*
170
+ * On most boards this register drives LEDs.
171
+ *
172
+ * TODO: for AN536 this controls whether flash and ATCM are
173
+ * enabled or disabled on reset. QEMU doesn't model this, and
174
+ * always wires up RAM in the ATCM area and ROM in the flash area.
175
+ */
176
+ if (cfg1_is_leds(s)) {
177
+ for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
178
+ led_set_state(s->led[i], extract32(value, i, 1));
179
+ }
180
}
181
break;
182
case A_CFG2:
183
if (!have_cfg2(s)) {
184
goto bad_offset;
185
}
186
- /* AN524: QSPI Select signal */
187
+ /* AN524, AN536: QSPI Select signal */
188
s->cfg2 = value;
189
break;
190
case A_CFG5:
191
if (!have_cfg5(s)) {
192
goto bad_offset;
193
}
194
- /* AN524: ACLK frequency in Hz */
195
+ /* AN524, AN536: ACLK frequency in Hz */
196
s->cfg5 = value;
197
break;
198
case A_CFG6:
199
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
200
goto bad_offset;
201
}
202
/* AN524: Clock divider for BRAM */
203
+ /* AN536: Core 0 vector table base address */
204
+ s->cfg6 = value;
205
+ break;
206
+ case A_CFG7:
207
+ if (!have_cfg7(s)) {
208
+ goto bad_offset;
209
+ }
210
+ /* AN536: Core 1 vector table base address */
211
s->cfg6 = value;
212
break;
213
case A_CFGDATA_OUT:
214
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_finalize(Object *obj)
215
g_free(s->oscclk_reset);
216
}
217
218
+static bool cfg7_needed(void *opaque)
219
+{
220
+ MPS2SCC *s = opaque;
221
+
222
+ return have_cfg7(s);
223
+}
224
+
225
+static const VMStateDescription vmstate_cfg7 = {
226
+ .name = "mps2-scc/cfg7",
227
+ .version_id = 1,
228
+ .minimum_version_id = 1,
229
+ .needed = cfg7_needed,
230
+ .fields = (const VMStateField[]) {
231
+ VMSTATE_UINT32(cfg7, MPS2SCC),
232
+ VMSTATE_END_OF_LIST()
233
+ }
234
+};
235
+
236
static const VMStateDescription mps2_scc_vmstate = {
237
.name = "mps2-scc",
238
.version_id = 3,
239
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_scc_vmstate = {
240
VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
241
0, vmstate_info_uint32, uint32_t),
242
VMSTATE_END_OF_LIST()
243
+ },
244
+ .subsections = (const VMStateDescription * const []) {
245
+ &vmstate_cfg7,
246
+ NULL
45
}
247
}
46
}
248
};
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
}
58
249
59
--
250
--
60
2.34.1
251
2.34.1
252
253
diff view generated by jsdifflib
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
1
The AN536 is another FPGA image for the MPS3 development board. Unlike
2
2
the existing FPGA images we already model, this board uses a Cortex-R
3
At Linaro I work on sbsa-ref, know direction it goes.
3
family CPU, and it does not use any equivalent to the M-profile
4
4
"Subsystem for Embedded" SoC-equivalent that we model in hw/arm/armsse.c.
5
May not get code details each time.
5
It's therefore more convenient for us to model it as a completely
6
6
separate C file.
7
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
7
8
This commit adds the basic skeleton of the board model, and the
9
code to create all the RAM and ROM. We assume that we're probably
10
going to want to add more images in future, so use the same
11
base class/subclass setup that mps2-tz.c uses, even though at
12
the moment there's only a single subclass.
13
14
Following commits will add the CPUs and the peripherals.
15
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20230515143753.365591-1-marcin.juszkiewicz@linaro.org
18
Message-id: 20240206132931.38376-9-peter.maydell@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
19
---
12
MAINTAINERS | 1 +
20
MAINTAINERS | 3 +-
13
1 file changed, 1 insertion(+)
21
configs/devices/arm-softmmu/default.mak | 1 +
22
hw/arm/mps3r.c | 239 ++++++++++++++++++++++++
23
hw/arm/Kconfig | 5 +
24
hw/arm/meson.build | 1 +
25
5 files changed, 248 insertions(+), 1 deletion(-)
26
create mode 100644 hw/arm/mps3r.c
14
27
15
diff --git a/MAINTAINERS b/MAINTAINERS
28
diff --git a/MAINTAINERS b/MAINTAINERS
16
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
17
--- a/MAINTAINERS
30
--- a/MAINTAINERS
18
+++ b/MAINTAINERS
31
+++ b/MAINTAINERS
19
@@ -XXX,XX +XXX,XX @@ SBSA-REF
32
@@ -XXX,XX +XXX,XX @@ F: include/hw/misc/imx7_*.h
20
M: Radoslaw Biernacki <rad@semihalf.com>
33
F: hw/pci-host/designware.c
34
F: include/hw/pci-host/designware.h
35
36
-MPS2
37
+MPS2 / MPS3
21
M: Peter Maydell <peter.maydell@linaro.org>
38
M: Peter Maydell <peter.maydell@linaro.org>
22
R: Leif Lindholm <quic_llindhol@quicinc.com>
23
+R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
24
L: qemu-arm@nongnu.org
39
L: qemu-arm@nongnu.org
25
S: Maintained
40
S: Maintained
26
F: hw/arm/sbsa-ref.c
41
F: hw/arm/mps2.c
42
F: hw/arm/mps2-tz.c
43
+F: hw/arm/mps3r.c
44
F: hw/misc/mps2-*.c
45
F: include/hw/misc/mps2-*.h
46
F: hw/arm/armsse.c
47
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
48
index XXXXXXX..XXXXXXX 100644
49
--- a/configs/devices/arm-softmmu/default.mak
50
+++ b/configs/devices/arm-softmmu/default.mak
51
@@ -XXX,XX +XXX,XX @@ CONFIG_ARM_VIRT=y
52
# CONFIG_INTEGRATOR=n
53
# CONFIG_FSL_IMX31=n
54
# CONFIG_MUSICPAL=n
55
+# CONFIG_MPS3R=n
56
# CONFIG_MUSCA=n
57
# CONFIG_CHEETAH=n
58
# CONFIG_SX1=n
59
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
60
new file mode 100644
61
index XXXXXXX..XXXXXXX
62
--- /dev/null
63
+++ b/hw/arm/mps3r.c
64
@@ -XXX,XX +XXX,XX @@
65
+/*
66
+ * Arm MPS3 board emulation for Cortex-R-based FPGA images.
67
+ * (For M-profile images see mps2.c and mps2tz.c.)
68
+ *
69
+ * Copyright (c) 2017 Linaro Limited
70
+ * Written by Peter Maydell
71
+ *
72
+ * This program is free software; you can redistribute it and/or modify
73
+ * it under the terms of the GNU General Public License version 2 or
74
+ * (at your option) any later version.
75
+ */
76
+
77
+/*
78
+ * The MPS3 is an FPGA based dev board. This file handles FPGA images
79
+ * which use the Cortex-R CPUs. We model these separately from the
80
+ * M-profile images, because on M-profile the FPGA image is based on
81
+ * a "Subsystem for Embedded" which is similar to an SoC, whereas
82
+ * the R-profile FPGA images don't have that abstraction layer.
83
+ *
84
+ * We model the following FPGA images here:
85
+ * "mps3-an536" -- dual Cortex-R52 as documented in Arm Application Note AN536
86
+ *
87
+ * Application Note AN536:
88
+ * https://developer.arm.com/documentation/dai0536/latest/
89
+ */
90
+
91
+#include "qemu/osdep.h"
92
+#include "qemu/units.h"
93
+#include "qapi/error.h"
94
+#include "exec/address-spaces.h"
95
+#include "cpu.h"
96
+#include "hw/boards.h"
97
+#include "hw/arm/boot.h"
98
+
99
+/* Define the layout of RAM and ROM in a board */
100
+typedef struct RAMInfo {
101
+ const char *name;
102
+ hwaddr base;
103
+ hwaddr size;
104
+ int mrindex; /* index into rams[]; -1 for the system RAM block */
105
+ int flags;
106
+} RAMInfo;
107
+
108
+/*
109
+ * The MPS3 DDR is 3GiB, but on a 32-bit host QEMU doesn't permit
110
+ * emulation of that much guest RAM, so artificially make it smaller.
111
+ */
112
+#if HOST_LONG_BITS == 32
113
+#define MPS3_DDR_SIZE (1 * GiB)
114
+#else
115
+#define MPS3_DDR_SIZE (3 * GiB)
116
+#endif
117
+
118
+/*
119
+ * Flag values:
120
+ * IS_MAIN: this is the main machine RAM
121
+ * IS_ROM: this area is read-only
122
+ */
123
+#define IS_MAIN 1
124
+#define IS_ROM 2
125
+
126
+#define MPS3R_RAM_MAX 9
127
+
128
+typedef enum MPS3RFPGAType {
129
+ FPGA_AN536,
130
+} MPS3RFPGAType;
131
+
132
+struct MPS3RMachineClass {
133
+ MachineClass parent;
134
+ MPS3RFPGAType fpga_type;
135
+ const RAMInfo *raminfo;
136
+};
137
+
138
+struct MPS3RMachineState {
139
+ MachineState parent;
140
+ MemoryRegion ram[MPS3R_RAM_MAX];
141
+};
142
+
143
+#define TYPE_MPS3R_MACHINE "mps3r"
144
+#define TYPE_MPS3R_AN536_MACHINE MACHINE_TYPE_NAME("mps3-an536")
145
+
146
+OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
147
+
148
+static const RAMInfo an536_raminfo[] = {
149
+ {
150
+ .name = "ATCM",
151
+ .base = 0x00000000,
152
+ .size = 0x00008000,
153
+ .mrindex = 0,
154
+ }, {
155
+ /* We model the QSPI flash as simple ROM for now */
156
+ .name = "QSPI",
157
+ .base = 0x08000000,
158
+ .size = 0x00800000,
159
+ .flags = IS_ROM,
160
+ .mrindex = 1,
161
+ }, {
162
+ .name = "BRAM",
163
+ .base = 0x10000000,
164
+ .size = 0x00080000,
165
+ .mrindex = 2,
166
+ }, {
167
+ .name = "DDR",
168
+ .base = 0x20000000,
169
+ .size = MPS3_DDR_SIZE,
170
+ .mrindex = -1,
171
+ }, {
172
+ .name = "ATCM0",
173
+ .base = 0xee000000,
174
+ .size = 0x00008000,
175
+ .mrindex = 3,
176
+ }, {
177
+ .name = "BTCM0",
178
+ .base = 0xee100000,
179
+ .size = 0x00008000,
180
+ .mrindex = 4,
181
+ }, {
182
+ .name = "CTCM0",
183
+ .base = 0xee200000,
184
+ .size = 0x00008000,
185
+ .mrindex = 5,
186
+ }, {
187
+ .name = "ATCM1",
188
+ .base = 0xee400000,
189
+ .size = 0x00008000,
190
+ .mrindex = 6,
191
+ }, {
192
+ .name = "BTCM1",
193
+ .base = 0xee500000,
194
+ .size = 0x00008000,
195
+ .mrindex = 7,
196
+ }, {
197
+ .name = "CTCM1",
198
+ .base = 0xee600000,
199
+ .size = 0x00008000,
200
+ .mrindex = 8,
201
+ }, {
202
+ .name = NULL,
203
+ }
204
+};
205
+
206
+static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
207
+ const RAMInfo *raminfo)
208
+{
209
+ /* Return an initialized MemoryRegion for the RAMInfo. */
210
+ MemoryRegion *ram;
211
+
212
+ if (raminfo->mrindex < 0) {
213
+ /* Means this RAMInfo is for QEMU's "system memory" */
214
+ MachineState *machine = MACHINE(mms);
215
+ assert(!(raminfo->flags & IS_ROM));
216
+ return machine->ram;
217
+ }
218
+
219
+ assert(raminfo->mrindex < MPS3R_RAM_MAX);
220
+ ram = &mms->ram[raminfo->mrindex];
221
+
222
+ memory_region_init_ram(ram, NULL, raminfo->name,
223
+ raminfo->size, &error_fatal);
224
+ if (raminfo->flags & IS_ROM) {
225
+ memory_region_set_readonly(ram, true);
226
+ }
227
+ return ram;
228
+}
229
+
230
+static void mps3r_common_init(MachineState *machine)
231
+{
232
+ MPS3RMachineState *mms = MPS3R_MACHINE(machine);
233
+ MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
234
+ MemoryRegion *sysmem = get_system_memory();
235
+
236
+ for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
237
+ MemoryRegion *mr = mr_for_raminfo(mms, ri);
238
+ memory_region_add_subregion(sysmem, ri->base, mr);
239
+ }
240
+}
241
+
242
+static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
243
+{
244
+ /*
245
+ * Set mc->default_ram_size and default_ram_id from the
246
+ * information in mmc->raminfo.
247
+ */
248
+ MachineClass *mc = MACHINE_CLASS(mmc);
249
+ const RAMInfo *p;
250
+
251
+ for (p = mmc->raminfo; p->name; p++) {
252
+ if (p->mrindex < 0) {
253
+ /* Found the entry for "system memory" */
254
+ mc->default_ram_size = p->size;
255
+ mc->default_ram_id = p->name;
256
+ return;
257
+ }
258
+ }
259
+ g_assert_not_reached();
260
+}
261
+
262
+static void mps3r_class_init(ObjectClass *oc, void *data)
263
+{
264
+ MachineClass *mc = MACHINE_CLASS(oc);
265
+
266
+ mc->init = mps3r_common_init;
267
+}
268
+
269
+static void mps3r_an536_class_init(ObjectClass *oc, void *data)
270
+{
271
+ MachineClass *mc = MACHINE_CLASS(oc);
272
+ MPS3RMachineClass *mmc = MPS3R_MACHINE_CLASS(oc);
273
+ static const char * const valid_cpu_types[] = {
274
+ ARM_CPU_TYPE_NAME("cortex-r52"),
275
+ NULL
276
+ };
277
+
278
+ mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
279
+ mc->default_cpus = 2;
280
+ mc->min_cpus = mc->default_cpus;
281
+ mc->max_cpus = mc->default_cpus;
282
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
283
+ mc->valid_cpu_types = valid_cpu_types;
284
+ mmc->raminfo = an536_raminfo;
285
+ mps3r_set_default_ram_info(mmc);
286
+}
287
+
288
+static const TypeInfo mps3r_machine_types[] = {
289
+ {
290
+ .name = TYPE_MPS3R_MACHINE,
291
+ .parent = TYPE_MACHINE,
292
+ .abstract = true,
293
+ .instance_size = sizeof(MPS3RMachineState),
294
+ .class_size = sizeof(MPS3RMachineClass),
295
+ .class_init = mps3r_class_init,
296
+ }, {
297
+ .name = TYPE_MPS3R_AN536_MACHINE,
298
+ .parent = TYPE_MPS3R_MACHINE,
299
+ .class_init = mps3r_an536_class_init,
300
+ },
301
+};
302
+
303
+DEFINE_TYPES(mps3r_machine_types);
304
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
305
index XXXXXXX..XXXXXXX 100644
306
--- a/hw/arm/Kconfig
307
+++ b/hw/arm/Kconfig
308
@@ -XXX,XX +XXX,XX @@ config MAINSTONE
309
select PFLASH_CFI01
310
select SMC91C111
311
312
+config MPS3R
313
+ bool
314
+ default y
315
+ depends on TCG && ARM
316
+
317
config MUSCA
318
bool
319
default y
320
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
321
index XXXXXXX..XXXXXXX 100644
322
--- a/hw/arm/meson.build
323
+++ b/hw/arm/meson.build
324
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_HIGHBANK', if_true: files('highbank.c'))
325
arm_ss.add(when: 'CONFIG_INTEGRATOR', if_true: files('integratorcp.c'))
326
arm_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mainstone.c'))
327
arm_ss.add(when: 'CONFIG_MICROBIT', if_true: files('microbit.c'))
328
+arm_ss.add(when: 'CONFIG_MPS3R', if_true: files('mps3r.c'))
329
arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
330
arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c'))
331
arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c'))
27
--
332
--
28
2.34.1
333
2.34.1
29
334
30
335
diff view generated by jsdifflib
1
Convert the simple (non-pointer-auth) BR, BLR and RET insns
1
Create the CPUs, the GIC, and the per-CPU RAM block for
2
to decodetree.
2
the mps3-an536 board.
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20240206132931.38376-10-peter.maydell@linaro.org
6
Message-id: 20230512144106.3608981-18-peter.maydell@linaro.org
7
---
6
---
8
target/arm/tcg/a64.decode | 5 ++++
7
hw/arm/mps3r.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++++-
9
target/arm/tcg/translate-a64.c | 55 ++++++++++++++++++++++++++++++----
8
1 file changed, 177 insertions(+), 3 deletions(-)
10
2 files changed, 54 insertions(+), 6 deletions(-)
11
9
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
10
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
13
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/a64.decode
12
--- a/hw/arm/mps3r.c
15
+++ b/target/arm/tcg/a64.decode
13
+++ b/hw/arm/mps3r.c
16
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@
17
# This file is processed by scripts/decodetree.py
15
#include "qemu/osdep.h"
18
#
16
#include "qemu/units.h"
19
17
#include "qapi/error.h"
20
+&r rn
18
+#include "qapi/qmp/qlist.h"
21
&ri rd imm
19
#include "exec/address-spaces.h"
22
&rri_sf rd rn imm sf
20
#include "cpu.h"
23
&i imm
21
#include "hw/boards.h"
24
@@ -XXX,XX +XXX,XX @@ CBZ sf:1 011010 nz:1 ................... rt:5 &cbz imm=%imm19
22
+#include "hw/qdev-properties.h"
25
TBZ . 011011 nz:1 ..... .............. rt:5 &tbz imm=%imm14 bitpos=%imm31_19
23
#include "hw/arm/boot.h"
26
24
+#include "hw/arm/bsa.h"
27
B_cond 0101010 0 ................... 0 cond:4 imm=%imm19
25
+#include "hw/intc/arm_gicv3.h"
28
+
26
29
+BR 1101011 0000 11111 000000 rn:5 00000 &r
27
/* Define the layout of RAM and ROM in a board */
30
+BLR 1101011 0001 11111 000000 rn:5 00000 &r
28
typedef struct RAMInfo {
31
+RET 1101011 0010 11111 000000 rn:5 00000 &r
29
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
32
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
30
#define IS_ROM 2
33
index XXXXXXX..XXXXXXX 100644
31
34
--- a/target/arm/tcg/translate-a64.c
32
#define MPS3R_RAM_MAX 9
35
+++ b/target/arm/tcg/translate-a64.c
33
+#define MPS3R_CPU_MAX 2
36
@@ -XXX,XX +XXX,XX @@ static bool trans_B_cond(DisasContext *s, arg_B_cond *a)
34
+
37
return true;
35
+#define PERIPHBASE 0xf0000000
36
+#define NUM_SPIS 96
37
38
typedef enum MPS3RFPGAType {
39
FPGA_AN536,
40
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineClass {
41
MachineClass parent;
42
MPS3RFPGAType fpga_type;
43
const RAMInfo *raminfo;
44
+ hwaddr loader_start;
45
};
46
47
struct MPS3RMachineState {
48
MachineState parent;
49
+ struct arm_boot_info bootinfo;
50
MemoryRegion ram[MPS3R_RAM_MAX];
51
+ Object *cpu[MPS3R_CPU_MAX];
52
+ MemoryRegion cpu_sysmem[MPS3R_CPU_MAX];
53
+ MemoryRegion sysmem_alias[MPS3R_CPU_MAX];
54
+ MemoryRegion cpu_ram[MPS3R_CPU_MAX];
55
+ GICv3State gic;
56
};
57
58
#define TYPE_MPS3R_MACHINE "mps3r"
59
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
60
return ram;
38
}
61
}
39
62
40
+static void set_btype_for_br(DisasContext *s, int rn)
63
+/*
64
+ * There is no defined secondary boot protocol for Linux for the AN536,
65
+ * because real hardware has a restriction that atomic operations between
66
+ * the two CPUs do not function correctly, and so true SMP is not
67
+ * possible. Therefore for cases where the user is directly booting
68
+ * a kernel, we treat the system as essentially uniprocessor, and
69
+ * put the secondary CPU into power-off state (as if the user on the
70
+ * real hardware had configured the secondary to be halted via the
71
+ * SCC config registers).
72
+ *
73
+ * Note that the default secondary boot code would not work here anyway
74
+ * as it assumes a GICv2, and we have a GICv3.
75
+ */
76
+static void mps3r_write_secondary_boot(ARMCPU *cpu,
77
+ const struct arm_boot_info *info)
41
+{
78
+{
42
+ if (dc_isar_feature(aa64_bti, s)) {
79
+ /*
43
+ /* BR to {x16,x17} or !guard -> 1, else 3. */
80
+ * Power the secondary CPU off. This means we don't need to write any
44
+ set_btype(s, rn == 16 || rn == 17 || !s->guarded_page ? 1 : 3);
81
+ * boot code into guest memory. Note that the 'cpu' argument to this
82
+ * function is the primary CPU we passed to arm_load_kernel(), not
83
+ * the secondary. Loop around all the other CPUs, as the boot.c
84
+ * code does for the "disable secondaries if PSCI is enabled" case.
85
+ */
86
+ for (CPUState *cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
87
+ if (cs != first_cpu) {
88
+ object_property_set_bool(OBJECT(cs), "start-powered-off", true,
89
+ &error_abort);
90
+ }
45
+ }
91
+ }
46
+}
92
+}
47
+
93
+
48
+static void set_btype_for_blr(DisasContext *s)
94
+static void mps3r_secondary_cpu_reset(ARMCPU *cpu,
95
+ const struct arm_boot_info *info)
49
+{
96
+{
50
+ if (dc_isar_feature(aa64_bti, s)) {
97
+ /* We don't need to do anything here because the CPU will be off */
51
+ /* BLR sets BTYPE to 2, regardless of source guarded page. */
98
+}
52
+ set_btype(s, 2);
99
+
100
+static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
101
+{
102
+ MachineState *machine = MACHINE(mms);
103
+ DeviceState *gicdev;
104
+ QList *redist_region_count;
105
+
106
+ object_initialize_child(OBJECT(mms), "gic", &mms->gic, TYPE_ARM_GICV3);
107
+ gicdev = DEVICE(&mms->gic);
108
+ qdev_prop_set_uint32(gicdev, "num-cpu", machine->smp.cpus);
109
+ qdev_prop_set_uint32(gicdev, "num-irq", NUM_SPIS + GIC_INTERNAL);
110
+ redist_region_count = qlist_new();
111
+ qlist_append_int(redist_region_count, machine->smp.cpus);
112
+ qdev_prop_set_array(gicdev, "redist-region-count", redist_region_count);
113
+ object_property_set_link(OBJECT(&mms->gic), "sysmem",
114
+ OBJECT(sysmem), &error_fatal);
115
+ sysbus_realize(SYS_BUS_DEVICE(&mms->gic), &error_fatal);
116
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->gic), 0, PERIPHBASE);
117
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->gic), 1, PERIPHBASE + 0x100000);
118
+ /*
119
+ * Wire the outputs from each CPU's generic timer and the GICv3
120
+ * maintenance interrupt signal to the appropriate GIC PPI inputs,
121
+ * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
122
+ */
123
+ for (int i = 0; i < machine->smp.cpus; i++) {
124
+ DeviceState *cpudev = DEVICE(mms->cpu[i]);
125
+ SysBusDevice *gicsbd = SYS_BUS_DEVICE(&mms->gic);
126
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
127
+ int irq;
128
+ /*
129
+ * Mapping from the output timer irq lines from the CPU to the
130
+ * GIC PPI inputs used for this board. This isn't a BSA board,
131
+ * but it uses the standard convention for the PPI numbers.
132
+ */
133
+ const int timer_irq[] = {
134
+ [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
135
+ [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
136
+ [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
137
+ };
138
+
139
+ for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
140
+ qdev_connect_gpio_out(cpudev, irq,
141
+ qdev_get_gpio_in(gicdev,
142
+ intidbase + timer_irq[irq]));
143
+ }
144
+
145
+ qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
146
+ qdev_get_gpio_in(gicdev,
147
+ intidbase + ARCH_GIC_MAINT_IRQ));
148
+
149
+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
150
+ qdev_get_gpio_in(gicdev,
151
+ intidbase + VIRTUAL_PMU_IRQ));
152
+
153
+ sysbus_connect_irq(gicsbd, i,
154
+ qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
155
+ sysbus_connect_irq(gicsbd, i + machine->smp.cpus,
156
+ qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
157
+ sysbus_connect_irq(gicsbd, i + 2 * machine->smp.cpus,
158
+ qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
159
+ sysbus_connect_irq(gicsbd, i + 3 * machine->smp.cpus,
160
+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
53
+ }
161
+ }
54
+}
162
+}
55
+
163
+
56
+static bool trans_BR(DisasContext *s, arg_r *a)
164
static void mps3r_common_init(MachineState *machine)
57
+{
165
{
58
+ gen_a64_set_pc(s, cpu_reg(s, a->rn));
166
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
59
+ set_btype_for_br(s, a->rn);
167
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
60
+ s->base.is_jmp = DISAS_JUMP;
168
MemoryRegion *mr = mr_for_raminfo(mms, ri);
61
+ return true;
169
memory_region_add_subregion(sysmem, ri->base, mr);
62
+}
170
}
63
+
171
+
64
+static bool trans_BLR(DisasContext *s, arg_r *a)
172
+ assert(machine->smp.cpus <= MPS3R_CPU_MAX);
65
+{
173
+ for (int i = 0; i < machine->smp.cpus; i++) {
66
+ TCGv_i64 dst = cpu_reg(s, a->rn);
174
+ g_autofree char *sysmem_name = g_strdup_printf("cpu-%d-memory", i);
67
+ TCGv_i64 lr = cpu_reg(s, 30);
175
+ g_autofree char *ramname = g_strdup_printf("cpu-%d-memory", i);
68
+ if (dst == lr) {
176
+ g_autofree char *alias_name = g_strdup_printf("sysmem-alias-%d", i);
69
+ TCGv_i64 tmp = tcg_temp_new_i64();
177
+
70
+ tcg_gen_mov_i64(tmp, dst);
178
+ /*
71
+ dst = tmp;
179
+ * Each CPU has some private RAM/peripherals, so create the container
180
+ * which will house those, with the whole-machine system memory being
181
+ * used where there's no CPU-specific device. Note that we need the
182
+ * sysmem_alias aliases because we can't put one MR (the original
183
+ * 'sysmem') into more than one other MR.
184
+ */
185
+ memory_region_init(&mms->cpu_sysmem[i], OBJECT(machine),
186
+ sysmem_name, UINT64_MAX);
187
+ memory_region_init_alias(&mms->sysmem_alias[i], OBJECT(machine),
188
+ alias_name, sysmem, 0, UINT64_MAX);
189
+ memory_region_add_subregion_overlap(&mms->cpu_sysmem[i], 0,
190
+ &mms->sysmem_alias[i], -1);
191
+
192
+ mms->cpu[i] = object_new(machine->cpu_type);
193
+ object_property_set_link(mms->cpu[i], "memory",
194
+ OBJECT(&mms->cpu_sysmem[i]), &error_abort);
195
+ object_property_set_int(mms->cpu[i], "reset-cbar",
196
+ PERIPHBASE, &error_abort);
197
+ qdev_realize(DEVICE(mms->cpu[i]), NULL, &error_fatal);
198
+ object_unref(mms->cpu[i]);
199
+
200
+ /* Per-CPU RAM */
201
+ memory_region_init_ram(&mms->cpu_ram[i], NULL, ramname,
202
+ 0x1000, &error_fatal);
203
+ memory_region_add_subregion(&mms->cpu_sysmem[i], 0xe7c01000,
204
+ &mms->cpu_ram[i]);
72
+ }
205
+ }
73
+ gen_pc_plus_diff(s, lr, curr_insn_len(s));
206
+
74
+ gen_a64_set_pc(s, dst);
207
+ create_gic(mms, sysmem);
75
+ set_btype_for_blr(s);
208
+
76
+ s->base.is_jmp = DISAS_JUMP;
209
+ mms->bootinfo.ram_size = machine->ram_size;
77
+ return true;
210
+ mms->bootinfo.board_id = -1;
78
+}
211
+ mms->bootinfo.loader_start = mmc->loader_start;
79
+
212
+ mms->bootinfo.write_secondary_boot = mps3r_write_secondary_boot;
80
+static bool trans_RET(DisasContext *s, arg_r *a)
213
+ mms->bootinfo.secondary_cpu_reset_hook = mps3r_secondary_cpu_reset;
81
+{
214
+ arm_load_kernel(ARM_CPU(mms->cpu[0]), machine, &mms->bootinfo);
82
+ gen_a64_set_pc(s, cpu_reg(s, a->rn));
215
}
83
+ s->base.is_jmp = DISAS_JUMP;
216
84
+ return true;
217
static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
85
+}
218
@@ -XXX,XX +XXX,XX @@ static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
86
+
219
/* Found the entry for "system memory" */
87
/* HINT instruction group, including various allocated HINTs */
220
mc->default_ram_size = p->size;
88
static void handle_hint(DisasContext *s, uint32_t insn,
221
mc->default_ram_id = p->name;
89
unsigned int op1, unsigned int op2, unsigned int crm)
222
+ mmc->loader_start = p->base;
90
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
223
return;
91
btype_mod = opc;
224
}
92
switch (op3) {
225
}
93
case 0:
226
@@ -XXX,XX +XXX,XX @@ static void mps3r_an536_class_init(ObjectClass *oc, void *data)
94
- /* BR, BLR, RET */
227
};
95
- if (op4 != 0) {
228
96
- goto do_unallocated;
229
mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
97
- }
230
- mc->default_cpus = 2;
98
- dst = cpu_reg(s, rn);
231
- mc->min_cpus = mc->default_cpus;
99
- break;
232
- mc->max_cpus = mc->default_cpus;
100
+ /* BR, BLR, RET : handled in decodetree */
233
+ /*
101
+ goto do_unallocated;
234
+ * In the real FPGA image there are always two cores, but the standard
102
235
+ * initial setting for the SCC SYSCON 0x000 register is 0x21, meaning
103
case 2:
236
+ * that the second core is held in reset and halted. Many images built for
104
case 3:
237
+ * the board do not expect the second core to run at startup (especially
238
+ * since on the real FPGA image it is not possible to use LDREX/STREX
239
+ * in RAM between the two cores, so a true SMP setup isn't supported).
240
+ *
241
+ * As QEMU's equivalent of this, we support both -smp 1 and -smp 2,
242
+ * with the default being -smp 1. This seems a more intuitive UI for
243
+ * QEMU users than, for instance, having a machine property to allow
244
+ * the user to set the initial value of the SYSCON 0x000 register.
245
+ */
246
+ mc->default_cpus = 1;
247
+ mc->min_cpus = 1;
248
+ mc->max_cpus = 2;
249
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
250
mc->valid_cpu_types = valid_cpu_types;
251
mmc->raminfo = an536_raminfo;
105
--
252
--
106
2.34.1
253
2.34.1
diff view generated by jsdifflib
1
In the vexpress board code, we allocate a new MemoryRegion at the top
1
This board has a lot of UARTs: there is one UART per CPU in the
2
of vexpress_common_init() but only set it up and use it inside the
2
per-CPU peripheral part of the address map, whose interrupts are
3
"if (map[VE_NORFLASHALIAS] != -1)" conditional, so we leak it if not.
3
connected as per-CPU interrupt lines. Then there are 4 UARTs in the
4
This isn't a very interesting leak as it's a tiny amount of memory
4
normal part of the peripheral space, whose interrupts are shared
5
once at startup, but it's easy to fix.
5
peripheral interrupts.
6
6
7
We could silence Coverity simply by moving the g_new() into the
7
Connect and wire them all up; this involves some OR gates where
8
if() block, but this use of g_new(MemoryRegion, 1) is a legacy from
8
multiple overflow interrupts are wired into one GIC input.
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.
13
14
This machine already has a VexpressMachineState struct that extends
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
9
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
23
Message-id: 20230512170223.3801643-3-peter.maydell@linaro.org
12
Message-id: 20240206132931.38376-11-peter.maydell@linaro.org
24
---
13
---
25
hw/arm/vexpress.c | 40 ++++++++++++++++++++--------------------
14
hw/arm/mps3r.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++
26
1 file changed, 20 insertions(+), 20 deletions(-)
15
1 file changed, 94 insertions(+)
27
16
28
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
17
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
29
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/vexpress.c
19
--- a/hw/arm/mps3r.c
31
+++ b/hw/arm/vexpress.c
20
+++ b/hw/arm/mps3r.c
32
@@ -XXX,XX +XXX,XX @@ struct VexpressMachineClass {
21
@@ -XXX,XX +XXX,XX @@
33
22
#include "qapi/qmp/qlist.h"
34
struct VexpressMachineState {
23
#include "exec/address-spaces.h"
35
MachineState parent;
24
#include "cpu.h"
36
+ MemoryRegion vram;
25
+#include "sysemu/sysemu.h"
37
+ MemoryRegion sram;
26
#include "hw/boards.h"
38
+ MemoryRegion flashalias;
27
+#include "hw/or-irq.h"
39
+ MemoryRegion lowram;
28
#include "hw/qdev-properties.h"
40
+ MemoryRegion a15sram;
29
#include "hw/arm/boot.h"
41
bool secure;
30
#include "hw/arm/bsa.h"
42
bool virt;
31
+#include "hw/char/cmsdk-apb-uart.h"
32
#include "hw/intc/arm_gicv3.h"
33
34
/* Define the layout of RAM and ROM in a board */
35
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
36
37
#define MPS3R_RAM_MAX 9
38
#define MPS3R_CPU_MAX 2
39
+#define MPS3R_UART_MAX 4 /* shared UART count */
40
41
#define PERIPHBASE 0xf0000000
42
#define NUM_SPIS 96
43
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
44
MemoryRegion sysmem_alias[MPS3R_CPU_MAX];
45
MemoryRegion cpu_ram[MPS3R_CPU_MAX];
46
GICv3State gic;
47
+ /* per-CPU UARTs followed by the shared UARTs */
48
+ CMSDKAPBUART uart[MPS3R_CPU_MAX + MPS3R_UART_MAX];
49
+ OrIRQState cpu_uart_oflow[MPS3R_CPU_MAX];
50
+ OrIRQState uart_oflow;
43
};
51
};
44
@@ -XXX,XX +XXX,XX @@ struct VexpressMachineState {
52
45
#define TYPE_VEXPRESS_A15_MACHINE MACHINE_TYPE_NAME("vexpress-a15")
53
#define TYPE_MPS3R_MACHINE "mps3r"
46
OBJECT_DECLARE_TYPE(VexpressMachineState, VexpressMachineClass, VEXPRESS_MACHINE)
54
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
47
55
48
-typedef void DBoardInitFn(const VexpressMachineState *machine,
56
OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
49
+typedef void DBoardInitFn(VexpressMachineState *machine,
57
50
ram_addr_t ram_size,
58
+/*
51
const char *cpu_type,
59
+ * Main clock frequency CLK in Hz (50MHz). In the image there are also
52
qemu_irq *pic);
60
+ * ACLK, MCLK, GPUCLK and PERIPHCLK at the same frequency; for our
53
@@ -XXX,XX +XXX,XX @@ static void init_cpus(MachineState *ms, const char *cpu_type,
61
+ * model we just roll them all into one.
62
+ */
63
+#define CLK_FRQ 50000000
64
+
65
static const RAMInfo an536_raminfo[] = {
66
{
67
.name = "ATCM",
68
@@ -XXX,XX +XXX,XX @@ static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
54
}
69
}
55
}
70
}
56
71
57
-static void a9_daughterboard_init(const VexpressMachineState *vms,
72
+/*
58
+static void a9_daughterboard_init(VexpressMachineState *vms,
73
+ * Create UART uartno, and map it into the MemoryRegion mem at address baseaddr.
59
ram_addr_t ram_size,
74
+ * The qemu_irq arguments are where we connect the various IRQs from the UART.
60
const char *cpu_type,
75
+ */
61
qemu_irq *pic)
76
+static void create_uart(MPS3RMachineState *mms, int uartno, MemoryRegion *mem,
77
+ hwaddr baseaddr, qemu_irq txirq, qemu_irq rxirq,
78
+ qemu_irq txoverirq, qemu_irq rxoverirq,
79
+ qemu_irq combirq)
80
+{
81
+ g_autofree char *s = g_strdup_printf("uart%d", uartno);
82
+ SysBusDevice *sbd;
83
+
84
+ assert(uartno < ARRAY_SIZE(mms->uart));
85
+ object_initialize_child(OBJECT(mms), s, &mms->uart[uartno],
86
+ TYPE_CMSDK_APB_UART);
87
+ qdev_prop_set_uint32(DEVICE(&mms->uart[uartno]), "pclk-frq", CLK_FRQ);
88
+ qdev_prop_set_chr(DEVICE(&mms->uart[uartno]), "chardev", serial_hd(uartno));
89
+ sbd = SYS_BUS_DEVICE(&mms->uart[uartno]);
90
+ sysbus_realize(sbd, &error_fatal);
91
+ memory_region_add_subregion(mem, baseaddr,
92
+ sysbus_mmio_get_region(sbd, 0));
93
+ sysbus_connect_irq(sbd, 0, txirq);
94
+ sysbus_connect_irq(sbd, 1, rxirq);
95
+ sysbus_connect_irq(sbd, 2, txoverirq);
96
+ sysbus_connect_irq(sbd, 3, rxoverirq);
97
+ sysbus_connect_irq(sbd, 4, combirq);
98
+}
99
+
100
static void mps3r_common_init(MachineState *machine)
62
{
101
{
63
MachineState *machine = MACHINE(vms);
102
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
103
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
64
MemoryRegion *sysmem = get_system_memory();
104
MemoryRegion *sysmem = get_system_memory();
65
- MemoryRegion *lowram = g_new(MemoryRegion, 1);
105
+ DeviceState *gicdev;
66
ram_addr_t low_ram_size;
106
67
107
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
68
if (ram_size > 0x40000000) {
108
MemoryRegion *mr = mr_for_raminfo(mms, ri);
69
@@ -XXX,XX +XXX,XX @@ static void a9_daughterboard_init(const VexpressMachineState *vms,
109
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
70
* address space should in theory be remappable to various
71
* things including ROM or RAM; we always map the RAM there.
72
*/
73
- memory_region_init_alias(lowram, NULL, "vexpress.lowmem", machine->ram,
74
- 0, low_ram_size);
75
- memory_region_add_subregion(sysmem, 0x0, lowram);
76
+ memory_region_init_alias(&vms->lowram, NULL, "vexpress.lowmem",
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);
132
}
110
}
133
111
134
dinfo = drive_get(IF_PFLASH, 0, 1);
112
create_gic(mms, sysmem);
135
ve_pflash_cfi01_register(map[VE_NORFLASH1], "vexpress.flash1", dinfo);
113
+ gicdev = DEVICE(&mms->gic);
136
114
+
137
sram_size = 0x2000000;
115
+ /*
138
- memory_region_init_ram(sram, NULL, "vexpress.sram", sram_size,
116
+ * UARTs 0 and 1 are per-CPU; their interrupts are wired to
139
+ memory_region_init_ram(&vms->sram, NULL, "vexpress.sram", sram_size,
117
+ * the relevant CPU's PPI 0..3, aka INTID 16..19
140
&error_fatal);
118
+ */
141
- memory_region_add_subregion(sysmem, map[VE_SRAM], sram);
119
+ for (int i = 0; i < machine->smp.cpus; i++) {
142
+ memory_region_add_subregion(sysmem, map[VE_SRAM], &vms->sram);
120
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
143
121
+ g_autofree char *s = g_strdup_printf("cpu-uart-oflow-orgate%d", i);
144
vram_size = 0x800000;
122
+ DeviceState *orgate;
145
- memory_region_init_ram(vram, NULL, "vexpress.vram", vram_size,
123
+
146
+ memory_region_init_ram(&vms->vram, NULL, "vexpress.vram", vram_size,
124
+ /* The two overflow IRQs from the UART are ORed together into PPI 3 */
147
&error_fatal);
125
+ object_initialize_child(OBJECT(mms), s, &mms->cpu_uart_oflow[i],
148
- memory_region_add_subregion(sysmem, map[VE_VIDEORAM], vram);
126
+ TYPE_OR_IRQ);
149
+ memory_region_add_subregion(sysmem, map[VE_VIDEORAM], &vms->vram);
127
+ orgate = DEVICE(&mms->cpu_uart_oflow[i]);
150
128
+ qdev_prop_set_uint32(orgate, "num-lines", 2);
151
/* 0x4e000000 LAN9118 Ethernet */
129
+ qdev_realize(orgate, NULL, &error_fatal);
152
if (nd_table[0].used) {
130
+ qdev_connect_gpio_out(orgate, 0,
131
+ qdev_get_gpio_in(gicdev, intidbase + 19));
132
+
133
+ create_uart(mms, i, &mms->cpu_sysmem[i], 0xe7c00000,
134
+ qdev_get_gpio_in(gicdev, intidbase + 17), /* tx */
135
+ qdev_get_gpio_in(gicdev, intidbase + 16), /* rx */
136
+ qdev_get_gpio_in(orgate, 0), /* txover */
137
+ qdev_get_gpio_in(orgate, 1), /* rxover */
138
+ qdev_get_gpio_in(gicdev, intidbase + 18) /* combined */);
139
+ }
140
+ /*
141
+ * UARTs 2 to 5 are whole-system; all overflow IRQs are ORed
142
+ * together into IRQ 17
143
+ */
144
+ object_initialize_child(OBJECT(mms), "uart-oflow-orgate",
145
+ &mms->uart_oflow, TYPE_OR_IRQ);
146
+ qdev_prop_set_uint32(DEVICE(&mms->uart_oflow), "num-lines",
147
+ MPS3R_UART_MAX * 2);
148
+ qdev_realize(DEVICE(&mms->uart_oflow), NULL, &error_fatal);
149
+ qdev_connect_gpio_out(DEVICE(&mms->uart_oflow), 0,
150
+ qdev_get_gpio_in(gicdev, 17));
151
+
152
+ for (int i = 0; i < MPS3R_UART_MAX; i++) {
153
+ hwaddr baseaddr = 0xe0205000 + i * 0x1000;
154
+ int rxirq = 5 + i * 2, txirq = 6 + i * 2, combirq = 13 + i;
155
+
156
+ create_uart(mms, i + MPS3R_CPU_MAX, sysmem, baseaddr,
157
+ qdev_get_gpio_in(gicdev, txirq),
158
+ qdev_get_gpio_in(gicdev, rxirq),
159
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2),
160
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2 + 1),
161
+ qdev_get_gpio_in(gicdev, combirq));
162
+ }
163
164
mms->bootinfo.ram_size = machine->ram_size;
165
mms->bootinfo.board_id = -1;
153
--
166
--
154
2.34.1
167
2.34.1
155
168
156
169
diff view generated by jsdifflib
1
Convert the exception-return insns ERET, ERETA and ERETB to
1
Add the GPIO, watchdog, dual-timer and I2C devices to the mps3-an536
2
decodetree. These were the last insns left in the legacy
2
board. These are all simple devices that just need to be created and
3
decoder function disas_uncond_reg_b(), which allows us to
3
wired up.
4
remove it.
5
6
The old decoder explicitly decoded the DRPS instruction,
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.
13
4
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Message-id: 20230512144106.3608981-21-peter.maydell@linaro.org
7
Message-id: 20240206132931.38376-12-peter.maydell@linaro.org
17
---
8
---
18
target/arm/tcg/a64.decode | 8 ++
9
hw/arm/mps3r.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
19
target/arm/tcg/translate-a64.c | 163 +++++++++++----------------------
10
1 file changed, 59 insertions(+)
20
2 files changed, 63 insertions(+), 108 deletions(-)
21
11
22
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
23
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/tcg/a64.decode
14
--- a/hw/arm/mps3r.c
25
+++ b/target/arm/tcg/a64.decode
15
+++ b/hw/arm/mps3r.c
26
@@ -XXX,XX +XXX,XX @@ RETA 1101011 0010 11111 00001 m:1 11111 11111 &reta # RETAA, RETAB
16
@@ -XXX,XX +XXX,XX @@
27
&bra rn rm m
17
#include "sysemu/sysemu.h"
28
BRA 1101011 1000 11111 00001 m:1 rn:5 rm:5 &bra # BRAA, BRAB
18
#include "hw/boards.h"
29
BLRA 1101011 1001 11111 00001 m:1 rn:5 rm:5 &bra # BLRAA, BLRAB
19
#include "hw/or-irq.h"
20
+#include "hw/qdev-clock.h"
21
#include "hw/qdev-properties.h"
22
#include "hw/arm/boot.h"
23
#include "hw/arm/bsa.h"
24
#include "hw/char/cmsdk-apb-uart.h"
25
+#include "hw/i2c/arm_sbcon_i2c.h"
26
#include "hw/intc/arm_gicv3.h"
27
+#include "hw/misc/unimp.h"
28
+#include "hw/timer/cmsdk-apb-dualtimer.h"
29
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
30
31
/* Define the layout of RAM and ROM in a board */
32
typedef struct RAMInfo {
33
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
34
CMSDKAPBUART uart[MPS3R_CPU_MAX + MPS3R_UART_MAX];
35
OrIRQState cpu_uart_oflow[MPS3R_CPU_MAX];
36
OrIRQState uart_oflow;
37
+ CMSDKAPBWatchdog watchdog;
38
+ CMSDKAPBDualTimer dualtimer;
39
+ ArmSbconI2CState i2c[5];
40
+ Clock *clk;
41
};
42
43
#define TYPE_MPS3R_MACHINE "mps3r"
44
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
45
MemoryRegion *sysmem = get_system_memory();
46
DeviceState *gicdev;
47
48
+ mms->clk = clock_new(OBJECT(machine), "CLK");
49
+ clock_set_hz(mms->clk, CLK_FRQ);
30
+
50
+
31
+ERET 1101011 0100 11111 000000 11111 00000
51
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
32
+ERETA 1101011 0100 11111 00001 m:1 11111 11111 &reta # ERETAA, ERETAB
52
MemoryRegion *mr = mr_for_raminfo(mms, ri);
33
+
53
memory_region_add_subregion(sysmem, ri->base, mr);
34
+# We don't need to decode DRPS because it always UNDEFs except when
54
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
35
+# the processor is in halting debug state (which we don't implement).
55
qdev_get_gpio_in(gicdev, combirq));
36
+# The pattern is listed here as documentation.
56
}
37
+# DRPS 1101011 0101 11111 000000 11111 00000
57
38
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
58
+ for (int i = 0; i < 4; i++) {
39
index XXXXXXX..XXXXXXX 100644
59
+ /* CMSDK GPIO controllers */
40
--- a/target/arm/tcg/translate-a64.c
60
+ g_autofree char *s = g_strdup_printf("gpio%d", i);
41
+++ b/target/arm/tcg/translate-a64.c
61
+ create_unimplemented_device(s, 0xe0000000 + i * 0x1000, 0x1000);
42
@@ -XXX,XX +XXX,XX @@ static bool trans_BLRA(DisasContext *s, arg_bra *a)
43
return true;
44
}
45
46
+static bool trans_ERET(DisasContext *s, arg_ERET *a)
47
+{
48
+ TCGv_i64 dst;
49
+
50
+ if (s->current_el == 0) {
51
+ return false;
52
+ }
53
+ if (s->fgt_eret) {
54
+ gen_exception_insn_el(s, 0, EXCP_UDEF, 0, 2);
55
+ return true;
56
+ }
57
+ dst = tcg_temp_new_i64();
58
+ tcg_gen_ld_i64(dst, cpu_env,
59
+ offsetof(CPUARMState, elr_el[s->current_el]));
60
+
61
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
62
+ gen_io_start();
63
+ }
62
+ }
64
+
63
+
65
+ gen_helper_exception_return(cpu_env, dst);
64
+ object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
66
+ /* Must exit loop to check un-masked IRQs */
65
+ TYPE_CMSDK_APB_WATCHDOG);
67
+ s->base.is_jmp = DISAS_EXIT;
66
+ qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->clk);
68
+ return true;
67
+ sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
69
+}
68
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
69
+ qdev_get_gpio_in(gicdev, 0));
70
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->watchdog), 0, 0xe0100000);
70
+
71
+
71
+static bool trans_ERETA(DisasContext *s, arg_reta *a)
72
+ object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
72
+{
73
+ TYPE_CMSDK_APB_DUALTIMER);
73
+ TCGv_i64 dst;
74
+ qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->clk);
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
76
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
77
+ qdev_get_gpio_in(gicdev, 3));
78
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 1,
79
+ qdev_get_gpio_in(gicdev, 1));
80
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 2,
81
+ qdev_get_gpio_in(gicdev, 2));
82
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0xe0101000);
74
+
83
+
75
+ if (!dc_isar_feature(aa64_pauth, s)) {
84
+ for (int i = 0; i < ARRAY_SIZE(mms->i2c); i++) {
76
+ return false;
85
+ static const hwaddr i2cbase[] = {0xe0102000, /* Touch */
77
+ }
86
+ 0xe0103000, /* Audio */
78
+ if (s->current_el == 0) {
87
+ 0xe0107000, /* Shield0 */
79
+ return false;
88
+ 0xe0108000, /* Shield1 */
80
+ }
89
+ 0xe0109000}; /* DDR4 EEPROM */
81
+ /* The FGT trap takes precedence over an auth trap. */
90
+ g_autofree char *s = g_strdup_printf("i2c%d", i);
82
+ if (s->fgt_eret) {
83
+ gen_exception_insn_el(s, 0, EXCP_UDEF, a->m ? 3 : 2, 2);
84
+ return true;
85
+ }
86
+ dst = tcg_temp_new_i64();
87
+ tcg_gen_ld_i64(dst, cpu_env,
88
+ offsetof(CPUARMState, elr_el[s->current_el]));
89
+
91
+
90
+ dst = auth_branch_target(s, dst, cpu_X[31], !a->m);
92
+ object_initialize_child(OBJECT(mms), s, &mms->i2c[i],
91
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
93
+ TYPE_ARM_SBCON_I2C);
92
+ gen_io_start();
94
+ sysbus_realize(SYS_BUS_DEVICE(&mms->i2c[i]), &error_fatal);
95
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->i2c[i]), 0, i2cbase[i]);
96
+ if (i != 2 && i != 3) {
97
+ /*
98
+ * internal-only bus: mark it full to avoid user-created
99
+ * i2c devices being plugged into it.
100
+ */
101
+ qbus_mark_full(qdev_get_child_bus(DEVICE(&mms->i2c[i]), "i2c"));
102
+ }
93
+ }
103
+ }
94
+
104
+
95
+ gen_helper_exception_return(cpu_env, dst);
105
mms->bootinfo.ram_size = machine->ram_size;
96
+ /* Must exit loop to check un-masked IRQs */
106
mms->bootinfo.board_id = -1;
97
+ s->base.is_jmp = DISAS_EXIT;
107
mms->bootinfo.loader_start = mmc->loader_start;
98
+ return true;
99
+}
100
+
101
/* HINT instruction group, including various allocated HINTs */
102
static void handle_hint(DisasContext *s, uint32_t insn,
103
unsigned int op1, unsigned int op2, unsigned int crm)
104
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
105
}
106
}
107
108
-/* Unconditional branch (register)
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)
215
{
216
@@ -XXX,XX +XXX,XX @@ static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
217
disas_exc(s, insn);
218
}
219
break;
220
- case 0x6b: /* Unconditional branch (register) */
221
- disas_uncond_b_reg(s, insn);
222
- break;
223
default:
224
unallocated_encoding(s);
225
break;
226
--
108
--
227
2.34.1
109
2.34.1
110
111
diff view generated by jsdifflib
1
Convert the EXTR instruction to decodetree (this is the
1
Add the remaining devices (or unimplemented-device stubs) for
2
only one in the 'Extract" class). This is the last of
2
this board: SPI controllers, SCC, FPGAIO, I2S, RTC, the
3
the dp-immediate insns in the legacy decoder, so we
3
QSPI write-config block, and ethernet.
4
can now remove disas_data_proc_imm().
5
4
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20230512144106.3608981-13-peter.maydell@linaro.org
7
Message-id: 20240206132931.38376-13-peter.maydell@linaro.org
9
---
8
---
10
target/arm/tcg/a64.decode | 7 +++
9
hw/arm/mps3r.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++
11
target/arm/tcg/translate-a64.c | 94 +++++++++++-----------------------
10
1 file changed, 74 insertions(+)
12
2 files changed, 36 insertions(+), 65 deletions(-)
13
11
14
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/tcg/a64.decode
14
--- a/hw/arm/mps3r.c
17
+++ b/target/arm/tcg/a64.decode
15
+++ b/hw/arm/mps3r.c
18
@@ -XXX,XX +XXX,XX @@ BFM . 01 100110 . ...... ...... ..... ..... @bitfield_64
16
@@ -XXX,XX +XXX,XX @@
19
BFM . 01 100110 . ...... ...... ..... ..... @bitfield_32
17
#include "hw/char/cmsdk-apb-uart.h"
20
UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_64
18
#include "hw/i2c/arm_sbcon_i2c.h"
21
UBFM . 10 100110 . ...... ...... ..... ..... @bitfield_32
19
#include "hw/intc/arm_gicv3.h"
20
+#include "hw/misc/mps2-scc.h"
21
+#include "hw/misc/mps2-fpgaio.h"
22
#include "hw/misc/unimp.h"
23
+#include "hw/net/lan9118.h"
24
+#include "hw/rtc/pl031.h"
25
+#include "hw/ssi/pl022.h"
26
#include "hw/timer/cmsdk-apb-dualtimer.h"
27
#include "hw/watchdog/cmsdk-apb-watchdog.h"
28
29
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
30
CMSDKAPBWatchdog watchdog;
31
CMSDKAPBDualTimer dualtimer;
32
ArmSbconI2CState i2c[5];
33
+ PL022State spi[3];
34
+ MPS2SCC scc;
35
+ MPS2FPGAIO fpgaio;
36
+ UnimplementedDeviceState i2s_audio;
37
+ PL031State rtc;
38
Clock *clk;
39
};
40
41
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an536_raminfo[] = {
42
}
43
};
44
45
+static const int an536_oscclk[] = {
46
+ 24000000, /* 24MHz reference for RTC and timers */
47
+ 50000000, /* 50MHz ACLK */
48
+ 50000000, /* 50MHz MCLK */
49
+ 50000000, /* 50MHz GPUCLK */
50
+ 24576000, /* 24.576MHz AUDCLK */
51
+ 23750000, /* 23.75MHz HDLCDCLK */
52
+ 100000000, /* 100MHz DDR4_REF_CLK */
53
+};
22
+
54
+
23
+# Extract
55
static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
24
+
56
const RAMInfo *raminfo)
25
+&extract rd rn rm imm sf
26
+
27
+EXTR 1 00 100111 1 0 rm:5 imm:6 rn:5 rd:5 &extract sf=1
28
+EXTR 0 00 100111 0 0 rm:5 0 imm:5 rn:5 rd:5 &extract sf=0
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
{
57
{
46
- unsigned int sf, n, rm, imm, rn, rd, bitsize, op21, op0;
58
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
47
+ TCGv_i64 tcg_rd, tcg_rm, tcg_rn;
59
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
48
60
MemoryRegion *sysmem = get_system_memory();
49
- sf = extract32(insn, 31, 1);
61
DeviceState *gicdev;
50
- n = extract32(insn, 22, 1);
62
+ QList *oscclk;
51
- rm = extract32(insn, 16, 5);
63
52
- imm = extract32(insn, 10, 6);
64
mms->clk = clock_new(OBJECT(machine), "CLK");
53
- rn = extract32(insn, 5, 5);
65
clock_set_hz(mms->clk, CLK_FRQ);
54
- rd = extract32(insn, 0, 5);
66
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
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
}
67
}
122
}
68
}
123
-}
69
124
-
70
+ for (int i = 0; i < ARRAY_SIZE(mms->spi); i++) {
125
-/* Data processing - immediate */
71
+ g_autofree char *s = g_strdup_printf("spi%d", i);
126
-static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
72
+ hwaddr baseaddr = 0xe0104000 + i * 0x1000;
127
-{
73
+
128
- switch (extract32(insn, 23, 6)) {
74
+ object_initialize_child(OBJECT(mms), s, &mms->spi[i], TYPE_PL022);
129
- case 0x27: /* Extract */
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->spi[i]), &error_fatal);
130
- disas_extract(s, insn);
76
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->spi[i]), 0, baseaddr);
131
- break;
77
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->spi[i]), 0,
132
- default:
78
+ qdev_get_gpio_in(gicdev, 22 + i));
133
- unallocated_encoding(s);
79
+ }
134
- break;
80
+
135
- }
81
+ object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
136
+ return true;
82
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg0", 0);
137
}
83
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg4", 0x2);
138
84
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-aid", 0x00200008);
139
/* Shift a TCGv src by TCGv shift_amount, put result in dst.
85
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-id", 0x41055360);
140
@@ -XXX,XX +XXX,XX @@ static bool btype_destination_ok(uint32_t insn, bool bt, int btype)
86
+ oscclk = qlist_new();
141
static void disas_a64_legacy(DisasContext *s, uint32_t insn)
87
+ for (int i = 0; i < ARRAY_SIZE(an536_oscclk); i++) {
142
{
88
+ qlist_append_int(oscclk, an536_oscclk[i]);
143
switch (extract32(insn, 25, 4)) {
89
+ }
144
- case 0x8: case 0x9: /* Data processing - immediate */
90
+ qdev_prop_set_array(DEVICE(&mms->scc), "oscclk", oscclk);
145
- disas_data_proc_imm(s, insn);
91
+ sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
146
- break;
92
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->scc), 0, 0xe0200000);
147
case 0xa: case 0xb: /* Branch, exception generation and system insns */
93
+
148
disas_b_exc_sys(s, insn);
94
+ create_unimplemented_device("i2s-audio", 0xe0201000, 0x1000);
149
break;
95
+
96
+ object_initialize_child(OBJECT(mms), "fpgaio", &mms->fpgaio,
97
+ TYPE_MPS2_FPGAIO);
98
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", an536_oscclk[1]);
99
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "num-leds", 10);
100
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-switches", true);
101
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-dbgctrl", false);
102
+ sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
103
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0xe0202000);
104
+
105
+ create_unimplemented_device("clcd", 0xe0209000, 0x1000);
106
+
107
+ object_initialize_child(OBJECT(mms), "rtc", &mms->rtc, TYPE_PL031);
108
+ sysbus_realize(SYS_BUS_DEVICE(&mms->rtc), &error_fatal);
109
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->rtc), 0, 0xe020a000);
110
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->rtc), 0,
111
+ qdev_get_gpio_in(gicdev, 4));
112
+
113
+ /*
114
+ * In hardware this is a LAN9220; the LAN9118 is software compatible
115
+ * except that it doesn't support the checksum-offload feature.
116
+ */
117
+ lan9118_init(0xe0300000,
118
+ qdev_get_gpio_in(gicdev, 18));
119
+
120
+ create_unimplemented_device("usb", 0xe0301000, 0x1000);
121
+ create_unimplemented_device("qspi-write-config", 0xe0600000, 0x1000);
122
+
123
mms->bootinfo.ram_size = machine->ram_size;
124
mms->bootinfo.board_id = -1;
125
mms->bootinfo.loader_start = mmc->loader_start;
150
--
126
--
151
2.34.1
127
2.34.1
128
129
diff view generated by jsdifflib
New patch
1
Add documentation for the mps3-an536 board type.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 20240206132931.38376-14-peter.maydell@linaro.org
6
---
7
docs/system/arm/mps2.rst | 37 ++++++++++++++++++++++++++++++++++---
8
1 file changed, 34 insertions(+), 3 deletions(-)
9
10
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
11
index XXXXXXX..XXXXXXX 100644
12
--- a/docs/system/arm/mps2.rst
13
+++ b/docs/system/arm/mps2.rst
14
@@ -XXX,XX +XXX,XX @@
15
-Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
16
-=========================================================================================================================================================
17
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an536``, ``mps3-an547``)
18
+=========================================================================================================================================================================
19
20
-These board models all use Arm M-profile CPUs.
21
+These board models use Arm M-profile or R-profile CPUs.
22
23
The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
24
bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
25
@@ -XXX,XX +XXX,XX @@ FPGA image.
26
27
QEMU models the following FPGA images:
28
29
+FPGA images using M-profile CPUs:
30
+
31
``mps2-an385``
32
Cortex-M3 as documented in Arm Application Note AN385
33
``mps2-an386``
34
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
35
``mps3-an547``
36
Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
37
38
+FPGA images using R-profile CPUs:
39
+
40
+``mps3-an536``
41
+ Dual Cortex-R52 on an MPS3, as documented in Arm Application Note AN536
42
+
43
Differences between QEMU and real hardware:
44
45
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
46
@@ -XXX,XX +XXX,XX @@ Differences between QEMU and real hardware:
47
flash, but only as simple ROM, so attempting to rewrite the flash
48
from the guest will fail
49
- QEMU does not model the USB controller in MPS3 boards
50
+- AN536 does not support runtime control of CPU reset and halt via
51
+ the SCC CFG_REG0 register.
52
+- AN536 does not support enabling or disabling the flash and ATCM
53
+ interfaces via the SCC CFG_REG1 register.
54
+- AN536 does not support setting of the initial vector table
55
+ base address via the SCC CFG_REG6 and CFG_REG7 register config,
56
+ and does not provide a mechanism for specifying these values at
57
+ startup, so all guest images must be built to start from TCM
58
+ (i.e. to expect the interrupt vector base at 0 from reset).
59
+- AN536 defaults to only creating a single CPU; this is the equivalent
60
+ of the way the real FPGA image usually runs with the second Cortex-R52
61
+ held in halt via the initial SCC CFG_REG0 register setting. You can
62
+ create the second CPU with ``-smp 2``; both CPUs will then start
63
+ execution immediately on startup.
64
+
65
+Note that for the AN536 the first UART is accessible only by
66
+CPU0, and the second UART is accessible only by CPU1. The
67
+first UART accessible shared between both CPUs is the third
68
+UART. Guest software might therefore be built to use either
69
+the first UART or the third UART; if you don't see any output
70
+from the UART you are looking at, try one of the others.
71
+(Even if the AN536 machine is started with a single CPU and so
72
+no "CPU1-only UART", the UART numbering remains the same,
73
+with the third UART being the first of the shared ones.)
74
75
Machine-specific options
76
""""""""""""""""""""""""
77
--
78
2.34.1
79
80
diff view generated by jsdifflib