1
First arm pullreq of 4.2...
1
The following changes since commit 5767815218efd3cbfd409505ed824d5f356044ae:
2
2
3
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)
4
-- PMM
5
6
The following changes since commit 27608c7c66bd923eb5e5faab80e795408cbe2b51:
7
8
Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20190814a' into staging (2019-08-16 12:00:18 +0100)
9
4
10
are available in the Git repository at:
5
are available in the Git repository at:
11
6
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190816
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240215
13
8
14
for you to fetch changes up to 664b7e3b97d6376f3329986c465b3782458b0f8b:
9
for you to fetch changes up to f780e63fe731b058fe52d43653600d8729a1b5f2:
15
10
16
target/arm: Use tcg_gen_extrh_i64_i32 to extract the high word (2019-08-16 14:02:53 +0100)
11
docs: Add documentation for the mps3-an536 board (2024-02-15 14:32:39 +0000)
17
12
18
----------------------------------------------------------------
13
----------------------------------------------------------------
19
target-arm queue:
14
target-arm queue:
20
* target/arm: generate a custom MIDR for -cpu max
15
* hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
21
* hw/misc/zynq_slcr: refactor to use standard register definition
16
* linux-user/aarch64: Choose SYNC as the preferred MTE mode
22
* Set ENET_BD_BDU in I.MX FEC controller
17
* Fix some errors in SVE/SME handling of MTE tags
23
* target/arm: Fix routing of singlestep exceptions
18
* hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
24
* refactor a32/t32 decoder handling of PC
19
* hw/block/tc58128: Don't emit deprecation warning under qtest
25
* minor optimisations/cleanups of some a32/t32 codegen
20
* tests/qtest: Fix handling of npcm7xx and GMAC tests
26
* target/arm/cpu64: Ensure kvm really supports aarch64=off
21
* hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
27
* target/arm/cpu: Ensure we can use the pmu with kvm
22
* tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
28
* target/arm: Minor cleanups preparatory to KVM SVE support
23
* Don't assert on vmload/vmsave of M-profile CPUs
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)
29
30
30
----------------------------------------------------------------
31
----------------------------------------------------------------
31
Aaron Hill (1):
32
Luc Michel (1):
32
Set ENET_BD_BDU in I.MX FEC controller
33
hw/arm/smmuv3: add support for stage 1 access fault
33
34
34
Alex Bennée (1):
35
Nabih Estefan (1):
35
target/arm: generate a custom MIDR for -cpu max
36
tests/qtest: Fix GMAC test to run on a machine in upstream QEMU
36
37
37
Andrew Jones (6):
38
Peter Maydell (22):
38
target/arm/cpu64: Ensure kvm really supports aarch64=off
39
hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
39
target/arm/cpu: Ensure we can use the pmu with kvm
40
hw/block/tc58128: Don't emit deprecation warning under qtest
40
target/arm/helper: zcr: Add build bug next to value range assumption
41
tests/qtest/meson.build: Don't include qtests_npcm7xx in qtests_aarch64
41
target/arm/cpu: Use div-round-up to determine predicate register array size
42
tests/qtest/bios-tables-test: Allow changes to virt GTDT
42
target/arm/kvm64: Fix error returns
43
hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
43
target/arm/kvm64: Move the get/put of fpsimd registers out
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
Damien Hedde (1):
62
Philippe Mathieu-Daudé (5):
46
hw/misc/zynq_slcr: use standard register definition
63
hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
64
hw/arm/stellaris: Convert ADC controller to Resettable interface
65
hw/arm/stellaris: Convert I2C controller to Resettable interface
66
hw/arm/stellaris: Add missing QOM 'machine' parent
67
hw/arm/stellaris: Add missing QOM 'SoC' parent
47
68
48
Peter Maydell (2):
69
Richard Henderson (6):
49
target/arm: Factor out 'generate singlestep exception' function
70
linux-user/aarch64: Choose SYNC as the preferred MTE mode
50
target/arm: Fix routing of singlestep exceptions
71
target/arm: Fix nregs computation in do_{ld,st}_zpa
72
target/arm: Adjust and validate mtedesc sizem1
73
target/arm: Split out make_svemte_desc
74
target/arm: Handle mte in do_ldrq, do_ldro
75
target/arm: Fix SVE/SME gross MTE suppression checks
51
76
52
Richard Henderson (18):
77
MAINTAINERS | 3 +-
53
target/arm: Pass in pc to thumb_insn_is_16bit
78
docs/system/arm/mps2.rst | 37 +-
54
target/arm: Introduce pc_curr
79
configs/devices/arm-softmmu/default.mak | 1 +
55
target/arm: Introduce read_pc
80
hw/arm/smmuv3-internal.h | 1 +
56
target/arm: Introduce add_reg_for_lit
81
include/hw/arm/smmu-common.h | 1 +
57
target/arm: Remove redundant s->pc & ~1
82
include/hw/arm/virt.h | 2 +
58
target/arm: Replace s->pc with s->base.pc_next
83
include/hw/misc/mps2-scc.h | 1 +
59
target/arm: Replace offset with pc in gen_exception_insn
84
linux-user/aarch64/target_prctl.h | 29 +-
60
target/arm: Replace offset with pc in gen_exception_internal_insn
85
target/arm/internals.h | 2 +-
61
target/arm: Remove offset argument to gen_exception_bkpt_insn
86
target/arm/tcg/translate-a64.h | 2 +
62
target/arm: Use unallocated_encoding for aarch32
87
hw/arm/mps3r.c | 640 ++++++++++++++++++++++++++++++++
63
target/arm: Remove helper_double_saturate
88
hw/arm/npcm7xx.c | 1 +
64
target/arm: Use tcg_gen_extract_i32 for shifter_out_im
89
hw/arm/smmu-common.c | 11 +
65
target/arm: Use tcg_gen_deposit_i32 for PKHBT, PKHTB
90
hw/arm/smmuv3.c | 1 +
66
target/arm: Remove redundant shift tests
91
hw/arm/stellaris.c | 47 ++-
67
target/arm: Use ror32 instead of open-coding the operation
92
hw/arm/virt-acpi-build.c | 20 +-
68
target/arm: Use tcg_gen_rotri_i32 for gen_swap_half
93
hw/arm/virt.c | 60 ++-
69
target/arm: Simplify SMMLA, SMMLAR, SMMLS, SMMLSR
94
hw/arm/xilinx_zynq.c | 2 +
70
target/arm: Use tcg_gen_extrh_i64_i32 to extract the high word
95
hw/block/tc58128.c | 4 +-
96
hw/misc/mps2-scc.c | 138 ++++++-
97
hw/pci-host/raven.c | 1 +
98
target/arm/helper.c | 14 +-
99
target/arm/tcg/cpu32.c | 109 ++++++
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
71
115
72
target/arm/cpu.h | 13 +-
73
target/arm/helper.h | 1 -
74
target/arm/kvm_arm.h | 28 ++
75
target/arm/translate-a64.h | 4 +-
76
target/arm/translate.h | 39 ++-
77
hw/misc/zynq_slcr.c | 450 ++++++++++++++++----------------
78
hw/net/imx_fec.c | 4 +
79
target/arm/cpu.c | 30 ++-
80
target/arm/cpu64.c | 31 ++-
81
target/arm/helper.c | 7 +
82
target/arm/kvm.c | 7 +
83
target/arm/kvm64.c | 161 +++++++-----
84
target/arm/op_helper.c | 15 --
85
target/arm/translate-a64.c | 130 ++++------
86
target/arm/translate-vfp.inc.c | 45 +---
87
target/arm/translate.c | 572 +++++++++++++++++------------------------
88
16 files changed, 771 insertions(+), 766 deletions(-)
89
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
All of the inputs to these instructions are 32-bits. Rather than
3
Similarly to commits dadbb58f59..5ae79fe825 for other ARM boards,
4
extend each input to 64-bits and then extract the high 32-bits of
4
connect FIQ output of the GIC CPU interfaces to the CPU.
5
the output, use tcg_gen_muls2_i32 and other 32-bit generator functions.
6
5
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20190808202616.13782-7-richard.henderson@linaro.org
7
Message-id: 20240130152548.17855-1-philmd@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
target/arm/translate.c | 72 +++++++++++++++---------------------------
11
hw/arm/xilinx_zynq.c | 2 ++
13
1 file changed, 26 insertions(+), 46 deletions(-)
12
1 file changed, 2 insertions(+)
14
13
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
16
--- a/hw/arm/xilinx_zynq.c
18
+++ b/target/arm/translate.c
17
+++ b/hw/arm/xilinx_zynq.c
19
@@ -XXX,XX +XXX,XX @@ static void gen_revsh(TCGv_i32 var)
18
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
20
tcg_gen_ext16s_i32(var, var);
19
sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
21
}
20
sysbus_connect_irq(busdev, 0,
22
21
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
23
-/* Return (b << 32) + a. Mark inputs as dead */
22
+ sysbus_connect_irq(busdev, 1,
24
-static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
23
+ qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ));
25
-{
24
26
- TCGv_i64 tmp64 = tcg_temp_new_i64();
25
for (n = 0; n < 64; n++) {
27
-
26
pic[n] = qdev_get_gpio_in(dev, n);
28
- tcg_gen_extu_i32_i64(tmp64, b);
29
- tcg_temp_free_i32(b);
30
- tcg_gen_shli_i64(tmp64, tmp64, 32);
31
- tcg_gen_add_i64(a, tmp64, a);
32
-
33
- tcg_temp_free_i64(tmp64);
34
- return a;
35
-}
36
-
37
-/* Return (b << 32) - a. Mark inputs as dead. */
38
-static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
39
-{
40
- TCGv_i64 tmp64 = tcg_temp_new_i64();
41
-
42
- tcg_gen_extu_i32_i64(tmp64, b);
43
- tcg_temp_free_i32(b);
44
- tcg_gen_shli_i64(tmp64, tmp64, 32);
45
- tcg_gen_sub_i64(a, tmp64, a);
46
-
47
- tcg_temp_free_i64(tmp64);
48
- return a;
49
-}
50
-
51
/* 32x32->64 multiply. Marks inputs as dead. */
52
static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
53
{
54
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
55
(SMMUL, SMMLA, SMMLS) */
56
tmp = load_reg(s, rm);
57
tmp2 = load_reg(s, rs);
58
- tmp64 = gen_muls_i64_i32(tmp, tmp2);
59
+ tcg_gen_muls2_i32(tmp2, tmp, tmp, tmp2);
60
61
if (rd != 15) {
62
- tmp = load_reg(s, rd);
63
+ tmp3 = load_reg(s, rd);
64
if (insn & (1 << 6)) {
65
- tmp64 = gen_subq_msw(tmp64, tmp);
66
+ tcg_gen_sub_i32(tmp, tmp, tmp3);
67
} else {
68
- tmp64 = gen_addq_msw(tmp64, tmp);
69
+ tcg_gen_add_i32(tmp, tmp, tmp3);
70
}
71
+ tcg_temp_free_i32(tmp3);
72
}
73
if (insn & (1 << 5)) {
74
- tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
75
+ /*
76
+ * Adding 0x80000000 to the 64-bit quantity
77
+ * means that we have carry in to the high
78
+ * word when the low word has the high bit set.
79
+ */
80
+ tcg_gen_shri_i32(tmp2, tmp2, 31);
81
+ tcg_gen_add_i32(tmp, tmp, tmp2);
82
}
83
- tcg_gen_shri_i64(tmp64, tmp64, 32);
84
- tmp = tcg_temp_new_i32();
85
- tcg_gen_extrl_i64_i32(tmp, tmp64);
86
- tcg_temp_free_i64(tmp64);
87
+ tcg_temp_free_i32(tmp2);
88
store_reg(s, rn, tmp);
89
break;
90
case 0:
91
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
92
}
93
break;
94
case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
95
- tmp64 = gen_muls_i64_i32(tmp, tmp2);
96
+ tcg_gen_muls2_i32(tmp2, tmp, tmp, tmp2);
97
if (rs != 15) {
98
- tmp = load_reg(s, rs);
99
+ tmp3 = load_reg(s, rs);
100
if (insn & (1 << 20)) {
101
- tmp64 = gen_addq_msw(tmp64, tmp);
102
+ tcg_gen_add_i32(tmp, tmp, tmp3);
103
} else {
104
- tmp64 = gen_subq_msw(tmp64, tmp);
105
+ tcg_gen_sub_i32(tmp, tmp, tmp3);
106
}
107
+ tcg_temp_free_i32(tmp3);
108
}
109
if (insn & (1 << 4)) {
110
- tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
111
+ /*
112
+ * Adding 0x80000000 to the 64-bit quantity
113
+ * means that we have carry in to the high
114
+ * word when the low word has the high bit set.
115
+ */
116
+ tcg_gen_shri_i32(tmp2, tmp2, 31);
117
+ tcg_gen_add_i32(tmp, tmp, tmp2);
118
}
119
- tcg_gen_shri_i64(tmp64, tmp64, 32);
120
- tmp = tcg_temp_new_i32();
121
- tcg_gen_extrl_i64_i32(tmp, tmp64);
122
- tcg_temp_free_i64(tmp64);
123
+ tcg_temp_free_i32(tmp2);
124
break;
125
case 7: /* Unsigned sum of absolute differences. */
126
gen_helper_usad8(tmp, tmp, tmp2);
127
--
27
--
128
2.20.1
28
2.34.1
129
29
130
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
Rotate is the more compact and obvious way to swap 16-bit
3
The API does not generate an error for setting ASYNC | SYNC; that merely
4
elements of a 32-bit word.
4
constrains the selection vs the per-cpu default. For qemu linux-user,
5
choose SYNC as the default.
5
6
7
Cc: qemu-stable@nongnu.org
8
Reported-by: Gustavo Romero <gustavo.romero@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190808202616.13782-6-richard.henderson@linaro.org
10
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20240207025210.8837-2-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
target/arm/translate.c | 6 +-----
14
linux-user/aarch64/target_prctl.h | 29 +++++++++++++++++------------
12
1 file changed, 1 insertion(+), 5 deletions(-)
15
1 file changed, 17 insertions(+), 12 deletions(-)
13
16
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
19
--- a/linux-user/aarch64/target_prctl.h
17
+++ b/target/arm/translate.c
20
+++ b/linux-user/aarch64/target_prctl.h
18
@@ -XXX,XX +XXX,XX @@ static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
21
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
19
/* Swap low and high halfwords. */
22
env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE;
20
static void gen_swap_half(TCGv_i32 var)
23
21
{
24
if (cpu_isar_feature(aa64_mte, cpu)) {
22
- TCGv_i32 tmp = tcg_temp_new_i32();
25
- switch (arg2 & PR_MTE_TCF_MASK) {
23
- tcg_gen_shri_i32(tmp, var, 16);
26
- case PR_MTE_TCF_NONE:
24
- tcg_gen_shli_i32(var, var, 16);
27
- case PR_MTE_TCF_SYNC:
25
- tcg_gen_or_i32(var, var, tmp);
28
- case PR_MTE_TCF_ASYNC:
26
- tcg_temp_free_i32(tmp);
29
- break;
27
+ tcg_gen_rotri_i32(var, var, 16);
30
- default:
28
}
31
- return -EINVAL;
29
32
- }
30
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
33
-
34
/*
35
* Write PR_MTE_TCF to SCTLR_EL1[TCF0].
36
- * Note that the syscall values are consistent with hw.
37
+ *
38
+ * The kernel has a per-cpu configuration for the sysadmin,
39
+ * /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred,
40
+ * which qemu does not implement.
41
+ *
42
+ * Because there is no performance difference between the modes, and
43
+ * because SYNC is most useful for debugging MTE errors, choose SYNC
44
+ * as the preferred mode. With this preference, and the way the API
45
+ * uses only two bits, there is no way for the program to select
46
+ * ASYMM mode.
47
*/
48
- env->cp15.sctlr_el[1] =
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].
31
--
60
--
32
2.20.1
61
2.34.1
33
34
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Extract is a compact combination of shift + and.
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
Message-id: 20190808202616.13782-2-richard.henderson@linaro.org
13
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
14
Message-id: 20240207025210.8837-3-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
17
---
10
target/arm/translate.c | 9 +--------
18
target/arm/tcg/translate-sve.c | 16 ++++++++--------
11
1 file changed, 1 insertion(+), 8 deletions(-)
19
1 file changed, 8 insertions(+), 8 deletions(-)
12
20
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
21
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
14
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
23
--- a/target/arm/tcg/translate-sve.c
16
+++ b/target/arm/translate.c
24
+++ b/target/arm/tcg/translate-sve.c
17
@@ -XXX,XX +XXX,XX @@ static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
25
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
18
26
TCGv_ptr t_pg;
19
static void shifter_out_im(TCGv_i32 var, int shift)
27
int desc = 0;
20
{
28
21
- if (shift == 0) {
29
- /*
22
- tcg_gen_andi_i32(cpu_CF, var, 1);
30
- * For e.g. LD4, there are not enough arguments to pass all 4
23
- } else {
31
- * registers as pointers, so encode the regno into the data field.
24
- tcg_gen_shri_i32(cpu_CF, var, shift);
32
- * For consistency, do this even for LD1.
25
- if (shift != 31) {
33
- */
26
- tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
34
+ assert(mte_n >= 1 && mte_n <= 4);
27
- }
35
if (s->mte_active[0]) {
28
- }
36
int msz = dtype_msz(dtype);
29
+ tcg_gen_extract_i32(cpu_CF, var, shift, 1);
37
38
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
39
addr = clean_data_tbi(s, addr);
40
}
41
42
+ /*
43
+ * For e.g. LD4, there are not enough arguments to pass all 4
44
+ * registers as pointers, so encode the regno into the data field.
45
+ * For consistency, do this even for LD1.
46
+ */
47
desc = simd_desc(vsz, vsz, zt | desc);
48
t_pg = tcg_temp_new_ptr();
49
50
@@ -XXX,XX +XXX,XX @@ static void do_ld_zpa(DisasContext *s, int zt, int pg,
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);
30
}
56
}
31
57
32
/* Shift by immediate. Includes special handling for shift == 0. */
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;
64
} else {
65
/* ST2, ST3, ST4 -- msz == esz, enforced by encoding */
66
assert(msz == esz);
67
fn = fn_multiple[s->mte_active[0]][be][nreg - 1][msz];
68
}
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);
72
}
73
74
static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a)
33
--
75
--
34
2.20.1
76
2.34.1
35
36
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The helper function is more documentary, and also already
3
When we added SVE_MTEDESC_SHIFT, we effectively limited the
4
handles the case of rotate by zero.
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).
5
7
8
Cc: qemu-stable@nongnu.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190808202616.13782-5-richard.henderson@linaro.org
11
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20240207025210.8837-4-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
target/arm/translate.c | 7 ++-----
15
target/arm/internals.h | 2 +-
12
1 file changed, 2 insertions(+), 5 deletions(-)
16
target/arm/tcg/translate-sve.c | 7 ++++---
17
2 files changed, 5 insertions(+), 4 deletions(-)
13
18
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
21
--- a/target/arm/internals.h
17
+++ b/target/arm/translate.c
22
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
23
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, TBI, 4, 2)
19
/* CPSR = immediate */
24
FIELD(MTEDESC, TCMA, 6, 2)
20
val = insn & 0xff;
25
FIELD(MTEDESC, WRITE, 8, 1)
21
shift = ((insn >> 8) & 0xf) * 2;
26
FIELD(MTEDESC, ALIGN, 9, 3)
22
- if (shift)
27
-FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - 12) /* size - 1 */
23
- val = (val >> shift) | (val << (32 - shift));
28
+FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - SVE_MTEDESC_SHIFT - 12) /* size - 1 */
24
+ val = ror32(val, shift);
29
25
i = ((insn & (1 << 22)) != 0);
30
bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
26
if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
31
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
27
i, val)) {
32
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
28
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
33
index XXXXXXX..XXXXXXX 100644
29
/* immediate operand */
34
--- a/target/arm/tcg/translate-sve.c
30
val = insn & 0xff;
35
+++ b/target/arm/tcg/translate-sve.c
31
shift = ((insn >> 8) & 0xf) * 2;
36
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
32
- if (shift) {
37
{
33
- val = (val >> shift) | (val << (32 - shift));
38
unsigned vsz = vec_full_reg_size(s);
34
- }
39
TCGv_ptr t_pg;
35
+ val = ror32(val, shift);
40
+ uint32_t sizem1;
36
tmp2 = tcg_temp_new_i32();
41
int desc = 0;
37
tcg_gen_movi_i32(tmp2, val);
42
38
if (logic_cc && shift) {
43
assert(mte_n >= 1 && mte_n <= 4);
44
+ sizem1 = (mte_n << dtype_msz(dtype)) - 1;
45
+ assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
46
if (s->mte_active[0]) {
47
- int msz = dtype_msz(dtype);
48
-
49
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
50
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
51
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
52
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
53
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (mte_n << msz) - 1);
54
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
55
desc <<= SVE_MTEDESC_SHIFT;
56
} else {
57
addr = clean_data_tbi(s, addr);
39
--
58
--
40
2.20.1
59
2.34.1
41
42
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Separate shift + extract low will result in one extra insn
3
Share code that creates mtedesc and embeds within simd_desc.
4
for hosts like RISC-V, MIPS, and Sparc.
5
4
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190808202616.13782-8-richard.henderson@linaro.org
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20240207025210.8837-5-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/translate.c | 18 ++++++------------
12
target/arm/tcg/translate-a64.h | 2 ++
12
1 file changed, 6 insertions(+), 12 deletions(-)
13
target/arm/tcg/translate-sme.c | 15 +++--------
14
target/arm/tcg/translate-sve.c | 47 ++++++++++++++++++----------------
15
3 files changed, 31 insertions(+), 33 deletions(-)
13
16
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
19
--- a/target/arm/tcg/translate-a64.h
17
+++ b/target/arm/translate.c
20
+++ b/target/arm/tcg/translate-a64.h
18
@@ -XXX,XX +XXX,XX @@ static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
21
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
19
if (insn & ARM_CP_RW_BIT) { /* TMRRC */
22
bool sve_access_check(DisasContext *s);
20
iwmmxt_load_reg(cpu_V0, wrd);
23
bool sme_enabled_check(DisasContext *s);
21
tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
24
bool sme_enabled_check_with_svcr(DisasContext *s, unsigned);
22
- tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
25
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
23
- tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
26
+ uint32_t msz, bool is_write, uint32_t data);
24
+ tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
27
25
} else { /* TMCRR */
28
/* This function corresponds to CheckStreamingSVEEnabled. */
26
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
29
static inline bool sme_sm_enabled_check(DisasContext *s)
27
iwmmxt_store_reg(cpu_V0, wrd);
30
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
28
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
31
index XXXXXXX..XXXXXXX 100644
29
if (insn & ARM_CP_RW_BIT) { /* MRA */
32
--- a/target/arm/tcg/translate-sme.c
30
iwmmxt_load_reg(cpu_V0, acc);
33
+++ b/target/arm/tcg/translate-sme.c
31
tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
34
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
32
- tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
35
33
- tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
36
TCGv_ptr t_za, t_pg;
34
+ tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
37
TCGv_i64 addr;
35
tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
38
- int svl, desc = 0;
36
} else { /* MAR */
39
+ uint32_t desc;
37
tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
40
bool be = s->be_data == MO_BE;
38
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
41
bool mte = s->mte_active[0];
39
gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
42
40
break;
43
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
41
case 2:
44
tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->esz);
42
- tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
45
tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
43
- tcg_gen_extrl_i64_i32(tmp, cpu_V0);
46
44
+ tcg_gen_extrh_i64_i32(tmp, cpu_V0);
47
- if (mte) {
45
break;
48
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
46
default: abort();
49
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
47
}
50
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
48
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
51
- desc = FIELD_DP32(desc, MTEDESC, WRITE, a->st);
49
break;
52
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << a->esz) - 1);
50
case 2:
53
- desc <<= SVE_MTEDESC_SHIFT;
51
tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
54
- } else {
52
- tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
55
+ if (!mte) {
53
- tcg_gen_extrl_i64_i32(tmp, cpu_V0);
56
addr = clean_data_tbi(s, addr);
54
+ tcg_gen_extrh_i64_i32(tmp, cpu_V0);
57
}
55
break;
58
- svl = streaming_vec_reg_size(s);
56
default: abort();
59
- desc = simd_desc(svl, svl, desc);
57
}
60
+
58
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
61
+ desc = make_svemte_desc(s, streaming_vec_reg_size(s), 1, a->esz, a->st, 0);
59
tmp = tcg_temp_new_i32();
62
60
tcg_gen_extrl_i64_i32(tmp, tmp64);
63
fns[a->esz][be][a->v][mte][a->st](tcg_env, t_za, t_pg, addr,
61
store_reg(s, rt, tmp);
64
tcg_constant_i32(desc));
62
- tcg_gen_shri_i64(tmp64, tmp64, 32);
65
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
63
tmp = tcg_temp_new_i32();
66
index XXXXXXX..XXXXXXX 100644
64
- tcg_gen_extrl_i64_i32(tmp, tmp64);
67
--- a/target/arm/tcg/translate-sve.c
65
+ tcg_gen_extrh_i64_i32(tmp, tmp64);
68
+++ b/target/arm/tcg/translate-sve.c
66
tcg_temp_free_i64(tmp64);
69
@@ -XXX,XX +XXX,XX @@ static const uint8_t dtype_esz[16] = {
67
store_reg(s, rt2, tmp);
70
3, 2, 1, 3
68
} else {
71
};
69
@@ -XXX,XX +XXX,XX @@ static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
72
70
tcg_gen_extrl_i64_i32(tmp, val);
73
-static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
71
store_reg(s, rlow, tmp);
74
- int dtype, uint32_t mte_n, bool is_write,
72
tmp = tcg_temp_new_i32();
75
- gen_helper_gvec_mem *fn)
73
- tcg_gen_shri_i64(val, val, 32);
76
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
74
- tcg_gen_extrl_i64_i32(tmp, val);
77
+ uint32_t msz, bool is_write, uint32_t data)
75
+ tcg_gen_extrh_i64_i32(tmp, val);
78
{
76
store_reg(s, rhigh, tmp);
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);
103
+}
104
+
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)
129
{
130
- unsigned vsz = vec_full_reg_size(s);
131
TCGv_ptr t_zm = tcg_temp_new_ptr();
132
TCGv_ptr t_pg = tcg_temp_new_ptr();
133
TCGv_ptr t_zt = tcg_temp_new_ptr();
134
- int desc = 0;
135
-
136
- if (s->mte_active[0]) {
137
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
138
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
139
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
140
- desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
141
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << msz) - 1);
142
- desc <<= SVE_MTEDESC_SHIFT;
143
- }
144
- desc = simd_desc(vsz, vsz, desc | scale);
145
+ uint32_t desc;
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));
150
+
151
+ desc = make_svemte_desc(s, vec_full_reg_size(s), 1, msz, is_write, scale);
152
fn(tcg_env, t_zt, t_pg, t_zm, scalar, tcg_constant_i32(desc));
77
}
153
}
78
154
79
--
155
--
80
2.20.1
156
2.34.1
81
82
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The offset is variable depending on the instruction set.
3
These functions "use the standard load helpers", but
4
Passing in the actual value is clearer in intent.
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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20240207025210.8837-6-richard.henderson@linaro.org
9
Message-id: 20190807045335.1361-9-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
target/arm/translate-a64.c | 8 ++++----
13
target/arm/tcg/translate-sve.c | 15 +++++++++++++--
13
target/arm/translate.c | 8 ++++----
14
1 file changed, 13 insertions(+), 2 deletions(-)
14
2 files changed, 8 insertions(+), 8 deletions(-)
15
15
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.c
18
--- a/target/arm/tcg/translate-sve.c
19
+++ b/target/arm/translate-a64.c
19
+++ b/target/arm/tcg/translate-sve.c
20
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal(int excp)
20
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
21
tcg_temp_free_i32(tcg_excp);
21
unsigned vsz = vec_full_reg_size(s);
22
}
22
TCGv_ptr t_pg;
23
23
int poff;
24
-static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
24
+ uint32_t desc;
25
+static void gen_exception_internal_insn(DisasContext *s, uint64_t pc, int excp)
25
26
{
26
/* Load the first quadword using the normal predicated load helpers. */
27
- gen_a64_set_pc_im(s->base.pc_next - offset);
27
+ if (!s->mte_active[0]) {
28
+ gen_a64_set_pc_im(pc);
28
+ addr = clean_data_tbi(s, addr);
29
gen_exception_internal(excp);
29
+ }
30
s->base.is_jmp = DISAS_NORETURN;
30
+
31
}
31
poff = pred_full_reg_offset(s, pg);
32
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
32
if (vsz > 16) {
33
break;
33
/*
34
}
34
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
35
#endif
35
36
- gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
36
gen_helper_gvec_mem *fn
37
+ gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
37
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
38
} else {
38
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(16, 16, zt)));
39
unsupported_encoding(s, insn);
39
+ desc = make_svemte_desc(s, 16, 1, dtype_msz(dtype), false, zt);
40
}
40
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
41
@@ -XXX,XX +XXX,XX @@ static bool aarch64_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
41
42
/* End the TB early; it likely won't be executed */
42
/* Replicate that first quadword. */
43
dc->base.is_jmp = DISAS_TOO_MANY;
43
if (vsz > 16) {
44
} else {
44
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
45
- gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
45
unsigned vsz_r32;
46
+ gen_exception_internal_insn(dc, dc->base.pc_next, EXCP_DEBUG);
46
TCGv_ptr t_pg;
47
/* The address covered by the breakpoint must be
47
int poff, doff;
48
included in [tb->pc, tb->pc + tb->size) in order
48
+ uint32_t desc;
49
to for it to be properly cleared -- thus we
49
50
diff --git a/target/arm/translate.c b/target/arm/translate.c
50
if (vsz < 32) {
51
index XXXXXXX..XXXXXXX 100644
51
/*
52
--- a/target/arm/translate.c
52
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
53
+++ b/target/arm/translate.c
54
@@ -XXX,XX +XXX,XX @@ static inline void gen_smc(DisasContext *s)
55
s->base.is_jmp = DISAS_SMC;
56
}
57
58
-static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
59
+static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
60
{
61
gen_set_condexec(s);
62
- gen_set_pc_im(s, s->base.pc_next - offset);
63
+ gen_set_pc_im(s, pc);
64
gen_exception_internal(excp);
65
s->base.is_jmp = DISAS_NORETURN;
66
}
67
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
68
s->current_el != 0 &&
69
#endif
70
(imm == (s->thumb ? 0x3c : 0xf000))) {
71
- gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
72
+ gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
73
return;
74
}
53
}
75
54
76
@@ -XXX,XX +XXX,XX @@ static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
55
/* Load the first octaword using the normal predicated load helpers. */
77
/* End the TB early; it's likely not going to be executed */
56
+ if (!s->mte_active[0]) {
78
dc->base.is_jmp = DISAS_TOO_MANY;
57
+ addr = clean_data_tbi(s, addr);
79
} else {
58
+ }
80
- gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
59
81
+ gen_exception_internal_insn(dc, dc->base.pc_next, EXCP_DEBUG);
60
poff = pred_full_reg_offset(s, pg);
82
/* The address covered by the breakpoint must be
61
if (vsz > 32) {
83
included in [tb->pc, tb->pc + tb->size) in order
62
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
84
to for it to be properly cleared -- thus we
63
64
gen_helper_gvec_mem *fn
65
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
66
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(32, 32, zt)));
67
+ desc = make_svemte_desc(s, 32, 1, dtype_msz(dtype), false, zt);
68
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
69
70
/*
71
* Replicate that first octaword.
85
--
72
--
86
2.20.1
73
2.34.1
87
88
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Provide a common routine for the places that require ALIGN(PC, 4)
3
The TBI and TCMA bits are located within mtedesc, not desc.
4
as the base address as opposed to plain PC. The two are always
5
the same for A32, but the difference is meaningful for thumb mode.
6
4
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20240207025210.8837-7-richard.henderson@linaro.org
10
Message-id: 20190807045335.1361-5-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/translate-vfp.inc.c | 38 ++------
12
target/arm/tcg/sme_helper.c | 8 ++++----
14
target/arm/translate.c | 166 +++++++++++++++------------------
13
target/arm/tcg/sve_helper.c | 12 ++++++------
15
2 files changed, 82 insertions(+), 122 deletions(-)
14
2 files changed, 10 insertions(+), 10 deletions(-)
16
15
17
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
16
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate-vfp.inc.c
18
--- a/target/arm/tcg/sme_helper.c
20
+++ b/target/arm/translate-vfp.inc.c
19
+++ b/target/arm/tcg/sme_helper.c
21
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
20
@@ -XXX,XX +XXX,XX @@ void sme_ld1_mte(CPUARMState *env, void *za, uint64_t *vg,
22
offset = -offset;
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;
23
}
29
}
24
30
25
- if (s->thumb && a->rn == 15) {
31
@@ -XXX,XX +XXX,XX @@ void sme_st1_mte(CPUARMState *env, void *za, uint64_t *vg, target_ulong addr,
26
- /* This is actually UNPREDICTABLE */
32
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
27
- addr = tcg_temp_new_i32();
33
28
- tcg_gen_movi_i32(addr, s->pc & ~2);
34
/* Perform gross MTE suppression early. */
29
- } else {
35
- if (!tbi_check(desc, bit55) ||
30
- addr = load_reg(s, a->rn);
36
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
31
- }
37
+ if (!tbi_check(mtedesc, bit55) ||
32
- tcg_gen_addi_i32(addr, addr, offset);
38
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
33
+ /* For thumb, use of PC is UNPREDICTABLE. */
39
mtedesc = 0;
34
+ addr = add_reg_for_lit(s, a->rn, offset);
35
tmp = tcg_temp_new_i32();
36
if (a->l) {
37
gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
39
offset = -offset;
40
}
40
}
41
41
42
- if (s->thumb && a->rn == 15) {
42
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
43
- /* This is actually UNPREDICTABLE */
43
index XXXXXXX..XXXXXXX 100644
44
- addr = tcg_temp_new_i32();
44
--- a/target/arm/tcg/sve_helper.c
45
- tcg_gen_movi_i32(addr, s->pc & ~2);
45
+++ b/target/arm/tcg/sve_helper.c
46
- } else {
46
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
47
- addr = load_reg(s, a->rn);
47
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
48
- }
48
49
- tcg_gen_addi_i32(addr, addr, offset);
49
/* Perform gross MTE suppression early. */
50
+ /* For thumb, use of PC is UNPREDICTABLE. */
50
- if (!tbi_check(desc, bit55) ||
51
+ addr = add_reg_for_lit(s, a->rn, offset);
51
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
52
tmp = tcg_temp_new_i64();
52
+ if (!tbi_check(mtedesc, bit55) ||
53
if (a->l) {
53
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
54
gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
54
mtedesc = 0;
55
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
56
return true;
57
}
55
}
58
56
59
- if (s->thumb && a->rn == 15) {
57
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r_mte(CPUARMState *env, void *vg, target_ulong addr,
60
- /* This is actually UNPREDICTABLE */
58
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
61
- addr = tcg_temp_new_i32();
59
62
- tcg_gen_movi_i32(addr, s->pc & ~2);
60
/* Perform gross MTE suppression early. */
63
- } else {
61
- if (!tbi_check(desc, bit55) ||
64
- addr = load_reg(s, a->rn);
62
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
65
- }
63
+ if (!tbi_check(mtedesc, bit55) ||
66
+ /* For thumb, use of PC is UNPREDICTABLE. */
64
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
67
+ addr = add_reg_for_lit(s, a->rn, 0);
65
mtedesc = 0;
68
if (a->p) {
69
/* pre-decrement */
70
tcg_gen_addi_i32(addr, addr, -(a->imm << 2));
71
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
72
return true;
73
}
66
}
74
67
75
- if (s->thumb && a->rn == 15) {
68
@@ -XXX,XX +XXX,XX @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
76
- /* This is actually UNPREDICTABLE */
69
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
77
- addr = tcg_temp_new_i32();
70
78
- tcg_gen_movi_i32(addr, s->pc & ~2);
71
/* Perform gross MTE suppression early. */
79
- } else {
72
- if (!tbi_check(desc, bit55) ||
80
- addr = load_reg(s, a->rn);
73
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
81
- }
74
+ if (!tbi_check(mtedesc, bit55) ||
82
+ /* For thumb, use of PC is UNPREDICTABLE. */
75
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
83
+ addr = add_reg_for_lit(s, a->rn, 0);
76
mtedesc = 0;
84
if (a->p) {
77
}
85
/* pre-decrement */
86
tcg_gen_addi_i32(addr, addr, -(a->imm << 2));
87
diff --git a/target/arm/translate.c b/target/arm/translate.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/target/arm/translate.c
90
+++ b/target/arm/translate.c
91
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 load_reg(DisasContext *s, int reg)
92
return tmp;
93
}
94
95
+/*
96
+ * Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
97
+ * This is used for load/store for which use of PC implies (literal),
98
+ * or ADD that implies ADR.
99
+ */
100
+static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
101
+{
102
+ TCGv_i32 tmp = tcg_temp_new_i32();
103
+
104
+ if (reg == 15) {
105
+ tcg_gen_movi_i32(tmp, (read_pc(s) & ~3) + ofs);
106
+ } else {
107
+ tcg_gen_addi_i32(tmp, cpu_R[reg], ofs);
108
+ }
109
+ return tmp;
110
+}
111
+
112
/* Set a CPU register. The source must be a temporary and will be
113
marked as dead. */
114
static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
115
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
116
*/
117
bool wback = extract32(insn, 21, 1);
118
119
- if (rn == 15) {
120
- if (insn & (1 << 21)) {
121
- /* UNPREDICTABLE */
122
- goto illegal_op;
123
- }
124
- addr = tcg_temp_new_i32();
125
- tcg_gen_movi_i32(addr, s->pc & ~3);
126
- } else {
127
- addr = load_reg(s, rn);
128
+ if (rn == 15 && (insn & (1 << 21))) {
129
+ /* UNPREDICTABLE */
130
+ goto illegal_op;
131
}
132
+
133
+ addr = add_reg_for_lit(s, rn, 0);
134
offset = (insn & 0xff) * 4;
135
if ((insn & (1 << 23)) == 0) {
136
offset = -offset;
137
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
138
store_reg(s, rd, tmp);
139
} else {
140
/* Add/sub 12-bit immediate. */
141
- if (rn == 15) {
142
- offset = s->pc & ~(uint32_t)3;
143
- if (insn & (1 << 23))
144
- offset -= imm;
145
- else
146
- offset += imm;
147
- tmp = tcg_temp_new_i32();
148
- tcg_gen_movi_i32(tmp, offset);
149
- store_reg(s, rd, tmp);
150
+ if (insn & (1 << 23)) {
151
+ imm = -imm;
152
+ }
153
+ tmp = add_reg_for_lit(s, rn, imm);
154
+ if (rn == 13 && rd == 13) {
155
+ /* ADD SP, SP, imm or SUB SP, SP, imm */
156
+ store_sp_checked(s, tmp);
157
} else {
158
- tmp = load_reg(s, rn);
159
- if (insn & (1 << 23))
160
- tcg_gen_subi_i32(tmp, tmp, imm);
161
- else
162
- tcg_gen_addi_i32(tmp, tmp, imm);
163
- if (rn == 13 && rd == 13) {
164
- /* ADD SP, SP, imm or SUB SP, SP, imm */
165
- store_sp_checked(s, tmp);
166
- } else {
167
- store_reg(s, rd, tmp);
168
- }
169
+ store_reg(s, rd, tmp);
170
}
171
}
172
}
173
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
174
}
175
}
176
memidx = get_mem_index(s);
177
- if (rn == 15) {
178
- addr = tcg_temp_new_i32();
179
- /* PC relative. */
180
- /* s->pc has already been incremented by 4. */
181
- imm = s->pc & 0xfffffffc;
182
- if (insn & (1 << 23))
183
- imm += insn & 0xfff;
184
- else
185
- imm -= insn & 0xfff;
186
- tcg_gen_movi_i32(addr, imm);
187
+ imm = insn & 0xfff;
188
+ if (insn & (1 << 23)) {
189
+ /* PC relative or Positive offset. */
190
+ addr = add_reg_for_lit(s, rn, imm);
191
+ } else if (rn == 15) {
192
+ /* PC relative with negative offset. */
193
+ addr = add_reg_for_lit(s, rn, -imm);
194
} else {
195
addr = load_reg(s, rn);
196
- if (insn & (1 << 23)) {
197
- /* Positive offset. */
198
- imm = insn & 0xfff;
199
- tcg_gen_addi_i32(addr, addr, imm);
200
- } else {
201
- imm = insn & 0xff;
202
- switch ((insn >> 8) & 0xf) {
203
- case 0x0: /* Shifted Register. */
204
- shift = (insn >> 4) & 0xf;
205
- if (shift > 3) {
206
- tcg_temp_free_i32(addr);
207
- goto illegal_op;
208
- }
209
- tmp = load_reg(s, rm);
210
- if (shift)
211
- tcg_gen_shli_i32(tmp, tmp, shift);
212
- tcg_gen_add_i32(addr, addr, tmp);
213
- tcg_temp_free_i32(tmp);
214
- break;
215
- case 0xc: /* Negative offset. */
216
- tcg_gen_addi_i32(addr, addr, -imm);
217
- break;
218
- case 0xe: /* User privilege. */
219
- tcg_gen_addi_i32(addr, addr, imm);
220
- memidx = get_a32_user_mem_index(s);
221
- break;
222
- case 0x9: /* Post-decrement. */
223
- imm = -imm;
224
- /* Fall through. */
225
- case 0xb: /* Post-increment. */
226
- postinc = 1;
227
- writeback = 1;
228
- break;
229
- case 0xd: /* Pre-decrement. */
230
- imm = -imm;
231
- /* Fall through. */
232
- case 0xf: /* Pre-increment. */
233
- writeback = 1;
234
- break;
235
- default:
236
+ imm = insn & 0xff;
237
+ switch ((insn >> 8) & 0xf) {
238
+ case 0x0: /* Shifted Register. */
239
+ shift = (insn >> 4) & 0xf;
240
+ if (shift > 3) {
241
tcg_temp_free_i32(addr);
242
goto illegal_op;
243
}
244
+ tmp = load_reg(s, rm);
245
+ if (shift) {
246
+ tcg_gen_shli_i32(tmp, tmp, shift);
247
+ }
248
+ tcg_gen_add_i32(addr, addr, tmp);
249
+ tcg_temp_free_i32(tmp);
250
+ break;
251
+ case 0xc: /* Negative offset. */
252
+ tcg_gen_addi_i32(addr, addr, -imm);
253
+ break;
254
+ case 0xe: /* User privilege. */
255
+ tcg_gen_addi_i32(addr, addr, imm);
256
+ memidx = get_a32_user_mem_index(s);
257
+ break;
258
+ case 0x9: /* Post-decrement. */
259
+ imm = -imm;
260
+ /* Fall through. */
261
+ case 0xb: /* Post-increment. */
262
+ postinc = 1;
263
+ writeback = 1;
264
+ break;
265
+ case 0xd: /* Pre-decrement. */
266
+ imm = -imm;
267
+ /* Fall through. */
268
+ case 0xf: /* Pre-increment. */
269
+ writeback = 1;
270
+ break;
271
+ default:
272
+ tcg_temp_free_i32(addr);
273
+ goto illegal_op;
274
}
275
}
276
277
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
278
if (insn & (1 << 11)) {
279
rd = (insn >> 8) & 7;
280
/* load pc-relative. Bit 1 of PC is ignored. */
281
- val = read_pc(s) + ((insn & 0xff) * 4);
282
- val &= ~(uint32_t)2;
283
- addr = tcg_temp_new_i32();
284
- tcg_gen_movi_i32(addr, val);
285
+ addr = add_reg_for_lit(s, 15, (insn & 0xff) * 4);
286
tmp = tcg_temp_new_i32();
287
gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
288
rd | ISSIs16Bit);
289
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
290
* - Add PC/SP (immediate)
291
*/
292
rd = (insn >> 8) & 7;
293
- if (insn & (1 << 11)) {
294
- /* SP */
295
- tmp = load_reg(s, 13);
296
- } else {
297
- /* PC. bit 1 is ignored. */
298
- tmp = tcg_temp_new_i32();
299
- tcg_gen_movi_i32(tmp, read_pc(s) & ~(uint32_t)2);
300
- }
301
val = (insn & 0xff) * 4;
302
- tcg_gen_addi_i32(tmp, tmp, val);
303
+ tmp = add_reg_for_lit(s, insn & (1 << 11) ? 13 : 15, val);
304
store_reg(s, rd, tmp);
305
break;
306
78
307
--
79
--
308
2.20.1
80
2.34.1
309
310
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
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).
2
10
3
Add a new field to retain the address of the instruction currently
11
Fortunately raven_io_read() and raven_io_write() will correctly deal
4
being translated. The 32-bit uses are all within subroutines used
12
with the case of being passed an unaligned address, so we can fix the
5
by a32 and t32. This will become less obvious when t16 support is
13
missing unaligned access support by setting .impl.unaligned in the
6
merged with a32+t32, and having a clear definition will help.
14
MemoryRegionOps struct.
7
15
8
Convert aarch64 as well for consistency. Note that there is one
16
Fixes: 9a1839164c9c8f06 ("raven: Implement non-contiguous I/O region")
9
instance of a pre-assert fprintf that used the wrong value for the
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
address of the current instruction.
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(+)
11
24
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
25
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Message-id: 20190807045335.1361-3-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
target/arm/translate-a64.h | 2 +-
19
target/arm/translate.h | 2 ++
20
target/arm/translate-a64.c | 21 +++++++++++----------
21
target/arm/translate.c | 14 ++++++++------
22
4 files changed, 22 insertions(+), 17 deletions(-)
23
24
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
25
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-a64.h
27
--- a/hw/pci-host/raven.c
27
+++ b/target/arm/translate-a64.h
28
+++ b/hw/pci-host/raven.c
28
@@ -XXX,XX +XXX,XX @@ void unallocated_encoding(DisasContext *s);
29
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps raven_io_ops = {
29
qemu_log_mask(LOG_UNIMP, \
30
.write = raven_io_write,
30
"%s:%d: unsupported instruction encoding 0x%08x " \
31
.endianness = DEVICE_LITTLE_ENDIAN,
31
"at pc=%016" PRIx64 "\n", \
32
.impl.max_access_size = 4,
32
- __FILE__, __LINE__, insn, s->pc - 4); \
33
+ .impl.unaligned = true,
33
+ __FILE__, __LINE__, insn, s->pc_curr); \
34
.valid.unaligned = true,
34
unallocated_encoding(s); \
35
};
35
} while (0)
36
36
37
diff --git a/target/arm/translate.h b/target/arm/translate.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate.h
40
+++ b/target/arm/translate.h
41
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
42
const ARMISARegisters *isar;
43
44
target_ulong pc;
45
+ /* The address of the current instruction being translated. */
46
+ target_ulong pc_curr;
47
target_ulong page_start;
48
uint32_t insn;
49
/* Nonzero if this instruction has been conditionally skipped. */
50
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/translate-a64.c
53
+++ b/target/arm/translate-a64.c
54
@@ -XXX,XX +XXX,XX @@ static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table,
55
*/
56
static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
57
{
58
- uint64_t addr = s->pc + sextract32(insn, 0, 26) * 4 - 4;
59
+ uint64_t addr = s->pc_curr + sextract32(insn, 0, 26) * 4;
60
61
if (insn & (1U << 31)) {
62
/* BL Branch with link */
63
@@ -XXX,XX +XXX,XX @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
64
sf = extract32(insn, 31, 1);
65
op = extract32(insn, 24, 1); /* 0: CBZ; 1: CBNZ */
66
rt = extract32(insn, 0, 5);
67
- addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
68
+ addr = s->pc_curr + sextract32(insn, 5, 19) * 4;
69
70
tcg_cmp = read_cpu_reg(s, rt, sf);
71
label_match = gen_new_label();
72
@@ -XXX,XX +XXX,XX @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn)
73
74
bit_pos = (extract32(insn, 31, 1) << 5) | extract32(insn, 19, 5);
75
op = extract32(insn, 24, 1); /* 0: TBZ; 1: TBNZ */
76
- addr = s->pc + sextract32(insn, 5, 14) * 4 - 4;
77
+ addr = s->pc_curr + sextract32(insn, 5, 14) * 4;
78
rt = extract32(insn, 0, 5);
79
80
tcg_cmp = tcg_temp_new_i64();
81
@@ -XXX,XX +XXX,XX @@ static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
82
unallocated_encoding(s);
83
return;
84
}
85
- addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
86
+ addr = s->pc_curr + sextract32(insn, 5, 19) * 4;
87
cond = extract32(insn, 0, 4);
88
89
reset_btype(s);
90
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
91
TCGv_i32 tcg_syn, tcg_isread;
92
uint32_t syndrome;
93
94
- gen_a64_set_pc_im(s->pc - 4);
95
+ gen_a64_set_pc_im(s->pc_curr);
96
tmpptr = tcg_const_ptr(ri);
97
syndrome = syn_aa64_sysregtrap(op0, op1, op2, crn, crm, rt, isread);
98
tcg_syn = tcg_const_i32(syndrome);
99
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
100
/* The pre HVC helper handles cases when HVC gets trapped
101
* as an undefined insn by runtime configuration.
102
*/
103
- gen_a64_set_pc_im(s->pc - 4);
104
+ gen_a64_set_pc_im(s->pc_curr);
105
gen_helper_pre_hvc(cpu_env);
106
gen_ss_advance(s);
107
gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16), 2);
108
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
109
unallocated_encoding(s);
110
break;
111
}
112
- gen_a64_set_pc_im(s->pc - 4);
113
+ gen_a64_set_pc_im(s->pc_curr);
114
tmp = tcg_const_i32(syn_aa64_smc(imm16));
115
gen_helper_pre_smc(cpu_env, tmp);
116
tcg_temp_free_i32(tmp);
117
@@ -XXX,XX +XXX,XX @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)
118
119
tcg_rt = cpu_reg(s, rt);
120
121
- clean_addr = tcg_const_i64((s->pc - 4) + imm);
122
+ clean_addr = tcg_const_i64(s->pc_curr + imm);
123
if (is_vector) {
124
do_fp_ld(s, rt, clean_addr, size);
125
} else {
126
@@ -XXX,XX +XXX,XX @@ static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
127
offset = sextract64(insn, 5, 19);
128
offset = offset << 2 | extract32(insn, 29, 2);
129
rd = extract32(insn, 0, 5);
130
- base = s->pc - 4;
131
+ base = s->pc_curr;
132
133
if (page) {
134
/* ADRP (page based) */
135
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
136
break;
137
default:
138
fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
139
- __func__, insn, fpopcode, s->pc);
140
+ __func__, insn, fpopcode, s->pc_curr);
141
g_assert_not_reached();
142
}
143
144
@@ -XXX,XX +XXX,XX @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
145
{
146
uint32_t insn;
147
148
+ s->pc_curr = s->pc;
149
insn = arm_ldl_code(env, s->pc, s->sctlr_b);
150
s->insn = insn;
151
s->pc += 4;
152
diff --git a/target/arm/translate.c b/target/arm/translate.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/target/arm/translate.c
155
+++ b/target/arm/translate.c
156
@@ -XXX,XX +XXX,XX @@ static inline void gen_hvc(DisasContext *s, int imm16)
157
* as an undefined insn by runtime configuration (ie before
158
* the insn really executes).
159
*/
160
- gen_set_pc_im(s, s->pc - 4);
161
+ gen_set_pc_im(s, s->pc_curr);
162
gen_helper_pre_hvc(cpu_env);
163
/* Otherwise we will treat this as a real exception which
164
* happens after execution of the insn. (The distinction matters
165
@@ -XXX,XX +XXX,XX @@ static inline void gen_smc(DisasContext *s)
166
*/
167
TCGv_i32 tmp;
168
169
- gen_set_pc_im(s, s->pc - 4);
170
+ gen_set_pc_im(s, s->pc_curr);
171
tmp = tcg_const_i32(syn_aa32_smc());
172
gen_helper_pre_smc(cpu_env, tmp);
173
tcg_temp_free_i32(tmp);
174
@@ -XXX,XX +XXX,XX @@ static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
175
176
/* Sync state because msr_banked() can raise exceptions */
177
gen_set_condexec(s);
178
- gen_set_pc_im(s, s->pc - 4);
179
+ gen_set_pc_im(s, s->pc_curr);
180
tcg_reg = load_reg(s, rn);
181
tcg_tgtmode = tcg_const_i32(tgtmode);
182
tcg_regno = tcg_const_i32(regno);
183
@@ -XXX,XX +XXX,XX @@ static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
184
185
/* Sync state because mrs_banked() can raise exceptions */
186
gen_set_condexec(s);
187
- gen_set_pc_im(s, s->pc - 4);
188
+ gen_set_pc_im(s, s->pc_curr);
189
tcg_reg = tcg_temp_new_i32();
190
tcg_tgtmode = tcg_const_i32(tgtmode);
191
tcg_regno = tcg_const_i32(regno);
192
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
193
}
194
195
gen_set_condexec(s);
196
- gen_set_pc_im(s, s->pc - 4);
197
+ gen_set_pc_im(s, s->pc_curr);
198
tmpptr = tcg_const_ptr(ri);
199
tcg_syn = tcg_const_i32(syndrome);
200
tcg_isread = tcg_const_i32(isread);
201
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
202
tmp = tcg_const_i32(mode);
203
/* get_r13_banked() will raise an exception if called from System mode */
204
gen_set_condexec(s);
205
- gen_set_pc_im(s, s->pc - 4);
206
+ gen_set_pc_im(s, s->pc_curr);
207
gen_helper_get_r13_banked(addr, cpu_env, tmp);
208
tcg_temp_free_i32(tmp);
209
switch (amode) {
210
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
211
return;
212
}
213
214
+ dc->pc_curr = dc->pc;
215
insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
216
dc->insn = insn;
217
dc->pc += 4;
218
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
219
return;
220
}
221
222
+ dc->pc_curr = dc->pc;
223
insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
224
is_16bit = thumb_insn_is_16bit(dc, dc->pc, insn);
225
dc->pc += 2;
226
--
37
--
227
2.20.1
38
2.34.1
228
39
229
40
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Suppress the deprecation warning when we're running under qtest,
2
to avoid "make check" including warning messages in its output.
2
3
3
The immediate shift generator functions already test for,
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
and eliminate, the case of a shift by zero.
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20240206154151.155620-1-peter.maydell@linaro.org
7
---
8
hw/block/tc58128.c | 4 +++-
9
1 file changed, 3 insertions(+), 1 deletion(-)
5
10
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c
7
Message-id: 20190808202616.13782-4-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate.c | 19 +++++++------------
12
1 file changed, 7 insertions(+), 12 deletions(-)
13
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
13
--- a/hw/block/tc58128.c
17
+++ b/target/arm/translate.c
14
+++ b/hw/block/tc58128.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
15
@@ -XXX,XX +XXX,XX @@ static sh7750_io_device tc58128 = {
19
shift = (insn >> 10) & 3;
16
20
/* ??? In many cases it's not necessary to do a
17
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2)
21
rotate, a shift is sufficient. */
18
{
22
- if (shift != 0)
19
- warn_report_once("The TC58128 flash device is deprecated");
23
- tcg_gen_rotri_i32(tmp, tmp, shift * 8);
20
+ if (!qtest_enabled()) {
24
+ tcg_gen_rotri_i32(tmp, tmp, shift * 8);
21
+ warn_report_once("The TC58128 flash device is deprecated");
25
op1 = (insn >> 20) & 7;
22
+ }
26
switch (op1) {
23
init_dev(&tc58128_devs[0], zone1);
27
case 0: gen_sxtb16(tmp); break;
24
init_dev(&tc58128_devs[1], zone2);
28
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
25
return sh7750_register_io_device(s, &tc58128);
29
shift = (insn >> 4) & 3;
30
/* ??? In many cases it's not necessary to do a
31
rotate, a shift is sufficient. */
32
- if (shift != 0)
33
- tcg_gen_rotri_i32(tmp, tmp, shift * 8);
34
+ tcg_gen_rotri_i32(tmp, tmp, shift * 8);
35
op = (insn >> 20) & 7;
36
switch (op) {
37
case 0: gen_sxth(tmp); break;
38
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
39
case 7:
40
goto illegal_op;
41
default: /* Saturate. */
42
- if (shift) {
43
- if (op & 1)
44
- tcg_gen_sari_i32(tmp, tmp, shift);
45
- else
46
- tcg_gen_shli_i32(tmp, tmp, shift);
47
+ if (op & 1) {
48
+ tcg_gen_sari_i32(tmp, tmp, shift);
49
+ } else {
50
+ tcg_gen_shli_i32(tmp, tmp, shift);
51
}
52
tmp2 = tcg_const_i32(imm);
53
if (op & 4) {
54
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
55
goto illegal_op;
56
}
57
tmp = load_reg(s, rm);
58
- if (shift) {
59
- tcg_gen_shli_i32(tmp, tmp, shift);
60
- }
61
+ tcg_gen_shli_i32(tmp, tmp, shift);
62
tcg_gen_add_i32(addr, addr, tmp);
63
tcg_temp_free_i32(tmp);
64
break;
65
--
26
--
66
2.20.1
27
2.34.1
67
28
68
29
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
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.
2
4
3
The thumb bit has already been removed from s->pc, and is always even.
5
In commit 327b680877b79c4b we added it to qtests_aarch64; revert
6
that change.
4
7
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Fixes: 327b680877b79c4b ("tests/qtest: Creating qtest for GMAC Module")
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190807045335.1361-6-richard.henderson@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
Message-id: 20240206163043.315535-1-peter.maydell@linaro.org
10
---
12
---
11
target/arm/translate.c | 10 +++++-----
13
tests/qtest/meson.build | 1 -
12
1 file changed, 5 insertions(+), 5 deletions(-)
14
1 file changed, 1 deletion(-)
13
15
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
18
--- a/tests/qtest/meson.build
17
+++ b/target/arm/translate.c
19
+++ b/tests/qtest/meson.build
18
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
20
@@ -XXX,XX +XXX,XX @@ qtests_aarch64 = \
19
/* Force a TB lookup after an instruction that changes the CPU state. */
21
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
20
static inline void gen_lookup_tb(DisasContext *s)
22
(config_all_accel.has_key('CONFIG_TCG') and \
21
{
23
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
22
- tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
24
- (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
23
+ tcg_gen_movi_i32(cpu_R[15], s->pc);
25
['arm-cpu-features',
24
s->base.is_jmp = DISAS_EXIT;
26
'numa-test',
25
}
27
'boot-serial-test',
26
27
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
28
* self-modifying code correctly and also to take
29
* any pending interrupts immediately.
30
*/
31
- gen_goto_tb(s, 0, s->pc & ~1);
32
+ gen_goto_tb(s, 0, s->pc);
33
return;
34
case 7: /* sb */
35
if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
36
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
37
* for TCG; MB and end the TB instead.
38
*/
39
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
40
- gen_goto_tb(s, 0, s->pc & ~1);
41
+ gen_goto_tb(s, 0, s->pc);
42
return;
43
default:
44
goto illegal_op;
45
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
46
* and also to take any pending interrupts
47
* immediately.
48
*/
49
- gen_goto_tb(s, 0, s->pc & ~1);
50
+ gen_goto_tb(s, 0, s->pc);
51
break;
52
case 7: /* sb */
53
if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
54
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
55
* for TCG; MB and end the TB instead.
56
*/
57
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
58
- gen_goto_tb(s, 0, s->pc & ~1);
59
+ gen_goto_tb(s, 0, s->pc);
60
break;
61
default:
62
goto illegal_op;
63
--
28
--
64
2.20.1
29
2.34.1
65
30
66
31
diff view generated by jsdifflib
New patch
1
Allow changes to the virt GTDT -- we are going to add the IRQ
2
entry for a new timer to it.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
6
Message-id: 20240122143537.233498-2-peter.maydell@linaro.org
7
---
8
tests/qtest/bios-tables-test-allowed-diff.h | 2 ++
9
1 file changed, 2 insertions(+)
10
11
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/tests/qtest/bios-tables-test-allowed-diff.h
14
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
15
@@ -1 +1,3 @@
16
/* List of comma-separated changed AML files to ignore */
17
+"tests/data/acpi/virt/FACP",
18
+"tests/data/acpi/virt/GTDT",
19
--
20
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
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
We currently have 3 different ways of computing the architectural
3
CPU model, but never wired up its IRQ line to the GIC.
4
value of "PC" as seen in the ARM ARM.
4
5
5
Wire up the IRQ line (this is always safe whether the CPU has the
6
The value of s->pc has been incremented past the current insn,
6
interrupt or not, since it always creates the outbound IRQ line).
7
but that is all. Thus for a32, PC = s->pc + 4; for t32, PC = s->pc;
7
Report it to the guest via dtb and ACPI if the CPU has the feature.
8
for t16, PC = s->pc + 2. These differing computations make it
8
9
impossible at present to unify the various code paths.
9
The DTB binding is documented in the kernel's
10
10
Documentation/devicetree/bindings/timer/arm\,arch_timer.yaml
11
With the newly introduced s->pc_curr, we can compute the correct
11
and the ACPI table entries are documented in the ACPI specification
12
value for all cases, using the formula given in the ARM ARM.
12
version 6.3 or later.
13
13
14
This changes the behaviour for load_reg() and load_reg_var()
14
Because the IRQ line ACPI binding is new in 6.3, we need to bump the
15
when called with reg==15 from a 32-bit Thumb instruction:
15
FADT table rev to show that we might be using 6.3 features.
16
previously they would have returned the incorrect value
16
17
of pc_curr + 6, and now they will return the architecturally
17
Note that exposing this IRQ in the DTB will trigger a bug in EDK2
18
correct value of PC, which is pc_curr + 4. This will not
18
versions prior to edk2-stable202311, for users who use the virt board
19
affect well-behaved guest software, because all of the places
19
with 'virtualization=on' to enable EL2 emulation and are booting an
20
we call these functions from T32 code are instructions where
20
EDK2 guest BIOS, if that EDK2 has assertions enabled. The effect is
21
using r15 is UNPREDICTABLE. Using the architectural PC value
21
that EDK2 will assert on bootup:
22
here is more consistent with the T16 and A32 behaviour.
22
23
23
ASSERT [ArmTimerDxe] /home/kraxel/projects/qemu/roms/edk2/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.c(72): PropSize == 36 || PropSize == 48
24
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
24
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
If you see that assertion you should do one of:
26
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
26
* update your EDK2 binaries to edk2-stable202311 or newer
27
Message-id: 20190807045335.1361-4-richard.henderson@linaro.org
27
* use the 'virt-8.2' versioned machine type
28
[PMM: added commit message note about UNPREDICTABLE T32 cases]
28
* not use 'virtualization=on'
29
30
(The versions shipped with QEMU itself have the fix.)
31
29
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
30
---
35
---
31
target/arm/translate.c | 59 ++++++++++++++++--------------------------
36
include/hw/arm/virt.h | 2 ++
32
1 file changed, 23 insertions(+), 36 deletions(-)
37
hw/arm/virt-acpi-build.c | 20 ++++++++++----
33
38
hw/arm/virt.c | 60 ++++++++++++++++++++++++++++++++++------
34
diff --git a/target/arm/translate.c b/target/arm/translate.c
39
3 files changed, 67 insertions(+), 15 deletions(-)
40
41
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
35
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate.c
43
--- a/include/hw/arm/virt.h
37
+++ b/target/arm/translate.c
44
+++ b/include/hw/arm/virt.h
38
@@ -XXX,XX +XXX,XX @@ static inline void store_cpu_offset(TCGv_i32 var, int offset)
45
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
39
#define store_cpu_field(var, name) \
46
/* Machines < 6.2 have no support for describing cpu topology to guest */
40
store_cpu_offset(var, offsetof(CPUARMState, name))
47
bool no_cpu_topology;
41
48
bool no_tcg_lpa2;
42
+/* The architectural value of PC. */
49
+ bool no_ns_el2_virt_timer_irq;
43
+static uint32_t read_pc(DisasContext *s)
50
};
51
52
struct VirtMachineState {
53
@@ -XXX,XX +XXX,XX @@ struct VirtMachineState {
54
PCIBus *bus;
55
char *oem_id;
56
char *oem_table_id;
57
+ bool ns_el2_virt_timer_irq;
58
};
59
60
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
61
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/virt-acpi-build.c
64
+++ b/hw/arm/virt-acpi-build.c
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)
73
*/
74
static void
75
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
76
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
77
uint32_t irqflags = vmc->claim_edge_triggered_timers ?
78
1 : /* Interrupt is Edge triggered */
79
0; /* Interrupt is Level triggered */
80
- AcpiTable table = { .sig = "GTDT", .rev = 2, .oem_id = vms->oem_id,
81
+ AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id,
82
.oem_table_id = vms->oem_table_id };
83
84
acpi_table_begin(&table, table_data);
85
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
86
build_append_int_noprefix(table_data, 0, 4);
87
/* Platform Timer Offset */
88
build_append_int_noprefix(table_data, 0, 4);
89
-
90
+ if (vms->ns_el2_virt_timer_irq) {
91
+ /* Virtual EL2 Timer GSIV */
92
+ build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL2_VIRT_IRQ, 4);
93
+ /* Virtual EL2 Timer Flags */
94
+ build_append_int_noprefix(table_data, irqflags, 4);
95
+ } else {
96
+ build_append_int_noprefix(table_data, 0, 4);
97
+ build_append_int_noprefix(table_data, 0, 4);
98
+ }
99
acpi_table_end(linker, &table);
100
}
101
102
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
103
static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker,
104
VirtMachineState *vms, unsigned dsdt_tbl_offset)
105
{
106
- /* ACPI v6.0 */
107
+ /* ACPI v6.3 */
108
AcpiFadtData fadt = {
109
.rev = 6,
110
- .minor_ver = 0,
111
+ .minor_ver = 3,
112
.flags = 1 << ACPI_FADT_F_HW_REDUCED_ACPI,
113
.xdsdt_tbl_offset = &dsdt_tbl_offset,
114
};
115
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
116
index XXXXXXX..XXXXXXX 100644
117
--- a/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)
44
+{
129
+{
45
+ return s->pc_curr + (s->thumb ? 4 : 8);
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);
46
+}
135
+}
47
+
136
+
48
/* Set a variable to the value of a CPU register. */
137
static void create_fdt(VirtMachineState *vms)
49
static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
50
{
138
{
51
if (reg == 15) {
139
MachineState *ms = MACHINE(vms);
52
- uint32_t addr;
140
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
53
- /* normally, since we updated PC, we need only to add one insn */
141
"arm,armv7-timer");
54
- if (s->thumb)
55
- addr = (long)s->pc + 2;
56
- else
57
- addr = (long)s->pc + 4;
58
- tcg_gen_movi_i32(var, addr);
59
+ tcg_gen_movi_i32(var, read_pc(s));
60
} else {
61
tcg_gen_mov_i32(var, cpu_R[reg]);
62
}
142
}
63
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
143
qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0);
64
/* branch link and change to thumb (blx <offset>) */
144
- qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
65
int32_t offset;
145
- GIC_FDT_IRQ_TYPE_PPI,
66
146
- INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
67
- val = (uint32_t)s->pc;
147
- GIC_FDT_IRQ_TYPE_PPI,
68
tmp = tcg_temp_new_i32();
148
- INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
69
- tcg_gen_movi_i32(tmp, val);
149
- GIC_FDT_IRQ_TYPE_PPI,
70
+ tcg_gen_movi_i32(tmp, s->pc);
150
- INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
71
store_reg(s, 14, tmp);
151
- GIC_FDT_IRQ_TYPE_PPI,
72
/* Sign-extend the 24-bit offset */
152
- INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
73
offset = (((int32_t)insn) << 8) >> 8;
153
+ if (vms->ns_el2_virt_timer_irq) {
74
+ val = read_pc(s);
154
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
75
/* offset * 4 + bit24 * 2 + (thumb bit) */
155
+ GIC_FDT_IRQ_TYPE_PPI,
76
val += (offset << 2) | ((insn >> 23) & 2) | 1;
156
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
77
- /* pipeline offset */
157
+ GIC_FDT_IRQ_TYPE_PPI,
78
- val += 4;
158
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
79
/* protected by ARCH(5); above, near the start of uncond block */
159
+ GIC_FDT_IRQ_TYPE_PPI,
80
gen_bx_im(s, val);
160
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
81
return;
161
+ GIC_FDT_IRQ_TYPE_PPI,
82
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
162
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags,
83
} else {
163
+ GIC_FDT_IRQ_TYPE_PPI,
84
/* store */
164
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_VIRT_IRQ), irqflags);
85
if (i == 15) {
165
+ } else {
86
- /* special case: r15 = PC + 8 */
166
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
87
- val = (long)s->pc + 4;
167
+ GIC_FDT_IRQ_TYPE_PPI,
88
tmp = tcg_temp_new_i32();
168
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
89
- tcg_gen_movi_i32(tmp, val);
169
+ GIC_FDT_IRQ_TYPE_PPI,
90
+ tcg_gen_movi_i32(tmp, read_pc(s));
170
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
91
} else if (user) {
171
+ GIC_FDT_IRQ_TYPE_PPI,
92
tmp = tcg_temp_new_i32();
172
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
93
tmp2 = tcg_const_i32(i);
173
+ GIC_FDT_IRQ_TYPE_PPI,
94
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
174
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
95
int32_t offset;
175
+ }
96
176
}
97
/* branch (and link) */
177
98
- val = (int32_t)s->pc;
178
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
99
if (insn & (1 << 24)) {
179
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
100
tmp = tcg_temp_new_i32();
180
[GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
101
- tcg_gen_movi_i32(tmp, val);
181
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
102
+ tcg_gen_movi_i32(tmp, s->pc);
182
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
103
store_reg(s, 14, tmp);
183
+ [GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
104
}
184
};
105
offset = sextract32(insn << 2, 0, 26);
185
106
- val += offset + 4;
186
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
107
- gen_jmp(s, val);
187
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
108
+ gen_jmp(s, read_pc(s) + offset);
188
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
109
}
189
object_unref(cpuobj);
110
break;
111
case 0xc:
112
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
113
tcg_temp_free_i32(addr);
114
} else if ((insn & (7 << 5)) == 0) {
115
/* Table Branch. */
116
- if (rn == 15) {
117
- addr = tcg_temp_new_i32();
118
- tcg_gen_movi_i32(addr, s->pc);
119
- } else {
120
- addr = load_reg(s, rn);
121
- }
122
+ addr = load_reg(s, rn);
123
tmp = load_reg(s, rm);
124
tcg_gen_add_i32(addr, addr, tmp);
125
if (insn & (1 << 4)) {
126
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
127
}
128
tcg_temp_free_i32(addr);
129
tcg_gen_shli_i32(tmp, tmp, 1);
130
- tcg_gen_addi_i32(tmp, tmp, s->pc);
131
+ tcg_gen_addi_i32(tmp, tmp, read_pc(s));
132
store_reg(s, 15, tmp);
133
} else {
134
bool is_lasr = false;
135
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
136
tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
137
}
138
139
- offset += s->pc;
140
+ offset += read_pc(s);
141
if (insn & (1 << 12)) {
142
/* b/bl */
143
gen_jmp(s, offset);
144
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
145
offset |= (insn & (1 << 11)) << 8;
146
147
/* jump to the offset */
148
- gen_jmp(s, s->pc + offset);
149
+ gen_jmp(s, read_pc(s) + offset);
150
}
151
} else {
152
/*
153
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
154
if (insn & (1 << 11)) {
155
rd = (insn >> 8) & 7;
156
/* load pc-relative. Bit 1 of PC is ignored. */
157
- val = s->pc + 2 + ((insn & 0xff) * 4);
158
+ val = read_pc(s) + ((insn & 0xff) * 4);
159
val &= ~(uint32_t)2;
160
addr = tcg_temp_new_i32();
161
tcg_gen_movi_i32(addr, val);
162
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
163
} else {
164
/* PC. bit 1 is ignored. */
165
tmp = tcg_temp_new_i32();
166
- tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
167
+ tcg_gen_movi_i32(tmp, read_pc(s) & ~(uint32_t)2);
168
}
169
val = (insn & 0xff) * 4;
170
tcg_gen_addi_i32(tmp, tmp, val);
171
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
172
tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
173
tcg_temp_free_i32(tmp);
174
offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
175
- val = (uint32_t)s->pc + 2;
176
- val += offset;
177
- gen_jmp(s, val);
178
+ gen_jmp(s, read_pc(s) + offset);
179
break;
180
181
case 15: /* IT, nop-hint. */
182
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
183
arm_skip_unless(s, cond);
184
185
/* jump to the offset */
186
- val = (uint32_t)s->pc + 2;
187
+ val = read_pc(s);
188
offset = ((int32_t)insn << 24) >> 24;
189
val += offset << 1;
190
gen_jmp(s, val);
191
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
192
break;
193
}
194
/* unconditional branch */
195
- val = (uint32_t)s->pc;
196
+ val = read_pc(s);
197
offset = ((int32_t)insn << 21) >> 21;
198
- val += (offset << 1) + 2;
199
+ val += offset << 1;
200
gen_jmp(s, val);
201
break;
202
203
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
204
/* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
205
uint32_t uoffset = ((int32_t)insn << 21) >> 9;
206
207
- tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
208
+ tcg_gen_movi_i32(cpu_R[14], read_pc(s) + uoffset);
209
}
210
break;
211
}
190
}
191
+
192
+ /* Now we've created the CPUs we can see if they have the hypvirt timer */
193
+ vms->ns_el2_virt_timer_irq = ns_el2_virt_timer_present() &&
194
+ !vmc->no_ns_el2_virt_timer_irq;
195
+
196
fdt_add_timer_nodes(vms);
197
fdt_add_cpu_nodes(vms);
198
199
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(9, 0)
200
201
static void virt_machine_8_2_options(MachineClass *mc)
202
{
203
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
204
+
205
virt_machine_9_0_options(mc);
206
compat_props_add(mc->compat_props, hw_compat_8_2, hw_compat_8_2_len);
207
+ /*
208
+ * Don't expose NS_EL2_VIRT timer IRQ in DTB on ACPI on 8.2 and
209
+ * earlier machines. (Exposing it tickles a bug in older EDK2
210
+ * guest BIOS binaries.)
211
+ */
212
+ vmc->no_ns_el2_virt_timer_irq = true;
213
}
214
DEFINE_VIRT_MACHINE(8, 2)
215
212
--
216
--
213
2.20.1
217
2.34.1
214
215
diff view generated by jsdifflib
New patch
1
1
Update the virt golden reference files to say that the FACP is ACPI
2
v6.3, and the GTDT table is a revision 3 table with space for the
3
virtual EL2 timer.
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 // ........
183
184
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
185
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
186
Message-id: 20240122143537.233498-4-peter.maydell@linaro.org
187
---
188
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
189
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
190
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
191
3 files changed, 2 deletions(-)
192
193
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
194
index XXXXXXX..XXXXXXX 100644
195
--- a/tests/qtest/bios-tables-test-allowed-diff.h
196
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
197
@@ -1,3 +1 @@
198
/* List of comma-separated changed AML files to ignore */
199
-"tests/data/acpi/virt/FACP",
200
-"tests/data/acpi/virt/GTDT",
201
diff --git a/tests/data/acpi/virt/FACP b/tests/data/acpi/virt/FACP
202
index XXXXXXX..XXXXXXX 100644
203
GIT binary patch
204
delta 25
205
gcmbQjG=+)F&CxkPgpq-PO=u!l<;2F$$vli407<0<)c^nh
206
207
delta 28
208
kcmbQjG=+)F&CxkPgpq-PO>`nx<-|!<6Akz$^DuG%0AAS!ssI20
209
210
diff --git a/tests/data/acpi/virt/GTDT b/tests/data/acpi/virt/GTDT
211
index XXXXXXX..XXXXXXX 100644
212
GIT binary patch
213
delta 25
214
bcmYeu;BpUf3CUn!U|^m+kt>V?$N&QXMtB4L
215
216
delta 16
217
Xcmc~u;BpUf2}xjJU|^avkt+-UB60)u
218
219
--
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
New patch
1
Currently QEMU will warn if there is a NIC on the board that
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:
1
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.
13
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
16
Reviewed-by: Thomas Huth <thuth@redhat.com>
17
Message-id: 20240206171231.396392-3-peter.maydell@linaro.org
18
---
19
tests/qtest/npcm7xx_emc-test.c | 5 ++++-
20
1 file changed, 4 insertions(+), 1 deletion(-)
21
22
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/tests/qtest/npcm7xx_emc-test.c
25
+++ b/tests/qtest/npcm7xx_emc-test.c
26
@@ -XXX,XX +XXX,XX @@ static int *packet_test_init(int module_num, GString *cmd_line)
27
* KISS and use -nic. The driver accepts 'emc0' and 'emc1' as aliases
28
* in the 'model' field to specify the device to match.
29
*/
30
- g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d ",
31
+ g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d "
32
+ "-nic user,model=npcm7xx-emc "
33
+ "-nic user,model=npcm-gmac "
34
+ "-nic user,model=npcm-gmac",
35
test_sockets[1], module_num);
36
37
g_test_queue_destroy(packet_test_clear, test_sockets);
38
--
39
2.34.1
diff view generated by jsdifflib
1
When generating an architectural single-step exception we were
1
It doesn't make sense to read the value of MDCR_EL2 on a non-A-profile
2
routing it to the "default exception level", which is to say
2
CPU, and in fact if you try to do it we will assert:
3
the same exception level we execute at except that EL0 exceptions
4
go to EL1. This is incorrect because the debug exception level
5
can be configured by the guest for situations such as single
6
stepping of EL0 and EL1 code by EL2.
7
3
8
We have to track the target debug exception level in the TB
4
#6 0x00007ffff4b95e96 in __GI___assert_fail
9
flags, because it is dependent on CPU state like HCR_EL2.TGE
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
10
and MDCR_EL2.TDE. (That we were previously calling the
6
#7 0x0000555555ebf412 in arm_security_space_below_el3 (env=0x555557bc8190) at ../../target/arm/helper.c:12600
11
arm_debug_target_el() function to determine dc->ss_same_el
7
#8 0x0000555555ea6f89 in arm_is_el2_enabled (env=0x555557bc8190) at ../../target/arm/cpu.h:2595
12
is itself a bug, though one that would only have manifested
8
#9 0x0000555555ea942f in arm_mdcr_el2_eff (env=0x555557bc8190) at ../../target/arm/internals.h:1512
13
as incorrect syndrome information.) Since we are out of TB
14
flag bits unless we want to expand into the cs_base field,
15
we share some bits with the M-profile only HANDLER and
16
STACKCHECK bits, since only A-profile has this singlestep.
17
9
18
Fixes: https://bugs.launchpad.net/qemu/+bug/1838913
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
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
23
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
21
Tested-by: Alex Bennée <alex.bennee@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Message-id: 20190805130952.4415-3-peter.maydell@linaro.org
25
Message-id: 20240208153346.970021-1-peter.maydell@linaro.org
23
---
26
---
24
target/arm/cpu.h | 5 +++++
27
target/arm/helper.c | 12 ++++++++++--
25
target/arm/translate.h | 15 +++++++++++----
28
1 file changed, 10 insertions(+), 2 deletions(-)
26
target/arm/helper.c | 6 ++++++
27
target/arm/translate-a64.c | 2 +-
28
target/arm/translate.c | 4 +++-
29
5 files changed, 26 insertions(+), 6 deletions(-)
30
29
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.h
34
+++ b/target/arm/cpu.h
35
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, PSTATE_SS, 26, 1)
36
/* Target EL if we take a floating-point-disabled exception */
37
FIELD(TBFLAG_ANY, FPEXC_EL, 24, 2)
38
FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
39
+/*
40
+ * For A-profile only, target EL for debug exceptions.
41
+ * Note that this overlaps with the M-profile-only HANDLER and STACKCHECK bits.
42
+ */
43
+FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 21, 2)
44
45
/* Bit usage when in AArch32 state: */
46
FIELD(TBFLAG_A32, THUMB, 0, 1)
47
diff --git a/target/arm/translate.h b/target/arm/translate.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/translate.h
50
+++ b/target/arm/translate.h
51
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
52
uint32_t svc_imm;
53
int aarch64;
54
int current_el;
55
+ /* Debug target exception level for single-step exceptions */
56
+ int debug_target_el;
57
GHashTable *cp_regs;
58
uint64_t features; /* CPU features bits */
59
/* Because unallocated encodings generate different exception syndrome
60
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
61
* ie A64 LDX*, LDAX*, A32/T32 LDREX*, LDAEX*.
62
*/
63
bool is_ldex;
64
- /* True if a single-step exception will be taken to the current EL */
65
- bool ss_same_el;
66
/* True if v8.3-PAuth is active. */
67
bool pauth_active;
68
/* True with v8.5-BTI and SCTLR_ELx.BT* set. */
69
@@ -XXX,XX +XXX,XX @@ static inline void gen_exception(int excp, uint32_t syndrome,
70
/* Generate an architectural singlestep exception */
71
static inline void gen_swstep_exception(DisasContext *s, int isv, int ex)
72
{
73
- gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, isv, ex),
74
- default_exception_el(s));
75
+ bool same_el = (s->debug_target_el == s->current_el);
76
+
77
+ /*
78
+ * If singlestep is targeting a lower EL than the current one,
79
+ * then s->ss_active must be false and we can never get here.
80
+ */
81
+ assert(s->debug_target_el >= s->current_el);
82
+
83
+ gen_exception(EXCP_UDEF, syn_swstep(same_el, isv, ex), s->debug_target_el);
84
}
85
86
/*
87
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
88
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
89
--- a/target/arm/helper.c
32
--- a/target/arm/helper.c
90
+++ b/target/arm/helper.c
33
+++ b/target/arm/helper.c
91
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
34
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
92
}
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;
93
}
50
}
94
51
95
+ if (!arm_feature(env, ARM_FEATURE_M)) {
52
+ mdcr_el2 = arm_mdcr_el2_eff(env);
96
+ int target_el = arm_debug_target_el(env);
53
+ hpmn = mdcr_el2 & MDCR_HPMN;
97
+
54
+
98
+ flags = FIELD_DP32(flags, TBFLAG_ANY, DEBUG_TARGET_EL, target_el);
55
if (!arm_feature(env, ARM_FEATURE_EL2) ||
99
+ }
56
(counter < hpmn || counter == 31)) {
100
+
57
e = env->cp15.c9_pmcr & PMCRE;
101
*pflags = flags;
102
*cs_base = 0;
103
}
104
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/target/arm/translate-a64.c
107
+++ b/target/arm/translate-a64.c
108
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
109
dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
110
dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
111
dc->is_ldex = false;
112
- dc->ss_same_el = (arm_debug_target_el(env) == dc->current_el);
113
+ dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
114
115
/* Bound the number of insns to execute to those left on the page. */
116
bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
117
diff --git a/target/arm/translate.c b/target/arm/translate.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/target/arm/translate.c
120
+++ b/target/arm/translate.c
121
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
122
dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
123
dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
124
dc->is_ldex = false;
125
- dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
126
+ if (!arm_feature(env, ARM_FEATURE_M)) {
127
+ dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
128
+ }
129
130
dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
131
132
--
58
--
133
2.20.1
59
2.34.1
134
60
135
61
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Nabih Estefan <nabihestefan@google.com>
2
2
3
Replace x = double_saturate(y) with x = add_saturate(y, y).
3
Fix the nocm_gmac-test.c file to run on a nuvoton 7xx machine instead
4
There is no need for a separate more specialized helper.
4
of 8xx. Also fix comments referencing this and values expecting 8xx.
5
5
6
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
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
[PMM: commit message tweaks]
9
Message-id: 20190807045335.1361-12-richard.henderson@linaro.org
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/helper.h | 1 -
14
tests/qtest/npcm_gmac-test.c | 84 +-----------------------------------
13
target/arm/op_helper.c | 15 ---------------
15
tests/qtest/meson.build | 3 +-
14
target/arm/translate.c | 4 ++--
16
2 files changed, 4 insertions(+), 83 deletions(-)
15
3 files changed, 2 insertions(+), 18 deletions(-)
16
17
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
18
diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.h
20
--- a/tests/qtest/npcm_gmac-test.c
20
+++ b/target/arm/helper.h
21
+++ b/tests/qtest/npcm_gmac-test.c
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(add_saturate, i32, env, i32, i32)
22
@@ -XXX,XX +XXX,XX @@ typedef struct TestData {
22
DEF_HELPER_3(sub_saturate, i32, env, i32, i32)
23
const GMACModule *module;
23
DEF_HELPER_3(add_usaturate, i32, env, i32, i32)
24
} TestData;
24
DEF_HELPER_3(sub_usaturate, i32, env, i32, i32)
25
25
-DEF_HELPER_2(double_saturate, i32, env, s32)
26
-/* Values extracted from hw/arm/npcm8xx.c */
26
DEF_HELPER_FLAGS_2(sdiv, TCG_CALL_NO_RWG_SE, s32, s32, s32)
27
+/* Values extracted from hw/arm/npcm7xx.c */
27
DEF_HELPER_FLAGS_2(udiv, TCG_CALL_NO_RWG_SE, i32, i32, i32)
28
static const GMACModule gmac_module_list[] = {
28
DEF_HELPER_FLAGS_1(rbit, TCG_CALL_NO_RWG_SE, i32, i32)
29
{
29
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
30
.irq = 14,
30
index XXXXXXX..XXXXXXX 100644
31
@@ -XXX,XX +XXX,XX @@ static const GMACModule gmac_module_list[] = {
31
--- a/target/arm/op_helper.c
32
.irq = 15,
32
+++ b/target/arm/op_helper.c
33
.base_addr = 0xf0804000
33
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sub_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
34
},
34
return res;
35
- {
36
- .irq = 16,
37
- .base_addr = 0xf0806000
38
- },
39
- {
40
- .irq = 17,
41
- .base_addr = 0xf0808000
42
- }
43
};
44
45
/* Returns the index of the GMAC module. */
46
@@ -XXX,XX +XXX,XX @@ static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
47
return qtest_readl(qts, mod->base_addr + regno);
35
}
48
}
36
49
37
-uint32_t HELPER(double_saturate)(CPUARMState *env, int32_t val)
50
-static uint16_t pcs_read(QTestState *qts, const GMACModule *mod,
51
- NPCMRegister regno)
38
-{
52
-{
39
- uint32_t res;
53
- uint32_t write_value = (regno & 0x3ffe00) >> 9;
40
- if (val >= 0x40000000) {
54
- qtest_writel(qts, PCS_BASE_ADDRESS + NPCM_PCS_IND_AC_BA, write_value);
41
- res = ~SIGNBIT;
55
- uint32_t read_offset = regno & 0x1ff;
42
- env->QF = 1;
56
- return qtest_readl(qts, PCS_BASE_ADDRESS + read_offset);
43
- } else if (val <= (int32_t)0xc0000000) {
44
- res = SIGNBIT;
45
- env->QF = 1;
46
- } else {
47
- res = val << 1;
48
- }
49
- return res;
50
-}
57
-}
51
-
58
-
52
uint32_t HELPER(add_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
59
/* Check that GMAC registers are reset to default value */
60
static void test_init(gconstpointer test_data)
53
{
61
{
54
uint32_t res = a + b;
62
const TestData *td = test_data;
55
diff --git a/target/arm/translate.c b/target/arm/translate.c
63
const GMACModule *mod = td->module;
64
- QTestState *qts = qtest_init("-machine npcm845-evb");
65
+ QTestState *qts = qtest_init("-machine npcm750-evb");
66
67
#define CHECK_REG32(regno, value) \
68
do { \
69
g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \
70
} while (0)
71
72
-#define CHECK_REG_PCS(regno, value) \
73
- do { \
74
- g_assert_cmphex(pcs_read(qts, mod, (regno)), ==, (value)); \
75
- } while (0)
76
-
77
CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100);
78
CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0);
79
CHECK_REG32(NPCM_DMA_RCV_POLL_DEMAND, 0);
80
@@ -XXX,XX +XXX,XX @@ static void test_init(gconstpointer test_data)
81
CHECK_REG32(NPCM_GMAC_PTP_TAR, 0);
82
CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0);
83
84
- /* TODO Add registers PCS */
85
- if (mod->base_addr == 0xf0802000) {
86
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID1, 0x699e);
87
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID2, 0);
88
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_STS, 0x8000);
89
-
90
- CHECK_REG_PCS(NPCM_PCS_SR_MII_CTRL, 0x1140);
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);
140
- }
141
-
142
qtest_quit(qts);
143
}
144
145
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
56
index XXXXXXX..XXXXXXX 100644
146
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/translate.c
147
--- a/tests/qtest/meson.build
58
+++ b/target/arm/translate.c
148
+++ b/tests/qtest/meson.build
59
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
149
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
60
tmp = load_reg(s, rm);
150
'npcm7xx_sdhci-test',
61
tmp2 = load_reg(s, rn);
151
'npcm7xx_smbus-test',
62
if (op1 & 2)
152
'npcm7xx_timer-test',
63
- gen_helper_double_saturate(tmp2, cpu_env, tmp2);
153
- 'npcm7xx_watchdog_timer-test'] + \
64
+ gen_helper_add_saturate(tmp2, cpu_env, tmp2, tmp2);
154
+ 'npcm7xx_watchdog_timer-test',
65
if (op1 & 1)
155
+ 'npcm_gmac-test'] + \
66
gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
156
(slirp.found() ? ['npcm7xx_emc-test'] : [])
67
else
157
qtests_aspeed = \
68
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
158
['aspeed_hace-test',
69
tmp = load_reg(s, rn);
70
tmp2 = load_reg(s, rm);
71
if (op & 1)
72
- gen_helper_double_saturate(tmp, cpu_env, tmp);
73
+ gen_helper_add_saturate(tmp, cpu_env, tmp, tmp);
74
if (op & 2)
75
gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
76
else
77
--
159
--
78
2.20.1
160
2.34.1
79
80
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Luc Michel <luc.michel@amd.com>
2
2
3
The offset is variable depending on the instruction set, whereas
3
An access fault is raised when the Access Flag is not set in the
4
we have stored values for the current pc and the next pc. Passing
4
looked-up PTE and the AFFD field is not set in the corresponding context
5
in the actual value is clearer in intent.
5
descriptor. This was already implemented for stage 2. Implement it for
6
stage 1 as well.
6
7
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Luc Michel <luc.michel@amd.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Mostafa Saleh <smostafa@google.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Message-id: 20190807045335.1361-8-richard.henderson@linaro.org
11
Tested-by: Mostafa Saleh <smostafa@google.com>
12
Message-id: 20240213082211.3330400-1-luc.michel@amd.com
13
[PMM: tweaked comment text]
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
15
---
13
target/arm/translate-a64.c | 25 ++++++++++++++-----------
16
hw/arm/smmuv3-internal.h | 1 +
14
target/arm/translate-vfp.inc.c | 6 +++---
17
include/hw/arm/smmu-common.h | 1 +
15
target/arm/translate.c | 31 ++++++++++++++++---------------
18
hw/arm/smmu-common.c | 11 +++++++++++
16
3 files changed, 33 insertions(+), 29 deletions(-)
19
hw/arm/smmuv3.c | 1 +
20
4 files changed, 14 insertions(+)
17
21
18
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
22
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
19
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate-a64.c
24
--- a/hw/arm/smmuv3-internal.h
21
+++ b/target/arm/translate-a64.c
25
+++ b/hw/arm/smmuv3-internal.h
22
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
26
@@ -XXX,XX +XXX,XX @@ static inline int pa_range(STE *ste)
23
s->base.is_jmp = DISAS_NORETURN;
27
#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
24
}
28
#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
25
29
#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
26
-static void gen_exception_insn(DisasContext *s, int offset, int excp,
30
+#define CD_AFFD(x) extract32((x)->word[1], 3 , 1)
27
+static void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
31
#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
28
uint32_t syndrome, uint32_t target_el)
32
#define CD_HD(x) extract32((x)->word[1], 10 , 1)
29
{
33
#define CD_HA(x) extract32((x)->word[1], 11 , 1)
30
- gen_a64_set_pc_im(s->base.pc_next - offset);
34
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
31
+ gen_a64_set_pc_im(pc);
32
gen_exception(excp, syndrome, target_el);
33
s->base.is_jmp = DISAS_NORETURN;
34
}
35
@@ -XXX,XX +XXX,XX @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
36
void unallocated_encoding(DisasContext *s)
37
{
38
/* Unallocated and reserved encodings are uncategorized */
39
- gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
40
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
41
default_exception_el(s));
42
}
43
44
@@ -XXX,XX +XXX,XX @@ static inline bool fp_access_check(DisasContext *s)
45
return true;
46
}
47
48
- gen_exception_insn(s, 4, EXCP_UDEF, syn_fp_access_trap(1, 0xe, false),
49
- s->fp_excp_el);
50
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
51
+ syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
52
return false;
53
}
54
55
@@ -XXX,XX +XXX,XX @@ static inline bool fp_access_check(DisasContext *s)
56
bool sve_access_check(DisasContext *s)
57
{
58
if (s->sve_excp_el) {
59
- gen_exception_insn(s, 4, EXCP_UDEF, syn_sve_access_trap(),
60
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_sve_access_trap(),
61
s->sve_excp_el);
62
return false;
63
}
64
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
65
switch (op2_ll) {
66
case 1: /* SVC */
67
gen_ss_advance(s);
68
- gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16),
69
- default_exception_el(s));
70
+ gen_exception_insn(s, s->base.pc_next, EXCP_SWI,
71
+ syn_aa64_svc(imm16), default_exception_el(s));
72
break;
73
case 2: /* HVC */
74
if (s->current_el == 0) {
75
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
76
gen_a64_set_pc_im(s->pc_curr);
77
gen_helper_pre_hvc(cpu_env);
78
gen_ss_advance(s);
79
- gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16), 2);
80
+ gen_exception_insn(s, s->base.pc_next, EXCP_HVC,
81
+ syn_aa64_hvc(imm16), 2);
82
break;
83
case 3: /* SMC */
84
if (s->current_el == 0) {
85
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
86
gen_helper_pre_smc(cpu_env, tmp);
87
tcg_temp_free_i32(tmp);
88
gen_ss_advance(s);
89
- gen_exception_insn(s, 0, EXCP_SMC, syn_aa64_smc(imm16), 3);
90
+ gen_exception_insn(s, s->base.pc_next, EXCP_SMC,
91
+ syn_aa64_smc(imm16), 3);
92
break;
93
default:
94
unallocated_encoding(s);
95
@@ -XXX,XX +XXX,XX @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
96
if (s->btype != 0
97
&& s->guarded_page
98
&& !btype_destination_ok(insn, s->bt, s->btype)) {
99
- gen_exception_insn(s, 4, EXCP_UDEF, syn_btitrap(s->btype),
100
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
101
+ syn_btitrap(s->btype),
102
default_exception_el(s));
103
return;
104
}
105
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
106
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/translate-vfp.inc.c
36
--- a/include/hw/arm/smmu-common.h
108
+++ b/target/arm/translate-vfp.inc.c
37
+++ b/include/hw/arm/smmu-common.h
109
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
38
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
110
{
39
bool disabled; /* smmu is disabled */
111
if (s->fp_excp_el) {
40
bool bypassed; /* translation is bypassed */
112
if (arm_dc_feature(s, ARM_FEATURE_M)) {
41
bool aborted; /* translation is aborted */
113
- gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
42
+ bool affd; /* AF fault disable */
114
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized(),
43
uint32_t iotlb_hits; /* counts IOTLB hits */
115
s->fp_excp_el);
44
uint32_t iotlb_misses; /* counts IOTLB misses*/
116
} else {
45
/* Used by stage-1 only. */
117
- gen_exception_insn(s, 4, EXCP_UDEF,
46
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
118
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
47
index XXXXXXX..XXXXXXX 100644
119
syn_fp_access_trap(1, 0xe, false),
48
--- a/hw/arm/smmu-common.c
120
s->fp_excp_el);
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);
121
}
53
}
122
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
54
+
123
55
+ /*
124
if (!s->vfp_enabled && !ignore_vfp_enabled) {
56
+ * QEMU does not currently implement HTTU, so if AFFD and PTE.AF
125
assert(!arm_dc_feature(s, ARM_FEATURE_M));
57
+ * are 0 we take an Access flag fault. (5.4. Context Descriptor)
126
- gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
58
+ * An Access flag fault takes priority over a Permission fault.
127
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
59
+ */
128
default_exception_el(s));
60
+ if (!PTE_AF(pte) && !cfg->affd) {
129
return false;
61
+ info->type = SMMU_PTW_ERR_ACCESS;
130
}
62
+ goto error;
131
diff --git a/target/arm/translate.c b/target/arm/translate.c
63
+ }
64
+
65
ap = PTE_AP(pte);
66
if (is_permission_fault(ap, perm)) {
67
info->type = SMMU_PTW_ERR_PERMISSION;
68
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
132
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/translate.c
70
--- a/hw/arm/smmuv3.c
134
+++ b/target/arm/translate.c
71
+++ b/hw/arm/smmuv3.c
135
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
72
@@ -XXX,XX +XXX,XX @@ static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
136
s->base.is_jmp = DISAS_NORETURN;
73
cfg->oas = MIN(oas2bits(SMMU_IDR5_OAS), cfg->oas);
137
}
74
cfg->tbi = CD_TBI(cd);
138
75
cfg->asid = CD_ASID(cd);
139
-static void gen_exception_insn(DisasContext *s, int offset, int excp,
76
+ cfg->affd = CD_AFFD(cd);
140
+static void gen_exception_insn(DisasContext *s, uint32_t pc, int excp,
77
141
int syn, uint32_t target_el)
78
trace_smmuv3_decode_cd(cfg->oas);
142
{
143
gen_set_condexec(s);
144
- gen_set_pc_im(s, s->base.pc_next - offset);
145
+ gen_set_pc_im(s, pc);
146
gen_exception(excp, syn, target_el);
147
s->base.is_jmp = DISAS_NORETURN;
148
}
149
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
150
return;
151
}
152
153
- gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
154
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
155
default_exception_el(s));
156
}
157
158
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
159
160
undef:
161
/* If we get here then some access check did not pass */
162
- gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
163
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
164
+ syn_uncategorized(), exc_target);
165
return false;
166
}
167
168
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
169
* for attempts to execute invalid vfp/neon encodings with FP disabled.
170
*/
171
if (s->fp_excp_el) {
172
- gen_exception_insn(s, 4, EXCP_UDEF,
173
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
174
syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
175
return 0;
176
}
177
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
178
* for attempts to execute invalid vfp/neon encodings with FP disabled.
179
*/
180
if (s->fp_excp_el) {
181
- gen_exception_insn(s, 4, EXCP_UDEF,
182
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
183
syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
184
return 0;
185
}
186
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
187
}
188
189
if (s->fp_excp_el) {
190
- gen_exception_insn(s, 4, EXCP_UDEF,
191
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
192
syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
193
return 0;
194
}
195
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
196
off_rm = vfp_reg_offset(0, rm);
197
}
198
if (s->fp_excp_el) {
199
- gen_exception_insn(s, 4, EXCP_UDEF,
200
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
201
syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
202
return 0;
203
}
204
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
205
* For the UNPREDICTABLE cases we choose to UNDEF.
206
*/
207
if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
208
- gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
209
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), 3);
210
return;
211
}
212
213
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
214
}
215
216
if (undef) {
217
- gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
218
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
219
default_exception_el(s));
220
return;
221
}
222
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
223
* UsageFault exception.
224
*/
225
if (arm_dc_feature(s, ARM_FEATURE_M)) {
226
- gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
227
+ gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
228
default_exception_el(s));
229
return;
230
}
231
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
232
break;
233
default:
234
illegal_op:
235
- gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
236
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
237
default_exception_el(s));
238
break;
239
}
240
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
241
}
242
243
/* All other insns: NOCP */
244
- gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
245
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized(),
246
default_exception_el(s));
247
break;
248
}
249
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
250
}
251
return;
252
illegal_op:
253
- gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
254
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
255
default_exception_el(s));
256
}
257
258
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
259
return;
260
illegal_op:
261
undef:
262
- gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
263
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
264
default_exception_el(s));
265
}
266
79
267
--
80
--
268
2.20.1
81
2.34.1
269
270
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Unlike the other more generic gen_exception{,_internal}_insn
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
interfaces, breakpoints always refer to the current instruction.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20240213155214.13619-2-philmd@linaro.org
9
Message-id: 20190807045335.1361-10-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
7
---
12
target/arm/translate-a64.c | 7 +++----
8
hw/arm/stellaris.c | 6 ++++--
13
target/arm/translate.c | 8 ++++----
9
1 file changed, 4 insertions(+), 2 deletions(-)
14
2 files changed, 7 insertions(+), 8 deletions(-)
15
10
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.c
13
--- a/hw/arm/stellaris.c
19
+++ b/target/arm/translate-a64.c
14
+++ b/hw/arm/stellaris.c
20
@@ -XXX,XX +XXX,XX @@ static void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
15
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_trigger(void *opaque, int irq, int level)
21
s->base.is_jmp = DISAS_NORETURN;
16
}
22
}
17
}
23
18
24
-static void gen_exception_bkpt_insn(DisasContext *s, int offset,
19
-static void stellaris_adc_reset(StellarisADCState *s)
25
- uint32_t syndrome)
20
+static void stellaris_adc_reset_hold(Object *obj)
26
+static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syndrome)
27
{
21
{
28
TCGv_i32 tcg_syn;
22
+ StellarisADCState *s = STELLARIS_ADC(obj);
29
23
int n;
30
- gen_a64_set_pc_im(s->base.pc_next - offset);
24
31
+ gen_a64_set_pc_im(s->pc_curr);
25
for (n = 0; n < 4; n++) {
32
tcg_syn = tcg_const_i32(syndrome);
26
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_init(Object *obj)
33
gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
27
memory_region_init_io(&s->iomem, obj, &stellaris_adc_ops, s,
34
tcg_temp_free_i32(tcg_syn);
28
"adc", 0x1000);
35
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
29
sysbus_init_mmio(sbd, &s->iomem);
36
break;
30
- stellaris_adc_reset(s);
37
}
31
qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
38
/* BRK */
39
- gen_exception_bkpt_insn(s, 4, syn_aa64_bkpt(imm16));
40
+ gen_exception_bkpt_insn(s, syn_aa64_bkpt(imm16));
41
break;
42
case 2:
43
if (op2_ll != 0) {
44
diff --git a/target/arm/translate.c b/target/arm/translate.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/translate.c
47
+++ b/target/arm/translate.c
48
@@ -XXX,XX +XXX,XX @@ static void gen_exception_insn(DisasContext *s, uint32_t pc, int excp,
49
s->base.is_jmp = DISAS_NORETURN;
50
}
32
}
51
33
52
-static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
34
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stellaris_i2c_info = {
53
+static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
35
static void stellaris_adc_class_init(ObjectClass *klass, void *data)
54
{
36
{
55
TCGv_i32 tcg_syn;
37
DeviceClass *dc = DEVICE_CLASS(klass);
56
38
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
57
gen_set_condexec(s);
39
58
- gen_set_pc_im(s, s->base.pc_next - offset);
40
+ rc->phases.hold = stellaris_adc_reset_hold;
59
+ gen_set_pc_im(s, s->pc_curr);
41
dc->vmsd = &vmstate_stellaris_adc;
60
tcg_syn = tcg_const_i32(syn);
42
}
61
gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
62
tcg_temp_free_i32(tcg_syn);
63
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
64
case 1:
65
/* bkpt */
66
ARCH(5);
67
- gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
68
+ gen_exception_bkpt_insn(s, syn_aa32_bkpt(imm16, false));
69
break;
70
case 2:
71
/* Hypervisor call (v7) */
72
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
73
{
74
int imm8 = extract32(insn, 0, 8);
75
ARCH(5);
76
- gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
77
+ gen_exception_bkpt_insn(s, syn_aa32_bkpt(imm8, true));
78
break;
79
}
80
43
81
--
44
--
82
2.20.1
45
2.34.1
83
46
84
47
diff view generated by jsdifflib
1
Factor out code to 'generate a singlestep exception', which is
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
currently repeated in four places.
3
2
4
To do this we need to also pull the identical copies of the
3
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
5
gen-exception() function out of translate-a64.c and translate.c
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
into translate.h.
5
Message-id: 20240213155214.13619-3-philmd@linaro.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
hw/arm/stellaris.c | 26 ++++++++++++++++++++++----
10
1 file changed, 22 insertions(+), 4 deletions(-)
7
11
8
(There is a bug in the code: we're taking the exception to the wrong
12
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
9
target EL. This will be simpler to fix if there's only one place to
10
do it.)
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Message-id: 20190805130952.4415-2-peter.maydell@linaro.org
16
---
17
target/arm/translate.h | 23 +++++++++++++++++++++++
18
target/arm/translate-a64.c | 19 ++-----------------
19
target/arm/translate.c | 20 ++------------------
20
3 files changed, 27 insertions(+), 35 deletions(-)
21
22
diff --git a/target/arm/translate.h b/target/arm/translate.h
23
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/translate.h
14
--- a/hw/arm/stellaris.c
25
+++ b/target/arm/translate.h
15
+++ b/hw/arm/stellaris.c
26
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_instance_init(Object *obj)
27
#define TARGET_ARM_TRANSLATE_H
17
s->sysclk = qdev_init_clock_out(DEVICE(s), "SYSCLK");
28
29
#include "exec/translator.h"
30
+#include "internals.h"
31
32
33
/* internal defines */
34
@@ -XXX,XX +XXX,XX @@ static inline void gen_ss_advance(DisasContext *s)
35
}
36
}
18
}
37
19
38
+static inline void gen_exception(int excp, uint32_t syndrome,
20
-/* I2C controller. */
39
+ uint32_t target_el)
21
+/*
40
+{
22
+ * I2C controller.
41
+ TCGv_i32 tcg_excp = tcg_const_i32(excp);
23
+ * ??? For now we only implement the master interface.
42
+ TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
24
+ */
43
+ TCGv_i32 tcg_el = tcg_const_i32(target_el);
25
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);
44
+
36
+
45
+ gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
37
if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
46
+ tcg_syn, tcg_el);
38
i2c_end_transfer(s->bus);
47
+
48
+ tcg_temp_free_i32(tcg_el);
49
+ tcg_temp_free_i32(tcg_syn);
50
+ tcg_temp_free_i32(tcg_excp);
51
+}
39
+}
52
+
40
+
53
+/* Generate an architectural singlestep exception */
41
+static void stellaris_i2c_reset_hold(Object *obj)
54
+static inline void gen_swstep_exception(DisasContext *s, int isv, int ex)
55
+{
42
+{
56
+ gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, isv, ex),
43
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
57
+ default_exception_el(s));
44
45
s->msa = 0;
46
s->mcs = 0;
47
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_reset(stellaris_i2c_state *s)
48
s->mimr = 0;
49
s->mris = 0;
50
s->mcr = 0;
58
+}
51
+}
59
+
52
+
60
/*
53
+static void stellaris_i2c_reset_exit(Object *obj)
61
* Given a VFP floating point constant encoded into an 8 bit immediate in an
54
+{
62
* instruction, expand it to the actual constant value of the specified
55
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
63
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
56
+
64
index XXXXXXX..XXXXXXX 100644
57
stellaris_i2c_update(s);
65
--- a/target/arm/translate-a64.c
66
+++ b/target/arm/translate-a64.c
67
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal(int excp)
68
tcg_temp_free_i32(tcg_excp);
69
}
58
}
70
59
71
-static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
60
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_init(Object *obj)
72
-{
61
memory_region_init_io(&s->iomem, obj, &stellaris_i2c_ops, s,
73
- TCGv_i32 tcg_excp = tcg_const_i32(excp);
62
"i2c", 0x1000);
74
- TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
63
sysbus_init_mmio(sbd, &s->iomem);
75
- TCGv_i32 tcg_el = tcg_const_i32(target_el);
64
- /* ??? For now we only implement the master interface. */
76
-
65
- stellaris_i2c_reset(s);
77
- gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
66
}
78
- tcg_syn, tcg_el);
67
79
- tcg_temp_free_i32(tcg_el);
68
/* Analogue to Digital Converter. This is only partially implemented,
80
- tcg_temp_free_i32(tcg_syn);
69
@@ -XXX,XX +XXX,XX @@ type_init(stellaris_machine_init)
81
- tcg_temp_free_i32(tcg_excp);
70
static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
82
-}
83
-
84
static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
85
{
71
{
86
gen_a64_set_pc_im(s->pc - offset);
72
DeviceClass *dc = DEVICE_CLASS(klass);
87
@@ -XXX,XX +XXX,XX @@ static void gen_step_complete_exception(DisasContext *s)
73
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
88
* of the exception, and our syndrome information is always correct.
74
89
*/
75
+ rc->phases.enter = stellaris_i2c_reset_enter;
90
gen_ss_advance(s);
76
+ rc->phases.hold = stellaris_i2c_reset_hold;
91
- gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
77
+ rc->phases.exit = stellaris_i2c_reset_exit;
92
- default_exception_el(s));
78
dc->vmsd = &vmstate_stellaris_i2c;
93
+ gen_swstep_exception(s, 1, s->is_ldex);
94
s->base.is_jmp = DISAS_NORETURN;
95
}
79
}
96
80
97
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
98
* bits should be zero.
99
*/
100
assert(dc->base.num_insns == 1);
101
- gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
102
- default_exception_el(dc));
103
+ gen_swstep_exception(dc, 0, 0);
104
dc->base.is_jmp = DISAS_NORETURN;
105
} else {
106
disas_a64_insn(env, dc);
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/target/arm/translate.c
110
+++ b/target/arm/translate.c
111
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal(int excp)
112
tcg_temp_free_i32(tcg_excp);
113
}
114
115
-static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
116
-{
117
- TCGv_i32 tcg_excp = tcg_const_i32(excp);
118
- TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
119
- TCGv_i32 tcg_el = tcg_const_i32(target_el);
120
-
121
- gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
122
- tcg_syn, tcg_el);
123
-
124
- tcg_temp_free_i32(tcg_el);
125
- tcg_temp_free_i32(tcg_syn);
126
- tcg_temp_free_i32(tcg_excp);
127
-}
128
-
129
static void gen_step_complete_exception(DisasContext *s)
130
{
131
/* We just completed step of an insn. Move from Active-not-pending
132
@@ -XXX,XX +XXX,XX @@ static void gen_step_complete_exception(DisasContext *s)
133
* of the exception, and our syndrome information is always correct.
134
*/
135
gen_ss_advance(s);
136
- gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
137
- default_exception_el(s));
138
+ gen_swstep_exception(s, 1, s->is_ldex);
139
s->base.is_jmp = DISAS_NORETURN;
140
}
141
142
@@ -XXX,XX +XXX,XX @@ static bool arm_pre_translate_insn(DisasContext *dc)
143
* bits should be zero.
144
*/
145
assert(dc->base.num_insns == 1);
146
- gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
147
- default_exception_el(dc));
148
+ gen_swstep_exception(dc, 0, 0);
149
dc->base.is_jmp = DISAS_NORETURN;
150
return true;
151
}
152
--
81
--
153
2.20.1
82
2.34.1
154
83
155
84
diff view generated by jsdifflib
1
From: Aaron Hill <aa1ronham@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
This commit properly sets the ENET_BD_BDU flag once the emulated FEC controller
3
QDev objects created with qdev_new() need to manually add
4
has finished processing the last descriptor. This is done for both transmit
4
their parent relationship with object_property_add_child().
5
and receive descriptors.
6
5
7
This allows the QNX 7.0.0 BSP for the Sabrelite board (which can be
6
This commit plug the devices which aren't part of the SoC;
8
found at http://blackberry.qnx.com/en/developers/bsp) to properly
7
they will be plugged into a SoC container in the next one.
9
control the FEC. Without this patch, the BSP ethernet driver will never
10
re-use FEC descriptors, as the unset ENET_BD_BDU flag will cause
11
it to believe that the descriptors are still in use by the NIC.
12
8
13
Note that Linux does not appear to use this field at all, and is
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
unaffected by this patch.
15
16
Without this patch, QNX will think that the NIC is still processing its
17
transaction descriptors, and won't send any more data over the network.
18
19
For reference:
20
21
On page 1192 of the I.MX 6DQ reference manual revision (Rev. 5, 06/2018),
22
which can be found at https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/i.mx-applications-processors/i.mx-6-processors/i.mx-6quad-processors-high-performance-3d-graphics-hd-video-arm-cortex-a9-core:i.MX6Q?&tab=Documentation_Tab&linkline=Application-Note
23
24
the 'BDU' field is described as follows for the 'Enhanced transmit
25
buffer descriptor':
26
27
'Last buffer descriptor update done. Indicates that the last BD data has been updated by
28
uDMA. This field is written by the user (=0) and uDMA (=1).'
29
30
The same description is used for the receive buffer descriptor.
31
32
Signed-off-by: Aaron Hill <aa1ronham@gmail.com>
33
Message-id: 20190805142417.10433-1-aaron.hill@alertinnovation.com
34
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20240213155214.13619-4-philmd@linaro.org
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
36
---
13
---
37
hw/net/imx_fec.c | 4 ++++
14
hw/arm/stellaris.c | 4 ++++
38
1 file changed, 4 insertions(+)
15
1 file changed, 4 insertions(+)
39
16
40
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
17
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
41
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/net/imx_fec.c
19
--- a/hw/arm/stellaris.c
43
+++ b/hw/net/imx_fec.c
20
+++ b/hw/arm/stellaris.c
44
@@ -XXX,XX +XXX,XX @@ static void imx_enet_do_tx(IMXFECState *s, uint32_t index)
21
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
45
if (bd.option & ENET_BD_TX_INT) {
22
&error_fatal);
46
s->regs[ENET_EIR] |= int_txf;
23
47
}
24
ssddev = qdev_new("ssd0323");
48
+ /* Indicate that we've updated the last buffer descriptor. */
25
+ object_property_add_child(OBJECT(ms), "oled", OBJECT(ssddev));
49
+ bd.last_buffer = ENET_BD_BDU;
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]);
50
}
42
}
51
if (bd.option & ENET_BD_TX_INT) {
52
s->regs[ENET_EIR] |= int_txb;
53
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
54
/* Last buffer in frame. */
55
bd.flags |= flags | ENET_BD_L;
56
FEC_PRINTF("rx frame flags %04x\n", bd.flags);
57
+ /* Indicate that we've updated the last buffer descriptor. */
58
+ bd.last_buffer = ENET_BD_BDU;
59
if (bd.option & ENET_BD_RX_INT) {
60
s->regs[ENET_EIR] |= ENET_INT_RXF;
61
}
62
--
43
--
63
2.20.1
44
2.34.1
64
45
65
46
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Use deposit as the composit operation to merge the
3
QDev objects created with qdev_new() need to manually add
4
bits from the two inputs.
4
their parent relationship with object_property_add_child().
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Since we don't model the SoC, just use a QOM container.
7
Message-id: 20190808202616.13782-3-richard.henderson@linaro.org
7
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20240213155214.13619-5-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/translate.c | 26 ++++++++++----------------
13
hw/arm/stellaris.c | 11 ++++++++++-
12
1 file changed, 10 insertions(+), 16 deletions(-)
14
1 file changed, 10 insertions(+), 1 deletion(-)
13
15
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
18
--- a/hw/arm/stellaris.c
17
+++ b/target/arm/translate.c
19
+++ b/hw/arm/stellaris.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
20
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
19
shift = (insn >> 7) & 0x1f;
21
* 400fe000 system control
20
if (insn & (1 << 6)) {
22
*/
21
/* pkhtb */
23
22
- if (shift == 0)
24
+ Object *soc_container;
23
+ if (shift == 0) {
25
DeviceState *gpio_dev[7], *nvic;
24
shift = 31;
26
qemu_irq gpio_in[7][8];
25
+ }
27
qemu_irq gpio_out[7][8];
26
tcg_gen_sari_i32(tmp2, tmp2, shift);
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
27
- tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
29
flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
28
- tcg_gen_ext16u_i32(tmp2, tmp2);
30
sram_size = ((board->dc0 >> 18) + 1) * 1024;
29
+ tcg_gen_deposit_i32(tmp, tmp, tmp2, 0, 16);
31
30
} else {
32
+ soc_container = object_new("container");
31
/* pkhbt */
33
+ object_property_add_child(OBJECT(ms), "soc", soc_container);
32
- if (shift)
34
+
33
- tcg_gen_shli_i32(tmp2, tmp2, shift);
35
/* Flash programming is done via the SCU, so pretend it is ROM. */
34
- tcg_gen_ext16u_i32(tmp, tmp);
36
memory_region_init_rom(flash, NULL, "stellaris.flash", flash_size,
35
- tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
37
&error_fatal);
36
+ tcg_gen_shli_i32(tmp2, tmp2, shift);
38
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
37
+ tcg_gen_deposit_i32(tmp, tmp2, tmp, 0, 16);
39
* need its sysclk output.
38
}
40
*/
39
- tcg_gen_or_i32(tmp, tmp, tmp2);
41
ssys_dev = qdev_new(TYPE_STELLARIS_SYS);
40
tcg_temp_free_i32(tmp2);
42
+ object_property_add_child(soc_container, "sys", OBJECT(ssys_dev));
41
store_reg(s, rd, tmp);
43
42
} else if ((insn & 0x00200020) == 0x00200000) {
44
/*
43
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
45
* Most devices come preprogrammed with a MAC address in the user data.
44
shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
46
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
45
if (insn & (1 << 5)) {
47
sysbus_realize_and_unref(SYS_BUS_DEVICE(ssys_dev), &error_fatal);
46
/* pkhtb */
48
47
- if (shift == 0)
49
nvic = qdev_new(TYPE_ARMV7M);
48
+ if (shift == 0) {
50
+ object_property_add_child(soc_container, "v7m", OBJECT(nvic));
49
shift = 31;
51
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
50
+ }
52
qdev_prop_set_uint8(nvic, "num-prio-bits", NUM_PRIO_BITS);
51
tcg_gen_sari_i32(tmp2, tmp2, shift);
53
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
52
- tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
54
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
53
- tcg_gen_ext16u_i32(tmp2, tmp2);
55
54
+ tcg_gen_deposit_i32(tmp, tmp, tmp2, 0, 16);
56
dev = qdev_new(TYPE_STELLARIS_GPTM);
55
} else {
57
sbd = SYS_BUS_DEVICE(dev);
56
/* pkhbt */
58
+ object_property_add_child(soc_container, "gptm[*]", OBJECT(dev));
57
- if (shift)
59
qdev_connect_clock_in(dev, "clk",
58
- tcg_gen_shli_i32(tmp2, tmp2, shift);
60
qdev_get_clock_out(ssys_dev, "SYSCLK"));
59
- tcg_gen_ext16u_i32(tmp, tmp);
61
sysbus_realize_and_unref(sbd, &error_fatal);
60
- tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
62
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
61
+ tcg_gen_shli_i32(tmp2, tmp2, shift);
63
62
+ tcg_gen_deposit_i32(tmp, tmp2, tmp, 0, 16);
64
if (board->dc1 & (1 << 3)) { /* watchdog present */
63
}
65
dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
64
- tcg_gen_or_i32(tmp, tmp, tmp2);
66
-
65
tcg_temp_free_i32(tmp2);
67
+ object_property_add_child(soc_container, "wdg", OBJECT(dev));
66
store_reg(s, rd, tmp);
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);
67
} else {
86
} else {
68
--
87
--
69
2.20.1
88
2.34.1
70
89
71
90
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
We support two different encodings for the AArch32 IMPDEF
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.
2
5
3
The current implementation of ZCR_ELx matches the architecture, only
6
When we implemented this we picked which encoding to
4
implementing the lower four bits, with the rest RAZ/WI. This puts
7
use based on whether the CPU set ARM_FEATURE_AARCH64.
5
a strict limit on ARM_MAX_VQ of 16. Make sure we don't let ARM_MAX_VQ
8
However this isn't right for three cases:
6
grow without a corresponding update here.
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
7
19
8
Suggested-by: Dave Martin <Dave.Martin@arm.com>
20
Make the decision of the encoding be based on whether
9
Signed-off-by: Andrew Jones <drjones@redhat.com>
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
31
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Eric Auger <eric.auger@redhat.com>
34
Message-id: 20240206132931.38376-2-peter.maydell@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
35
---
14
target/arm/helper.c | 1 +
36
target/arm/helper.c | 2 +-
15
1 file changed, 1 insertion(+)
37
1 file changed, 1 insertion(+), 1 deletion(-)
16
38
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
41
--- a/target/arm/helper.c
20
+++ b/target/arm/helper.c
42
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
43
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
22
int new_len;
44
* AArch64 cores we might need to add a specific feature flag
23
45
* to indicate cores with "flavour 2" CBAR.
24
/* Bits other than [3:0] are RAZ/WI. */
46
*/
25
+ QEMU_BUILD_BUG_ON(ARM_MAX_VQ > 16);
47
- if (arm_feature(env, ARM_FEATURE_AARCH64)) {
26
raw_write(env, ri, value & 0xf);
48
+ if (arm_feature(env, ARM_FEATURE_V8)) {
27
49
/* 32 bit view is [31:18] 0...0 [43:32]. */
28
/*
50
uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18)
51
| extract64(cpu->reset_cbar, 32, 12);
29
--
52
--
30
2.20.1
53
2.34.1
31
32
diff view generated by jsdifflib
New patch
1
The Cortex-R52 implements the Configuration Base Address Register
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.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20240206132931.38376-3-peter.maydell@linaro.org
9
---
10
target/arm/tcg/cpu32.c | 1 +
11
1 file changed, 1 insertion(+)
12
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/tcg/cpu32.c
16
+++ b/target/arm/tcg/cpu32.c
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
18
set_feature(&cpu->env, ARM_FEATURE_PMSA);
19
set_feature(&cpu->env, ARM_FEATURE_NEON);
20
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
21
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
22
cpu->midr = 0x411fd133; /* r1p3 */
23
cpu->revidr = 0x00000000;
24
cpu->reset_fpsid = 0x41034023;
25
--
26
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Add the Cortex-R52 IMPDEF sysregs, by defining them here and
2
also by enabling the AUXCR feature which defines the ACTLR
3
and HACTLR registers. As is our usual practice, we make these
4
simple reads-as-zero stubs for now.
2
5
3
This function is used in two different contexts, and it will be
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
clearer if the function is given the address to which it applies.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20240206132931.38376-4-peter.maydell@linaro.org
9
---
10
target/arm/tcg/cpu32.c | 108 +++++++++++++++++++++++++++++++++++++++++
11
1 file changed, 108 insertions(+)
5
12
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190807045335.1361-2-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate.c | 14 +++++++-------
13
1 file changed, 7 insertions(+), 7 deletions(-)
14
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
15
--- a/target/arm/tcg/cpu32.c
18
+++ b/target/arm/translate.c
16
+++ b/target/arm/tcg/cpu32.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
20
}
18
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
21
}
19
}
22
20
23
-static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
21
+static const ARMCPRegInfo cortex_r52_cp_reginfo[] = {
24
+static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn)
22
+ { .name = "CPUACTLR", .cp = 15, .opc1 = 0, .crm = 15,
23
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
24
+ { .name = "IMP_ATCMREGIONR",
25
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
26
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
27
+ { .name = "IMP_BTCMREGIONR",
28
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
29
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
30
+ { .name = "IMP_CTCMREGIONR",
31
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 2,
32
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
33
+ { .name = "IMP_CSCTLR",
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
+};
124
+
125
+
126
static void cortex_r52_initfn(Object *obj)
25
{
127
{
26
- /* Return true if this is a 16 bit instruction. We must be precise
128
ARMCPU *cpu = ARM_CPU(obj);
27
- * about this (matching the decode). We assume that s->pc still
129
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
28
- * points to the first 16 bits of the insn.
130
set_feature(&cpu->env, ARM_FEATURE_NEON);
29
+ /*
131
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
30
+ * Return true if this is a 16 bit instruction. We must be precise
132
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
31
+ * about this (matching the decode).
133
+ set_feature(&cpu->env, ARM_FEATURE_AUXCR);
32
*/
134
cpu->midr = 0x411fd133; /* r1p3 */
33
if ((insn >> 11) < 0x1d) {
135
cpu->revidr = 0x00000000;
34
/* Definitely a 16-bit instruction */
136
cpu->reset_fpsid = 0x41034023;
35
@@ -XXX,XX +XXX,XX @@ static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
137
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
36
return false;
138
37
}
139
cpu->pmsav7_dregion = 16;
38
140
cpu->pmsav8r_hdregion = 16;
39
- if ((insn >> 11) == 0x1e && s->pc - s->page_start < TARGET_PAGE_SIZE - 3) {
141
+
40
+ if ((insn >> 11) == 0x1e && pc - s->page_start < TARGET_PAGE_SIZE - 3) {
142
+ define_arm_cp_regs(cpu, cortex_r52_cp_reginfo);
41
/* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
42
* is not on the next page; we merge this into a 32-bit
43
* insn.
44
@@ -XXX,XX +XXX,XX @@ static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
45
*/
46
uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
47
48
- return !thumb_insn_is_16bit(s, insn);
49
+ return !thumb_insn_is_16bit(s, s->pc, insn);
50
}
143
}
51
144
52
static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
145
static void cortex_r5f_initfn(Object *obj)
53
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
54
}
55
56
insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
57
- is_16bit = thumb_insn_is_16bit(dc, insn);
58
+ is_16bit = thumb_insn_is_16bit(dc, dc->pc, insn);
59
dc->pc += 2;
60
if (!is_16bit) {
61
uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
62
--
146
--
63
2.20.1
147
2.34.1
64
65
diff view generated by jsdifflib
1
From: Damien Hedde <damien.hedde@greensocs.com>
1
Architecturally, the AArch32 MSR/MRS to/from banked register
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.
2
6
3
Replace the zynq_slcr registers enum and macros using the
7
However, for the case of accessing SPSR_hyp from hyp mode, it turns
4
hw/registerfields.h macros.
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.
5
17
6
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
18
For convenience of being able to run guest code, permit
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
this UNPREDICTABLE access instead of UNDEFing it.
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
20
9
Message-id: 20190729145654.14644-30-damien.hedde@greensocs.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20240206132931.38376-5-peter.maydell@linaro.org
11
---
24
---
12
hw/misc/zynq_slcr.c | 450 ++++++++++++++++++++++----------------------
25
target/arm/tcg/op_helper.c | 43 ++++++++++++++++++++++++++------------
13
1 file changed, 225 insertions(+), 225 deletions(-)
26
target/arm/tcg/translate.c | 19 +++++++++++------
27
2 files changed, 43 insertions(+), 19 deletions(-)
14
28
15
diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
29
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
16
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/misc/zynq_slcr.c
31
--- a/target/arm/tcg/op_helper.c
18
+++ b/hw/misc/zynq_slcr.c
32
+++ b/target/arm/tcg/op_helper.c
19
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
20
#include "sysemu/sysemu.h"
34
*/
21
#include "qemu/log.h"
35
int curmode = env->uncached_cpsr & CPSR_M;
22
#include "qemu/module.h"
36
23
+#include "hw/registerfields.h"
37
- if (regno == 17) {
24
38
- /* ELR_Hyp: a special case because access from tgtmode is OK */
25
#ifndef ZYNQ_SLCR_ERR_DEBUG
39
- if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
26
#define ZYNQ_SLCR_ERR_DEBUG 0
40
- goto undef;
27
@@ -XXX,XX +XXX,XX @@
41
+ if (tgtmode == ARM_CPU_MODE_HYP) {
28
#define XILINX_LOCK_KEY 0x767b
42
+ /*
29
#define XILINX_UNLOCK_KEY 0xdf0d
43
+ * Handle Hyp target regs first because some are special cases
30
44
+ * which don't want the usual "not accessible from tgtmode" check.
31
-#define R_PSS_RST_CTRL_SOFT_RST 0x1
45
+ */
32
+REG32(SCL, 0x000)
46
+ switch (regno) {
33
+REG32(LOCK, 0x004)
47
+ case 16 ... 17: /* ELR_Hyp, SPSR_Hyp */
34
+REG32(UNLOCK, 0x008)
48
+ if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
35
+REG32(LOCKSTA, 0x00c)
49
+ goto undef;
36
50
+ }
37
-enum {
51
+ break;
38
- SCL = 0x000 / 4,
52
+ case 13:
39
- LOCK,
53
+ if (curmode != ARM_CPU_MODE_MON) {
40
- UNLOCK,
54
+ goto undef;
41
- LOCKSTA,
55
+ }
42
+REG32(ARM_PLL_CTRL, 0x100)
56
+ break;
43
+REG32(DDR_PLL_CTRL, 0x104)
57
+ default:
44
+REG32(IO_PLL_CTRL, 0x108)
58
+ g_assert_not_reached();
45
+REG32(PLL_STATUS, 0x10c)
46
+REG32(ARM_PLL_CFG, 0x110)
47
+REG32(DDR_PLL_CFG, 0x114)
48
+REG32(IO_PLL_CFG, 0x118)
49
50
- ARM_PLL_CTRL = 0x100 / 4,
51
- DDR_PLL_CTRL,
52
- IO_PLL_CTRL,
53
- PLL_STATUS,
54
- ARM_PLL_CFG,
55
- DDR_PLL_CFG,
56
- IO_PLL_CFG,
57
-
58
- ARM_CLK_CTRL = 0x120 / 4,
59
- DDR_CLK_CTRL,
60
- DCI_CLK_CTRL,
61
- APER_CLK_CTRL,
62
- USB0_CLK_CTRL,
63
- USB1_CLK_CTRL,
64
- GEM0_RCLK_CTRL,
65
- GEM1_RCLK_CTRL,
66
- GEM0_CLK_CTRL,
67
- GEM1_CLK_CTRL,
68
- SMC_CLK_CTRL,
69
- LQSPI_CLK_CTRL,
70
- SDIO_CLK_CTRL,
71
- UART_CLK_CTRL,
72
- SPI_CLK_CTRL,
73
- CAN_CLK_CTRL,
74
- CAN_MIOCLK_CTRL,
75
- DBG_CLK_CTRL,
76
- PCAP_CLK_CTRL,
77
- TOPSW_CLK_CTRL,
78
+REG32(ARM_CLK_CTRL, 0x120)
79
+REG32(DDR_CLK_CTRL, 0x124)
80
+REG32(DCI_CLK_CTRL, 0x128)
81
+REG32(APER_CLK_CTRL, 0x12c)
82
+REG32(USB0_CLK_CTRL, 0x130)
83
+REG32(USB1_CLK_CTRL, 0x134)
84
+REG32(GEM0_RCLK_CTRL, 0x138)
85
+REG32(GEM1_RCLK_CTRL, 0x13c)
86
+REG32(GEM0_CLK_CTRL, 0x140)
87
+REG32(GEM1_CLK_CTRL, 0x144)
88
+REG32(SMC_CLK_CTRL, 0x148)
89
+REG32(LQSPI_CLK_CTRL, 0x14c)
90
+REG32(SDIO_CLK_CTRL, 0x150)
91
+REG32(UART_CLK_CTRL, 0x154)
92
+REG32(SPI_CLK_CTRL, 0x158)
93
+REG32(CAN_CLK_CTRL, 0x15c)
94
+REG32(CAN_MIOCLK_CTRL, 0x160)
95
+REG32(DBG_CLK_CTRL, 0x164)
96
+REG32(PCAP_CLK_CTRL, 0x168)
97
+REG32(TOPSW_CLK_CTRL, 0x16c)
98
99
#define FPGA_CTRL_REGS(n, start) \
100
- FPGA ## n ## _CLK_CTRL = (start) / 4, \
101
- FPGA ## n ## _THR_CTRL, \
102
- FPGA ## n ## _THR_CNT, \
103
- FPGA ## n ## _THR_STA,
104
- FPGA_CTRL_REGS(0, 0x170)
105
- FPGA_CTRL_REGS(1, 0x180)
106
- FPGA_CTRL_REGS(2, 0x190)
107
- FPGA_CTRL_REGS(3, 0x1a0)
108
+ REG32(FPGA ## n ## _CLK_CTRL, (start)) \
109
+ REG32(FPGA ## n ## _THR_CTRL, (start) + 0x4)\
110
+ REG32(FPGA ## n ## _THR_CNT, (start) + 0x8)\
111
+ REG32(FPGA ## n ## _THR_STA, (start) + 0xc)
112
+FPGA_CTRL_REGS(0, 0x170)
113
+FPGA_CTRL_REGS(1, 0x180)
114
+FPGA_CTRL_REGS(2, 0x190)
115
+FPGA_CTRL_REGS(3, 0x1a0)
116
117
- BANDGAP_TRIP = 0x1b8 / 4,
118
- PLL_PREDIVISOR = 0x1c0 / 4,
119
- CLK_621_TRUE,
120
+REG32(BANDGAP_TRIP, 0x1b8)
121
+REG32(PLL_PREDIVISOR, 0x1c0)
122
+REG32(CLK_621_TRUE, 0x1c4)
123
124
- PSS_RST_CTRL = 0x200 / 4,
125
- DDR_RST_CTRL,
126
- TOPSW_RESET_CTRL,
127
- DMAC_RST_CTRL,
128
- USB_RST_CTRL,
129
- GEM_RST_CTRL,
130
- SDIO_RST_CTRL,
131
- SPI_RST_CTRL,
132
- CAN_RST_CTRL,
133
- I2C_RST_CTRL,
134
- UART_RST_CTRL,
135
- GPIO_RST_CTRL,
136
- LQSPI_RST_CTRL,
137
- SMC_RST_CTRL,
138
- OCM_RST_CTRL,
139
- FPGA_RST_CTRL = 0x240 / 4,
140
- A9_CPU_RST_CTRL,
141
+REG32(PSS_RST_CTRL, 0x200)
142
+ FIELD(PSS_RST_CTRL, SOFT_RST, 0, 1)
143
+REG32(DDR_RST_CTRL, 0x204)
144
+REG32(TOPSW_RESET_CTRL, 0x208)
145
+REG32(DMAC_RST_CTRL, 0x20c)
146
+REG32(USB_RST_CTRL, 0x210)
147
+REG32(GEM_RST_CTRL, 0x214)
148
+REG32(SDIO_RST_CTRL, 0x218)
149
+REG32(SPI_RST_CTRL, 0x21c)
150
+REG32(CAN_RST_CTRL, 0x220)
151
+REG32(I2C_RST_CTRL, 0x224)
152
+REG32(UART_RST_CTRL, 0x228)
153
+REG32(GPIO_RST_CTRL, 0x22c)
154
+REG32(LQSPI_RST_CTRL, 0x230)
155
+REG32(SMC_RST_CTRL, 0x234)
156
+REG32(OCM_RST_CTRL, 0x238)
157
+REG32(FPGA_RST_CTRL, 0x240)
158
+REG32(A9_CPU_RST_CTRL, 0x244)
159
160
- RS_AWDT_CTRL = 0x24c / 4,
161
- RST_REASON,
162
+REG32(RS_AWDT_CTRL, 0x24c)
163
+REG32(RST_REASON, 0x250)
164
165
- REBOOT_STATUS = 0x258 / 4,
166
- BOOT_MODE,
167
+REG32(REBOOT_STATUS, 0x258)
168
+REG32(BOOT_MODE, 0x25c)
169
170
- APU_CTRL = 0x300 / 4,
171
- WDT_CLK_SEL,
172
+REG32(APU_CTRL, 0x300)
173
+REG32(WDT_CLK_SEL, 0x304)
174
175
- TZ_DMA_NS = 0x440 / 4,
176
- TZ_DMA_IRQ_NS,
177
- TZ_DMA_PERIPH_NS,
178
+REG32(TZ_DMA_NS, 0x440)
179
+REG32(TZ_DMA_IRQ_NS, 0x444)
180
+REG32(TZ_DMA_PERIPH_NS, 0x448)
181
182
- PSS_IDCODE = 0x530 / 4,
183
+REG32(PSS_IDCODE, 0x530)
184
185
- DDR_URGENT = 0x600 / 4,
186
- DDR_CAL_START = 0x60c / 4,
187
- DDR_REF_START = 0x614 / 4,
188
- DDR_CMD_STA,
189
- DDR_URGENT_SEL,
190
- DDR_DFI_STATUS,
191
+REG32(DDR_URGENT, 0x600)
192
+REG32(DDR_CAL_START, 0x60c)
193
+REG32(DDR_REF_START, 0x614)
194
+REG32(DDR_CMD_STA, 0x618)
195
+REG32(DDR_URGENT_SEL, 0x61c)
196
+REG32(DDR_DFI_STATUS, 0x620)
197
198
- MIO = 0x700 / 4,
199
+REG32(MIO, 0x700)
200
#define MIO_LENGTH 54
201
202
- MIO_LOOPBACK = 0x804 / 4,
203
- MIO_MST_TRI0,
204
- MIO_MST_TRI1,
205
+REG32(MIO_LOOPBACK, 0x804)
206
+REG32(MIO_MST_TRI0, 0x808)
207
+REG32(MIO_MST_TRI1, 0x80c)
208
209
- SD0_WP_CD_SEL = 0x830 / 4,
210
- SD1_WP_CD_SEL,
211
+REG32(SD0_WP_CD_SEL, 0x830)
212
+REG32(SD1_WP_CD_SEL, 0x834)
213
214
- LVL_SHFTR_EN = 0x900 / 4,
215
- OCM_CFG = 0x910 / 4,
216
+REG32(LVL_SHFTR_EN, 0x900)
217
+REG32(OCM_CFG, 0x910)
218
219
- CPU_RAM = 0xa00 / 4,
220
+REG32(CPU_RAM, 0xa00)
221
222
- IOU = 0xa30 / 4,
223
+REG32(IOU, 0xa30)
224
225
- DMAC_RAM = 0xa50 / 4,
226
+REG32(DMAC_RAM, 0xa50)
227
228
- AFI0 = 0xa60 / 4,
229
- AFI1 = AFI0 + 3,
230
- AFI2 = AFI1 + 3,
231
- AFI3 = AFI2 + 3,
232
+REG32(AFI0, 0xa60)
233
+REG32(AFI1, 0xa6c)
234
+REG32(AFI2, 0xa78)
235
+REG32(AFI3, 0xa84)
236
#define AFI_LENGTH 3
237
238
- OCM = 0xa90 / 4,
239
+REG32(OCM, 0xa90)
240
241
- DEVCI_RAM = 0xaa0 / 4,
242
+REG32(DEVCI_RAM, 0xaa0)
243
244
- CSG_RAM = 0xab0 / 4,
245
+REG32(CSG_RAM, 0xab0)
246
247
- GPIOB_CTRL = 0xb00 / 4,
248
- GPIOB_CFG_CMOS18,
249
- GPIOB_CFG_CMOS25,
250
- GPIOB_CFG_CMOS33,
251
- GPIOB_CFG_HSTL = 0xb14 / 4,
252
- GPIOB_DRVR_BIAS_CTRL,
253
+REG32(GPIOB_CTRL, 0xb00)
254
+REG32(GPIOB_CFG_CMOS18, 0xb04)
255
+REG32(GPIOB_CFG_CMOS25, 0xb08)
256
+REG32(GPIOB_CFG_CMOS33, 0xb0c)
257
+REG32(GPIOB_CFG_HSTL, 0xb14)
258
+REG32(GPIOB_DRVR_BIAS_CTRL, 0xb18)
259
260
- DDRIOB = 0xb40 / 4,
261
+REG32(DDRIOB, 0xb40)
262
#define DDRIOB_LENGTH 14
263
-};
264
265
#define ZYNQ_SLCR_MMIO_SIZE 0x1000
266
#define ZYNQ_SLCR_NUM_REGS (ZYNQ_SLCR_MMIO_SIZE / 4)
267
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_reset(DeviceState *d)
268
269
DB_PRINT("RESET\n");
270
271
- s->regs[LOCKSTA] = 1;
272
+ s->regs[R_LOCKSTA] = 1;
273
/* 0x100 - 0x11C */
274
- s->regs[ARM_PLL_CTRL] = 0x0001A008;
275
- s->regs[DDR_PLL_CTRL] = 0x0001A008;
276
- s->regs[IO_PLL_CTRL] = 0x0001A008;
277
- s->regs[PLL_STATUS] = 0x0000003F;
278
- s->regs[ARM_PLL_CFG] = 0x00014000;
279
- s->regs[DDR_PLL_CFG] = 0x00014000;
280
- s->regs[IO_PLL_CFG] = 0x00014000;
281
+ s->regs[R_ARM_PLL_CTRL] = 0x0001A008;
282
+ s->regs[R_DDR_PLL_CTRL] = 0x0001A008;
283
+ s->regs[R_IO_PLL_CTRL] = 0x0001A008;
284
+ s->regs[R_PLL_STATUS] = 0x0000003F;
285
+ s->regs[R_ARM_PLL_CFG] = 0x00014000;
286
+ s->regs[R_DDR_PLL_CFG] = 0x00014000;
287
+ s->regs[R_IO_PLL_CFG] = 0x00014000;
288
289
/* 0x120 - 0x16C */
290
- s->regs[ARM_CLK_CTRL] = 0x1F000400;
291
- s->regs[DDR_CLK_CTRL] = 0x18400003;
292
- s->regs[DCI_CLK_CTRL] = 0x01E03201;
293
- s->regs[APER_CLK_CTRL] = 0x01FFCCCD;
294
- s->regs[USB0_CLK_CTRL] = s->regs[USB1_CLK_CTRL] = 0x00101941;
295
- s->regs[GEM0_RCLK_CTRL] = s->regs[GEM1_RCLK_CTRL] = 0x00000001;
296
- s->regs[GEM0_CLK_CTRL] = s->regs[GEM1_CLK_CTRL] = 0x00003C01;
297
- s->regs[SMC_CLK_CTRL] = 0x00003C01;
298
- s->regs[LQSPI_CLK_CTRL] = 0x00002821;
299
- s->regs[SDIO_CLK_CTRL] = 0x00001E03;
300
- s->regs[UART_CLK_CTRL] = 0x00003F03;
301
- s->regs[SPI_CLK_CTRL] = 0x00003F03;
302
- s->regs[CAN_CLK_CTRL] = 0x00501903;
303
- s->regs[DBG_CLK_CTRL] = 0x00000F03;
304
- s->regs[PCAP_CLK_CTRL] = 0x00000F01;
305
+ s->regs[R_ARM_CLK_CTRL] = 0x1F000400;
306
+ s->regs[R_DDR_CLK_CTRL] = 0x18400003;
307
+ s->regs[R_DCI_CLK_CTRL] = 0x01E03201;
308
+ s->regs[R_APER_CLK_CTRL] = 0x01FFCCCD;
309
+ s->regs[R_USB0_CLK_CTRL] = s->regs[R_USB1_CLK_CTRL] = 0x00101941;
310
+ s->regs[R_GEM0_RCLK_CTRL] = s->regs[R_GEM1_RCLK_CTRL] = 0x00000001;
311
+ s->regs[R_GEM0_CLK_CTRL] = s->regs[R_GEM1_CLK_CTRL] = 0x00003C01;
312
+ s->regs[R_SMC_CLK_CTRL] = 0x00003C01;
313
+ s->regs[R_LQSPI_CLK_CTRL] = 0x00002821;
314
+ s->regs[R_SDIO_CLK_CTRL] = 0x00001E03;
315
+ s->regs[R_UART_CLK_CTRL] = 0x00003F03;
316
+ s->regs[R_SPI_CLK_CTRL] = 0x00003F03;
317
+ s->regs[R_CAN_CLK_CTRL] = 0x00501903;
318
+ s->regs[R_DBG_CLK_CTRL] = 0x00000F03;
319
+ s->regs[R_PCAP_CLK_CTRL] = 0x00000F01;
320
321
/* 0x170 - 0x1AC */
322
- s->regs[FPGA0_CLK_CTRL] = s->regs[FPGA1_CLK_CTRL] = s->regs[FPGA2_CLK_CTRL]
323
- = s->regs[FPGA3_CLK_CTRL] = 0x00101800;
324
- s->regs[FPGA0_THR_STA] = s->regs[FPGA1_THR_STA] = s->regs[FPGA2_THR_STA]
325
- = s->regs[FPGA3_THR_STA] = 0x00010000;
326
+ s->regs[R_FPGA0_CLK_CTRL] = s->regs[R_FPGA1_CLK_CTRL]
327
+ = s->regs[R_FPGA2_CLK_CTRL]
328
+ = s->regs[R_FPGA3_CLK_CTRL] = 0x00101800;
329
+ s->regs[R_FPGA0_THR_STA] = s->regs[R_FPGA1_THR_STA]
330
+ = s->regs[R_FPGA2_THR_STA]
331
+ = s->regs[R_FPGA3_THR_STA] = 0x00010000;
332
333
/* 0x1B0 - 0x1D8 */
334
- s->regs[BANDGAP_TRIP] = 0x0000001F;
335
- s->regs[PLL_PREDIVISOR] = 0x00000001;
336
- s->regs[CLK_621_TRUE] = 0x00000001;
337
+ s->regs[R_BANDGAP_TRIP] = 0x0000001F;
338
+ s->regs[R_PLL_PREDIVISOR] = 0x00000001;
339
+ s->regs[R_CLK_621_TRUE] = 0x00000001;
340
341
/* 0x200 - 0x25C */
342
- s->regs[FPGA_RST_CTRL] = 0x01F33F0F;
343
- s->regs[RST_REASON] = 0x00000040;
344
+ s->regs[R_FPGA_RST_CTRL] = 0x01F33F0F;
345
+ s->regs[R_RST_REASON] = 0x00000040;
346
347
- s->regs[BOOT_MODE] = 0x00000001;
348
+ s->regs[R_BOOT_MODE] = 0x00000001;
349
350
/* 0x700 - 0x7D4 */
351
for (i = 0; i < 54; i++) {
352
- s->regs[MIO + i] = 0x00001601;
353
+ s->regs[R_MIO + i] = 0x00001601;
354
}
355
for (i = 2; i <= 8; i++) {
356
- s->regs[MIO + i] = 0x00000601;
357
+ s->regs[R_MIO + i] = 0x00000601;
358
}
359
360
- s->regs[MIO_MST_TRI0] = s->regs[MIO_MST_TRI1] = 0xFFFFFFFF;
361
+ s->regs[R_MIO_MST_TRI0] = s->regs[R_MIO_MST_TRI1] = 0xFFFFFFFF;
362
363
- s->regs[CPU_RAM + 0] = s->regs[CPU_RAM + 1] = s->regs[CPU_RAM + 3]
364
- = s->regs[CPU_RAM + 4] = s->regs[CPU_RAM + 7]
365
- = 0x00010101;
366
- s->regs[CPU_RAM + 2] = s->regs[CPU_RAM + 5] = 0x01010101;
367
- s->regs[CPU_RAM + 6] = 0x00000001;
368
+ s->regs[R_CPU_RAM + 0] = s->regs[R_CPU_RAM + 1] = s->regs[R_CPU_RAM + 3]
369
+ = s->regs[R_CPU_RAM + 4] = s->regs[R_CPU_RAM + 7]
370
+ = 0x00010101;
371
+ s->regs[R_CPU_RAM + 2] = s->regs[R_CPU_RAM + 5] = 0x01010101;
372
+ s->regs[R_CPU_RAM + 6] = 0x00000001;
373
374
- s->regs[IOU + 0] = s->regs[IOU + 1] = s->regs[IOU + 2] = s->regs[IOU + 3]
375
- = 0x09090909;
376
- s->regs[IOU + 4] = s->regs[IOU + 5] = 0x00090909;
377
- s->regs[IOU + 6] = 0x00000909;
378
+ s->regs[R_IOU + 0] = s->regs[R_IOU + 1] = s->regs[R_IOU + 2]
379
+ = s->regs[R_IOU + 3] = 0x09090909;
380
+ s->regs[R_IOU + 4] = s->regs[R_IOU + 5] = 0x00090909;
381
+ s->regs[R_IOU + 6] = 0x00000909;
382
383
- s->regs[DMAC_RAM] = 0x00000009;
384
+ s->regs[R_DMAC_RAM] = 0x00000009;
385
386
- s->regs[AFI0 + 0] = s->regs[AFI0 + 1] = 0x09090909;
387
- s->regs[AFI1 + 0] = s->regs[AFI1 + 1] = 0x09090909;
388
- s->regs[AFI2 + 0] = s->regs[AFI2 + 1] = 0x09090909;
389
- s->regs[AFI3 + 0] = s->regs[AFI3 + 1] = 0x09090909;
390
- s->regs[AFI0 + 2] = s->regs[AFI1 + 2] = s->regs[AFI2 + 2]
391
- = s->regs[AFI3 + 2] = 0x00000909;
392
+ s->regs[R_AFI0 + 0] = s->regs[R_AFI0 + 1] = 0x09090909;
393
+ s->regs[R_AFI1 + 0] = s->regs[R_AFI1 + 1] = 0x09090909;
394
+ s->regs[R_AFI2 + 0] = s->regs[R_AFI2 + 1] = 0x09090909;
395
+ s->regs[R_AFI3 + 0] = s->regs[R_AFI3 + 1] = 0x09090909;
396
+ s->regs[R_AFI0 + 2] = s->regs[R_AFI1 + 2] = s->regs[R_AFI2 + 2]
397
+ = s->regs[R_AFI3 + 2] = 0x00000909;
398
399
- s->regs[OCM + 0] = 0x01010101;
400
- s->regs[OCM + 1] = s->regs[OCM + 2] = 0x09090909;
401
+ s->regs[R_OCM + 0] = 0x01010101;
402
+ s->regs[R_OCM + 1] = s->regs[R_OCM + 2] = 0x09090909;
403
404
- s->regs[DEVCI_RAM] = 0x00000909;
405
- s->regs[CSG_RAM] = 0x00000001;
406
+ s->regs[R_DEVCI_RAM] = 0x00000909;
407
+ s->regs[R_CSG_RAM] = 0x00000001;
408
409
- s->regs[DDRIOB + 0] = s->regs[DDRIOB + 1] = s->regs[DDRIOB + 2]
410
- = s->regs[DDRIOB + 3] = 0x00000e00;
411
- s->regs[DDRIOB + 4] = s->regs[DDRIOB + 5] = s->regs[DDRIOB + 6]
412
- = 0x00000e00;
413
- s->regs[DDRIOB + 12] = 0x00000021;
414
+ s->regs[R_DDRIOB + 0] = s->regs[R_DDRIOB + 1] = s->regs[R_DDRIOB + 2]
415
+ = s->regs[R_DDRIOB + 3] = 0x00000e00;
416
+ s->regs[R_DDRIOB + 4] = s->regs[R_DDRIOB + 5] = s->regs[R_DDRIOB + 6]
417
+ = 0x00000e00;
418
+ s->regs[R_DDRIOB + 12] = 0x00000021;
419
}
420
421
422
static bool zynq_slcr_check_offset(hwaddr offset, bool rnw)
423
{
424
switch (offset) {
425
- case LOCK:
426
- case UNLOCK:
427
- case DDR_CAL_START:
428
- case DDR_REF_START:
429
+ case R_LOCK:
430
+ case R_UNLOCK:
431
+ case R_DDR_CAL_START:
432
+ case R_DDR_REF_START:
433
return !rnw; /* Write only */
434
- case LOCKSTA:
435
- case FPGA0_THR_STA:
436
- case FPGA1_THR_STA:
437
- case FPGA2_THR_STA:
438
- case FPGA3_THR_STA:
439
- case BOOT_MODE:
440
- case PSS_IDCODE:
441
- case DDR_CMD_STA:
442
- case DDR_DFI_STATUS:
443
- case PLL_STATUS:
444
+ case R_LOCKSTA:
445
+ case R_FPGA0_THR_STA:
446
+ case R_FPGA1_THR_STA:
447
+ case R_FPGA2_THR_STA:
448
+ case R_FPGA3_THR_STA:
449
+ case R_BOOT_MODE:
450
+ case R_PSS_IDCODE:
451
+ case R_DDR_CMD_STA:
452
+ case R_DDR_DFI_STATUS:
453
+ case R_PLL_STATUS:
454
return rnw;/* read only */
455
- case SCL:
456
- case ARM_PLL_CTRL ... IO_PLL_CTRL:
457
- case ARM_PLL_CFG ... IO_PLL_CFG:
458
- case ARM_CLK_CTRL ... TOPSW_CLK_CTRL:
459
- case FPGA0_CLK_CTRL ... FPGA0_THR_CNT:
460
- case FPGA1_CLK_CTRL ... FPGA1_THR_CNT:
461
- case FPGA2_CLK_CTRL ... FPGA2_THR_CNT:
462
- case FPGA3_CLK_CTRL ... FPGA3_THR_CNT:
463
- case BANDGAP_TRIP:
464
- case PLL_PREDIVISOR:
465
- case CLK_621_TRUE:
466
- case PSS_RST_CTRL ... A9_CPU_RST_CTRL:
467
- case RS_AWDT_CTRL:
468
- case RST_REASON:
469
- case REBOOT_STATUS:
470
- case APU_CTRL:
471
- case WDT_CLK_SEL:
472
- case TZ_DMA_NS ... TZ_DMA_PERIPH_NS:
473
- case DDR_URGENT:
474
- case DDR_URGENT_SEL:
475
- case MIO ... MIO + MIO_LENGTH - 1:
476
- case MIO_LOOPBACK ... MIO_MST_TRI1:
477
- case SD0_WP_CD_SEL:
478
- case SD1_WP_CD_SEL:
479
- case LVL_SHFTR_EN:
480
- case OCM_CFG:
481
- case CPU_RAM:
482
- case IOU:
483
- case DMAC_RAM:
484
- case AFI0 ... AFI3 + AFI_LENGTH - 1:
485
- case OCM:
486
- case DEVCI_RAM:
487
- case CSG_RAM:
488
- case GPIOB_CTRL ... GPIOB_CFG_CMOS33:
489
- case GPIOB_CFG_HSTL:
490
- case GPIOB_DRVR_BIAS_CTRL:
491
- case DDRIOB ... DDRIOB + DDRIOB_LENGTH - 1:
492
+ case R_SCL:
493
+ case R_ARM_PLL_CTRL ... R_IO_PLL_CTRL:
494
+ case R_ARM_PLL_CFG ... R_IO_PLL_CFG:
495
+ case R_ARM_CLK_CTRL ... R_TOPSW_CLK_CTRL:
496
+ case R_FPGA0_CLK_CTRL ... R_FPGA0_THR_CNT:
497
+ case R_FPGA1_CLK_CTRL ... R_FPGA1_THR_CNT:
498
+ case R_FPGA2_CLK_CTRL ... R_FPGA2_THR_CNT:
499
+ case R_FPGA3_CLK_CTRL ... R_FPGA3_THR_CNT:
500
+ case R_BANDGAP_TRIP:
501
+ case R_PLL_PREDIVISOR:
502
+ case R_CLK_621_TRUE:
503
+ case R_PSS_RST_CTRL ... R_A9_CPU_RST_CTRL:
504
+ case R_RS_AWDT_CTRL:
505
+ case R_RST_REASON:
506
+ case R_REBOOT_STATUS:
507
+ case R_APU_CTRL:
508
+ case R_WDT_CLK_SEL:
509
+ case R_TZ_DMA_NS ... R_TZ_DMA_PERIPH_NS:
510
+ case R_DDR_URGENT:
511
+ case R_DDR_URGENT_SEL:
512
+ case R_MIO ... R_MIO + MIO_LENGTH - 1:
513
+ case R_MIO_LOOPBACK ... R_MIO_MST_TRI1:
514
+ case R_SD0_WP_CD_SEL:
515
+ case R_SD1_WP_CD_SEL:
516
+ case R_LVL_SHFTR_EN:
517
+ case R_OCM_CFG:
518
+ case R_CPU_RAM:
519
+ case R_IOU:
520
+ case R_DMAC_RAM:
521
+ case R_AFI0 ... R_AFI3 + AFI_LENGTH - 1:
522
+ case R_OCM:
523
+ case R_DEVCI_RAM:
524
+ case R_CSG_RAM:
525
+ case R_GPIOB_CTRL ... R_GPIOB_CFG_CMOS33:
526
+ case R_GPIOB_CFG_HSTL:
527
+ case R_GPIOB_DRVR_BIAS_CTRL:
528
+ case R_DDRIOB ... R_DDRIOB + DDRIOB_LENGTH - 1:
529
return true;
530
default:
531
return false;
532
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_write(void *opaque, hwaddr offset,
533
}
534
535
switch (offset) {
536
- case SCL:
537
- s->regs[SCL] = val & 0x1;
538
+ case R_SCL:
539
+ s->regs[R_SCL] = val & 0x1;
540
return;
541
- case LOCK:
542
+ case R_LOCK:
543
if ((val & 0xFFFF) == XILINX_LOCK_KEY) {
544
DB_PRINT("XILINX LOCK 0xF8000000 + 0x%x <= 0x%x\n", (int)offset,
545
(unsigned)val & 0xFFFF);
546
- s->regs[LOCKSTA] = 1;
547
+ s->regs[R_LOCKSTA] = 1;
548
} else {
549
DB_PRINT("WRONG XILINX LOCK KEY 0xF8000000 + 0x%x <= 0x%x\n",
550
(int)offset, (unsigned)val & 0xFFFF);
551
}
59
}
552
return;
60
return;
553
- case UNLOCK:
554
+ case R_UNLOCK:
555
if ((val & 0xFFFF) == XILINX_UNLOCK_KEY) {
556
DB_PRINT("XILINX UNLOCK 0xF8000000 + 0x%x <= 0x%x\n", (int)offset,
557
(unsigned)val & 0xFFFF);
558
- s->regs[LOCKSTA] = 0;
559
+ s->regs[R_LOCKSTA] = 0;
560
} else {
561
DB_PRINT("WRONG XILINX UNLOCK KEY 0xF8000000 + 0x%x <= 0x%x\n",
562
(int)offset, (unsigned)val & 0xFFFF);
563
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_write(void *opaque, hwaddr offset,
564
return;
565
}
61
}
566
62
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
567
- if (s->regs[LOCKSTA]) {
63
}
568
+ if (s->regs[R_LOCKSTA]) {
64
}
569
qemu_log_mask(LOG_GUEST_ERROR,
65
570
"SCLR registers are locked. Unlock them first\n");
66
- if (tgtmode == ARM_CPU_MODE_HYP) {
571
return;
67
- /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
572
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_write(void *opaque, hwaddr offset,
68
- if (curmode != ARM_CPU_MODE_MON) {
573
s->regs[offset] = val;
69
- goto undef;
574
70
- }
575
switch (offset) {
71
- }
576
- case PSS_RST_CTRL:
72
-
577
- if (val & R_PSS_RST_CTRL_SOFT_RST) {
73
return;
578
+ case R_PSS_RST_CTRL:
74
579
+ if (FIELD_EX32(val, PSS_RST_CTRL, SOFT_RST)) {
75
undef:
580
qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
76
@@ -XXX,XX +XXX,XX @@ void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
77
78
switch (regno) {
79
case 16: /* SPSRs */
80
- env->banked_spsr[bank_number(tgtmode)] = value;
81
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
82
+ /* Only happens for SPSR_Hyp access in Hyp mode */
83
+ env->spsr = value;
84
+ } else {
85
+ env->banked_spsr[bank_number(tgtmode)] = value;
86
+ }
87
break;
88
case 17: /* ELR_Hyp */
89
env->elr_el[2] = value;
90
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
91
92
switch (regno) {
93
case 16: /* SPSRs */
94
- return env->banked_spsr[bank_number(tgtmode)];
95
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
96
+ /* Only happens for SPSR_Hyp access in Hyp mode */
97
+ return env->spsr;
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;
581
}
133
}
582
break;
134
break;
583
--
135
--
584
2.20.1
136
2.34.1
585
586
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
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
Unless we're guaranteed to always increase ARM_MAX_VQ by a multiple of
5
This register is present on all board types except AN524
4
four, then we should use DIV_ROUND_UP to ensure we get an appropriate
6
and AN527; correct the condition.
5
array size.
6
7
7
Signed-off-by: Andrew Jones <drjones@redhat.com>
8
Fixes: 6ac80818941829c0 ("hw/misc/mps2-scc: Implement changes for AN547")
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20240206132931.38376-6-peter.maydell@linaro.org
10
---
13
---
11
target/arm/cpu.h | 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/target/arm/cpu.h b/target/arm/cpu.h
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/target/arm/cpu.h
19
--- a/hw/misc/mps2-scc.c
17
+++ b/target/arm/cpu.h
20
+++ b/hw/misc/mps2-scc.c
18
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVectorReg {
21
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
19
#ifdef TARGET_AARCH64
22
r = s->cfg2;
20
/* In AArch32 mode, predicate registers do not exist at all. */
23
break;
21
typedef struct ARMPredicateReg {
24
case A_CFG3:
22
- uint64_t p[2 * ARM_MAX_VQ / 8] QEMU_ALIGNED(16);
25
- if (scc_partno(s) == 0x524 && scc_partno(s) == 0x547) {
23
+ uint64_t p[DIV_ROUND_UP(2 * ARM_MAX_VQ, 8)] QEMU_ALIGNED(16);
26
+ if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
24
} ARMPredicateReg;
27
/* CFG3 reserved on AN524 */
25
28
goto bad_offset;
26
/* In AArch32 mode, PAC keys do not exist at all. */
29
}
27
--
30
--
28
2.20.1
31
2.34.1
29
32
30
33
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
The MPS SCC device has a lot of different flavours for the various
2
different MPS FPGA images, which look mostly similar but have
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.
2
6
3
We first convert the pmu property from a static property to one with
7
Factor out the conditions into some functions which we can
4
its own accessors. Then we use the set accessor to check if the PMU is
8
give more descriptive names to.
5
supported when using KVM. Indeed a 32-bit KVM host does not support
6
the PMU, so this check will catch an attempt to use it at property-set
7
time.
8
9
9
Signed-off-by: Andrew Jones <drjones@redhat.com>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
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>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20240206132931.38376-7-peter.maydell@linaro.org
12
---
14
---
13
target/arm/kvm_arm.h | 14 ++++++++++++++
15
hw/misc/mps2-scc.c | 45 +++++++++++++++++++++++++++++++--------------
14
target/arm/cpu.c | 30 +++++++++++++++++++++++++-----
16
1 file changed, 31 insertions(+), 14 deletions(-)
15
target/arm/kvm.c | 7 +++++++
16
3 files changed, 46 insertions(+), 5 deletions(-)
17
17
18
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
18
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/kvm_arm.h
20
--- a/hw/misc/mps2-scc.c
21
+++ b/target/arm/kvm_arm.h
21
+++ b/hw/misc/mps2-scc.c
22
@@ -XXX,XX +XXX,XX @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
22
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
23
*/
23
return extract32(s->id, 4, 8);
24
bool kvm_arm_aarch32_supported(CPUState *cs);
25
26
+/**
27
+ * bool kvm_arm_pmu_supported:
28
+ * @cs: CPUState
29
+ *
30
+ * Returns: true if the KVM VCPU can enable its PMU
31
+ * and false otherwise.
32
+ */
33
+bool kvm_arm_pmu_supported(CPUState *cs);
34
+
35
/**
36
* kvm_arm_get_max_vm_ipa_size - Returns the number of bits in the
37
* IPA address space supported by KVM
38
@@ -XXX,XX +XXX,XX @@ static inline bool kvm_arm_aarch32_supported(CPUState *cs)
39
return false;
40
}
24
}
41
25
42
+static inline bool kvm_arm_pmu_supported(CPUState *cs)
26
+/* Is CFG_REG2 present? */
27
+static bool have_cfg2(MPS2SCC *s)
43
+{
28
+{
44
+ return false;
29
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
45
+}
30
+}
46
+
31
+
47
static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
32
+/* Is CFG_REG3 present? */
48
{
33
+static bool have_cfg3(MPS2SCC *s)
49
return -ENOENT;
50
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/cpu.c
53
+++ b/target/arm/cpu.c
54
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_has_el3_property =
55
static Property arm_cpu_cfgend_property =
56
DEFINE_PROP_BOOL("cfgend", ARMCPU, cfgend, false);
57
58
-/* use property name "pmu" to match other archs and virt tools */
59
-static Property arm_cpu_has_pmu_property =
60
- DEFINE_PROP_BOOL("pmu", ARMCPU, has_pmu, true);
61
-
62
static Property arm_cpu_has_vfp_property =
63
DEFINE_PROP_BOOL("vfp", ARMCPU, has_vfp, true);
64
65
@@ -XXX,XX +XXX,XX @@ static Property arm_cpu_pmsav7_dregion_property =
66
pmsav7_dregion,
67
qdev_prop_uint32, uint32_t);
68
69
+static bool arm_get_pmu(Object *obj, Error **errp)
70
+{
34
+{
71
+ ARMCPU *cpu = ARM_CPU(obj);
35
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
72
+
73
+ return cpu->has_pmu;
74
+}
36
+}
75
+
37
+
76
+static void arm_set_pmu(Object *obj, bool value, Error **errp)
38
+/* Is CFG_REG5 present? */
39
+static bool have_cfg5(MPS2SCC *s)
77
+{
40
+{
78
+ ARMCPU *cpu = ARM_CPU(obj);
41
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
79
+
80
+ if (value) {
81
+ if (kvm_enabled() && !kvm_arm_pmu_supported(CPU(cpu))) {
82
+ error_setg(errp, "'pmu' feature not supported by KVM on this host");
83
+ return;
84
+ }
85
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
86
+ } else {
87
+ unset_feature(&cpu->env, ARM_FEATURE_PMU);
88
+ }
89
+ cpu->has_pmu = value;
90
+}
42
+}
91
+
43
+
92
static void arm_get_init_svtor(Object *obj, Visitor *v, const char *name,
44
+/* Is CFG_REG6 present? */
93
void *opaque, Error **errp)
45
+static bool have_cfg6(MPS2SCC *s)
94
{
95
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
96
}
97
98
if (arm_feature(&cpu->env, ARM_FEATURE_PMU)) {
99
- qdev_property_add_static(DEVICE(obj), &arm_cpu_has_pmu_property,
100
+ cpu->has_pmu = true;
101
+ object_property_add_bool(obj, "pmu", arm_get_pmu, arm_set_pmu,
102
&error_abort);
103
}
104
105
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/kvm.c
108
+++ b/target/arm/kvm.c
109
@@ -XXX,XX +XXX,XX @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
110
env->features = arm_host_cpu_features.features;
111
}
112
113
+bool kvm_arm_pmu_supported(CPUState *cpu)
114
+{
46
+{
115
+ KVMState *s = KVM_STATE(current_machine->accelerator);
47
+ return scc_partno(s) == 0x524;
116
+
117
+ return kvm_check_extension(s, KVM_CAP_ARM_PMU_V3);
118
+}
48
+}
119
+
49
+
120
int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
50
/* Handle a write via the SYS_CFG channel to the specified function/device.
121
{
51
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
122
KVMState *s = KVM_STATE(ms->accelerator);
52
*/
53
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
54
r = s->cfg1;
55
break;
56
case A_CFG2:
57
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
58
- /* CFG2 reserved on other boards */
59
+ if (!have_cfg2(s)) {
60
goto bad_offset;
61
}
62
r = s->cfg2;
63
break;
64
case A_CFG3:
65
- if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
66
- /* CFG3 reserved on AN524 */
67
+ if (!have_cfg3(s)) {
68
goto bad_offset;
69
}
70
/* These are user-settable DIP switches on the board. We don't
71
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
72
r = s->cfg4;
73
break;
74
case A_CFG5:
75
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
76
- /* CFG5 reserved on other boards */
77
+ if (!have_cfg5(s)) {
78
goto bad_offset;
79
}
80
r = s->cfg5;
81
break;
82
case A_CFG6:
83
- if (scc_partno(s) != 0x524) {
84
- /* CFG6 reserved on other boards */
85
+ if (!have_cfg6(s)) {
86
goto bad_offset;
87
}
88
r = s->cfg6;
89
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
90
}
91
break;
92
case A_CFG2:
93
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
94
- /* CFG2 reserved on other boards */
95
+ if (!have_cfg2(s)) {
96
goto bad_offset;
97
}
98
/* AN524: QSPI Select signal */
99
s->cfg2 = value;
100
break;
101
case A_CFG5:
102
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
103
- /* CFG5 reserved on other boards */
104
+ if (!have_cfg5(s)) {
105
goto bad_offset;
106
}
107
/* AN524: ACLK frequency in Hz */
108
s->cfg5 = value;
109
break;
110
case A_CFG6:
111
- if (scc_partno(s) != 0x524) {
112
- /* CFG6 reserved on other boards */
113
+ if (!have_cfg6(s)) {
114
goto bad_offset;
115
}
116
/* AN524: Clock divider for BRAM */
123
--
117
--
124
2.20.1
118
2.34.1
125
119
126
120
diff view generated by jsdifflib
New patch
1
1
The MPS2 SCC device is broadly the same for all FPGA images, but has
2
minor differences in the behaviour of the CFG registers depending on
3
the image. In many cases we don't really care about the functionality
4
controlled by these registers and a reads-as-written or similar
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.
34
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
36
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
37
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
38
Message-id: 20240206132931.38376-8-peter.maydell@linaro.org
39
---
40
include/hw/misc/mps2-scc.h | 1 +
41
hw/misc/mps2-scc.c | 101 +++++++++++++++++++++++++++++++++----
42
2 files changed, 92 insertions(+), 10 deletions(-)
43
44
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/include/hw/misc/mps2-scc.h
47
+++ b/include/hw/misc/mps2-scc.h
48
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
49
uint32_t cfg4;
50
uint32_t cfg5;
51
uint32_t cfg6;
52
+ uint32_t cfg7;
53
uint32_t cfgdata_rtn;
54
uint32_t cfgdata_out;
55
uint32_t cfgctrl;
56
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/misc/mps2-scc.c
59
+++ b/hw/misc/mps2-scc.c
60
@@ -XXX,XX +XXX,XX @@ REG32(CFG3, 0xc)
61
REG32(CFG4, 0x10)
62
REG32(CFG5, 0x14)
63
REG32(CFG6, 0x18)
64
+REG32(CFG7, 0x1c)
65
REG32(CFGDATA_RTN, 0xa0)
66
REG32(CFGDATA_OUT, 0xa4)
67
REG32(CFGCTRL, 0xa8)
68
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
69
/* Is CFG_REG2 present? */
70
static bool have_cfg2(MPS2SCC *s)
71
{
72
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
73
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
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
247
}
248
};
249
250
--
251
2.34.1
252
253
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
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
If -cpu <cpu>,aarch64=off is used then KVM must also be used, and it
3
family CPU, and it does not use any equivalent to the M-profile
4
and the host must support running the vcpu in 32-bit mode. Also, if
4
"Subsystem for Embedded" SoC-equivalent that we model in hw/arm/armsse.c.
5
-cpu <cpu>,aarch64=on is used, then it doesn't matter if kvm is
5
It's therefore more convenient for us to model it as a completely
6
enabled or not.
6
separate C file.
7
7
8
Signed-off-by: Andrew Jones <drjones@redhat.com>
8
This commit adds the basic skeleton of the board model, and the
9
Reviewed-by: Eric Auger <eric.auger@redhat.com>
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
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Message-id: 20240206132931.38376-9-peter.maydell@linaro.org
11
---
19
---
12
target/arm/kvm_arm.h | 14 ++++++++++++++
20
MAINTAINERS | 3 +-
13
target/arm/cpu64.c | 12 ++++++------
21
configs/devices/arm-softmmu/default.mak | 1 +
14
target/arm/kvm64.c | 9 +++++++++
22
hw/arm/mps3r.c | 239 ++++++++++++++++++++++++
15
3 files changed, 29 insertions(+), 6 deletions(-)
23
hw/arm/Kconfig | 5 +
16
24
hw/arm/meson.build | 1 +
17
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
25
5 files changed, 248 insertions(+), 1 deletion(-)
26
create mode 100644 hw/arm/mps3r.c
27
28
diff --git a/MAINTAINERS b/MAINTAINERS
18
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/kvm_arm.h
30
--- a/MAINTAINERS
20
+++ b/target/arm/kvm_arm.h
31
+++ b/MAINTAINERS
21
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf);
32
@@ -XXX,XX +XXX,XX @@ F: include/hw/misc/imx7_*.h
22
*/
33
F: hw/pci-host/designware.c
23
void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
34
F: include/hw/pci-host/designware.h
24
35
25
+/**
36
-MPS2
26
+ * kvm_arm_aarch32_supported:
37
+MPS2 / MPS3
27
+ * @cs: CPUState
38
M: Peter Maydell <peter.maydell@linaro.org>
39
L: qemu-arm@nongnu.org
40
S: Maintained
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.)
28
+ *
68
+ *
29
+ * Returns: true if the KVM VCPU can enable AArch32 mode
69
+ * Copyright (c) 2017 Linaro Limited
30
+ * and false otherwise.
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.
31
+ */
75
+ */
32
+bool kvm_arm_aarch32_supported(CPUState *cs);
76
+
33
+
77
+/*
34
/**
78
+ * The MPS3 is an FPGA based dev board. This file handles FPGA images
35
* kvm_arm_get_max_vm_ipa_size - Returns the number of bits in the
79
+ * which use the Cortex-R CPUs. We model these separately from the
36
* IPA address space supported by KVM
80
+ * M-profile images, because on M-profile the FPGA image is based on
37
@@ -XXX,XX +XXX,XX @@ static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
81
+ * a "Subsystem for Embedded" which is similar to an SoC, whereas
38
cpu->host_cpu_probe_failed = true;
82
+ * the R-profile FPGA images don't have that abstraction layer.
39
}
83
+ *
40
84
+ * We model the following FPGA images here:
41
+static inline bool kvm_arm_aarch32_supported(CPUState *cs)
85
+ * "mps3-an536" -- dual Cortex-R52 as documented in Arm Application Note AN536
42
+{
86
+ *
43
+ return false;
87
+ * Application Note AN536:
44
+}
88
+ * https://developer.arm.com/documentation/dai0536/latest/
45
+
89
+ */
46
static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
90
+
47
{
91
+#include "qemu/osdep.h"
48
return -ENOENT;
92
+#include "qemu/units.h"
49
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
93
+#include "qapi/error.h"
50
index XXXXXXX..XXXXXXX 100644
94
+#include "exec/address-spaces.h"
51
--- a/target/arm/cpu64.c
95
+#include "cpu.h"
52
+++ b/target/arm/cpu64.c
96
+#include "hw/boards.h"
53
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_set_aarch64(Object *obj, bool value, Error **errp)
97
+#include "hw/arm/boot.h"
54
* restriction allows us to avoid fixing up functionality that assumes a
98
+
55
* uniform execution state like do_interrupt.
99
+/* Define the layout of RAM and ROM in a board */
56
*/
100
+typedef struct RAMInfo {
57
- if (!kvm_enabled()) {
101
+ const char *name;
58
- error_setg(errp, "'aarch64' feature cannot be disabled "
102
+ hwaddr base;
59
- "unless KVM is enabled");
103
+ hwaddr size;
60
- return;
104
+ int mrindex; /* index into rams[]; -1 for the system RAM block */
61
- }
105
+ int flags;
62
-
106
+} RAMInfo;
63
if (value == false) {
107
+
64
+ if (!kvm_enabled() || !kvm_arm_aarch32_supported(CPU(cpu))) {
108
+/*
65
+ error_setg(errp, "'aarch64' feature cannot be disabled "
109
+ * The MPS3 DDR is 3GiB, but on a 32-bit host QEMU doesn't permit
66
+ "unless KVM is enabled and 32-bit EL1 "
110
+ * emulation of that much guest RAM, so artificially make it smaller.
67
+ "is supported");
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;
68
+ return;
256
+ return;
69
+ }
257
+ }
70
unset_feature(&cpu->env, ARM_FEATURE_AARCH64);
258
+ }
71
} else {
259
+ g_assert_not_reached();
72
set_feature(&cpu->env, ARM_FEATURE_AARCH64);
260
+}
73
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
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
74
index XXXXXXX..XXXXXXX 100644
305
index XXXXXXX..XXXXXXX 100644
75
--- a/target/arm/kvm64.c
306
--- a/hw/arm/Kconfig
76
+++ b/target/arm/kvm64.c
307
+++ b/hw/arm/Kconfig
77
@@ -XXX,XX +XXX,XX @@
308
@@ -XXX,XX +XXX,XX @@ config MAINSTONE
78
#include "exec/gdbstub.h"
309
select PFLASH_CFI01
79
#include "sysemu/sysemu.h"
310
select SMC91C111
80
#include "sysemu/kvm.h"
311
81
+#include "sysemu/kvm_int.h"
312
+config MPS3R
82
#include "kvm_arm.h"
313
+ bool
83
+#include "hw/boards.h"
314
+ default y
84
#include "internals.h"
315
+ depends on TCG && ARM
85
316
+
86
static bool have_guest_debug;
317
config MUSCA
87
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
318
bool
88
return true;
319
default y
89
}
320
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
90
321
index XXXXXXX..XXXXXXX 100644
91
+bool kvm_arm_aarch32_supported(CPUState *cpu)
322
--- a/hw/arm/meson.build
92
+{
323
+++ b/hw/arm/meson.build
93
+ KVMState *s = KVM_STATE(current_machine->accelerator);
324
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_HIGHBANK', if_true: files('highbank.c'))
94
+
325
arm_ss.add(when: 'CONFIG_INTEGRATOR', if_true: files('integratorcp.c'))
95
+ return kvm_check_extension(s, KVM_CAP_ARM_EL1_32BIT);
326
arm_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mainstone.c'))
96
+}
327
arm_ss.add(when: 'CONFIG_MICROBIT', if_true: files('microbit.c'))
97
+
328
+arm_ss.add(when: 'CONFIG_MPS3R', if_true: files('mps3r.c'))
98
#define ARM_CPU_ID_MPIDR 3, 0, 0, 0, 5
329
arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
99
330
arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c'))
100
int kvm_arch_init_vcpu(CPUState *cs)
331
arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c'))
101
--
332
--
102
2.20.1
333
2.34.1
103
334
104
335
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
Create the CPUs, the GIC, and the per-CPU RAM block for
2
the mps3-an536 board.
2
3
3
Move the getting/putting of the fpsimd registers out of
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
kvm_arch_get/put_registers() into their own helper functions
5
Message-id: 20240206132931.38376-10-peter.maydell@linaro.org
5
to prepare for alternatively getting/putting SVE registers.
6
---
7
hw/arm/mps3r.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++++-
8
1 file changed, 177 insertions(+), 3 deletions(-)
6
9
7
No functional change.
10
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
8
9
Signed-off-by: Andrew Jones <drjones@redhat.com>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/kvm64.c | 148 +++++++++++++++++++++++++++------------------
15
1 file changed, 88 insertions(+), 60 deletions(-)
16
17
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
18
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/kvm64.c
12
--- a/hw/arm/mps3r.c
20
+++ b/target/arm/kvm64.c
13
+++ b/hw/arm/mps3r.c
21
@@ -XXX,XX +XXX,XX @@ int kvm_arm_cpreg_level(uint64_t regidx)
14
@@ -XXX,XX +XXX,XX @@
22
#define AARCH64_SIMD_CTRL_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U32 | \
15
#include "qemu/osdep.h"
23
KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
16
#include "qemu/units.h"
24
17
#include "qapi/error.h"
25
+static int kvm_arch_put_fpsimd(CPUState *cs)
18
+#include "qapi/qmp/qlist.h"
19
#include "exec/address-spaces.h"
20
#include "cpu.h"
21
#include "hw/boards.h"
22
+#include "hw/qdev-properties.h"
23
#include "hw/arm/boot.h"
24
+#include "hw/arm/bsa.h"
25
+#include "hw/intc/arm_gicv3.h"
26
27
/* Define the layout of RAM and ROM in a board */
28
typedef struct RAMInfo {
29
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
30
#define IS_ROM 2
31
32
#define MPS3R_RAM_MAX 9
33
+#define MPS3R_CPU_MAX 2
34
+
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;
61
}
62
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)
26
+{
78
+{
27
+ ARMCPU *cpu = ARM_CPU(cs);
79
+ /*
28
+ CPUARMState *env = &cpu->env;
80
+ * Power the secondary CPU off. This means we don't need to write any
29
+ struct kvm_one_reg reg;
81
+ * boot code into guest memory. Note that the 'cpu' argument to this
30
+ uint32_t fpr;
82
+ * function is the primary CPU we passed to arm_load_kernel(), not
31
+ int i, ret;
83
+ * the secondary. Loop around all the other CPUs, as the boot.c
32
+
84
+ * code does for the "disable secondaries if PSCI is enabled" case.
33
+ for (i = 0; i < 32; i++) {
85
+ */
34
+ uint64_t *q = aa64_vfp_qreg(env, i);
86
+ for (CPUState *cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
35
+#ifdef HOST_WORDS_BIGENDIAN
87
+ if (cs != first_cpu) {
36
+ uint64_t fp_val[2] = { q[1], q[0] };
88
+ object_property_set_bool(OBJECT(cs), "start-powered-off", true,
37
+ reg.addr = (uintptr_t)fp_val;
89
+ &error_abort);
38
+#else
39
+ reg.addr = (uintptr_t)q;
40
+#endif
41
+ reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
42
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
43
+ if (ret) {
44
+ return ret;
45
+ }
90
+ }
46
+ }
91
+ }
47
+
92
+}
48
+ reg.addr = (uintptr_t)(&fpr);
93
+
49
+ fpr = vfp_get_fpsr(env);
94
+static void mps3r_secondary_cpu_reset(ARMCPU *cpu,
50
+ reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
95
+ const struct arm_boot_info *info)
51
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
96
+{
52
+ if (ret) {
97
+ /* We don't need to do anything here because the CPU will be off */
53
+ return ret;
98
+}
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));
54
+ }
161
+ }
55
+
162
+}
56
+ reg.addr = (uintptr_t)(&fpr);
163
+
57
+ fpr = vfp_get_fpcr(env);
164
static void mps3r_common_init(MachineState *machine)
58
+ reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
165
{
59
+ ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
166
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
60
+ if (ret) {
167
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
61
+ return ret;
168
MemoryRegion *mr = mr_for_raminfo(mms, ri);
169
memory_region_add_subregion(sysmem, ri->base, mr);
170
}
171
+
172
+ assert(machine->smp.cpus <= MPS3R_CPU_MAX);
173
+ for (int i = 0; i < machine->smp.cpus; i++) {
174
+ g_autofree char *sysmem_name = g_strdup_printf("cpu-%d-memory", i);
175
+ g_autofree char *ramname = g_strdup_printf("cpu-%d-memory", i);
176
+ g_autofree char *alias_name = g_strdup_printf("sysmem-alias-%d", i);
177
+
178
+ /*
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]);
62
+ }
205
+ }
63
+
206
+
64
+ return 0;
207
+ create_gic(mms, sysmem);
65
+}
208
+
66
+
209
+ mms->bootinfo.ram_size = machine->ram_size;
67
int kvm_arch_put_registers(CPUState *cs, int level)
210
+ mms->bootinfo.board_id = -1;
68
{
211
+ mms->bootinfo.loader_start = mmc->loader_start;
69
struct kvm_one_reg reg;
212
+ mms->bootinfo.write_secondary_boot = mps3r_write_secondary_boot;
70
- uint32_t fpr;
213
+ mms->bootinfo.secondary_cpu_reset_hook = mps3r_secondary_cpu_reset;
71
uint64_t val;
214
+ arm_load_kernel(ARM_CPU(mms->cpu[0]), machine, &mms->bootinfo);
72
- int i;
215
}
73
- int ret;
216
74
+ int i, ret;
217
static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
75
unsigned int el;
218
@@ -XXX,XX +XXX,XX @@ static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
76
219
/* Found the entry for "system memory" */
77
ARMCPU *cpu = ARM_CPU(cs);
220
mc->default_ram_size = p->size;
78
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
221
mc->default_ram_id = p->name;
222
+ mmc->loader_start = p->base;
223
return;
79
}
224
}
80
}
225
}
81
226
@@ -XXX,XX +XXX,XX @@ static void mps3r_an536_class_init(ObjectClass *oc, void *data)
82
- /* Advanced SIMD and FP registers. */
227
};
83
- for (i = 0; i < 32; i++) {
228
84
- uint64_t *q = aa64_vfp_qreg(env, i);
229
mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
85
-#ifdef HOST_WORDS_BIGENDIAN
230
- mc->default_cpus = 2;
86
- uint64_t fp_val[2] = { q[1], q[0] };
231
- mc->min_cpus = mc->default_cpus;
87
- reg.addr = (uintptr_t)fp_val;
232
- mc->max_cpus = mc->default_cpus;
88
-#else
233
+ /*
89
- reg.addr = (uintptr_t)q;
234
+ * In the real FPGA image there are always two cores, but the standard
90
-#endif
235
+ * initial setting for the SCC SYSCON 0x000 register is 0x21, meaning
91
- reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
236
+ * that the second core is held in reset and halted. Many images built for
92
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
237
+ * the board do not expect the second core to run at startup (especially
93
- if (ret) {
238
+ * since on the real FPGA image it is not possible to use LDREX/STREX
94
- return ret;
239
+ * in RAM between the two cores, so a true SMP setup isn't supported).
95
- }
240
+ *
96
- }
241
+ * As QEMU's equivalent of this, we support both -smp 1 and -smp 2,
97
-
242
+ * with the default being -smp 1. This seems a more intuitive UI for
98
- reg.addr = (uintptr_t)(&fpr);
243
+ * QEMU users than, for instance, having a machine property to allow
99
- fpr = vfp_get_fpsr(env);
244
+ * the user to set the initial value of the SYSCON 0x000 register.
100
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
245
+ */
101
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
246
+ mc->default_cpus = 1;
102
- if (ret) {
247
+ mc->min_cpus = 1;
103
- return ret;
248
+ mc->max_cpus = 2;
104
- }
249
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
105
-
250
mc->valid_cpu_types = valid_cpu_types;
106
- fpr = vfp_get_fpcr(env);
251
mmc->raminfo = an536_raminfo;
107
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
108
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
109
+ ret = kvm_arch_put_fpsimd(cs);
110
if (ret) {
111
return ret;
112
}
113
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
114
return ret;
115
}
116
117
+static int kvm_arch_get_fpsimd(CPUState *cs)
118
+{
119
+ ARMCPU *cpu = ARM_CPU(cs);
120
+ CPUARMState *env = &cpu->env;
121
+ struct kvm_one_reg reg;
122
+ uint32_t fpr;
123
+ int i, ret;
124
+
125
+ for (i = 0; i < 32; i++) {
126
+ uint64_t *q = aa64_vfp_qreg(env, i);
127
+ reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
128
+ reg.addr = (uintptr_t)q;
129
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
130
+ if (ret) {
131
+ return ret;
132
+ } else {
133
+#ifdef HOST_WORDS_BIGENDIAN
134
+ uint64_t t;
135
+ t = q[0], q[0] = q[1], q[1] = t;
136
+#endif
137
+ }
138
+ }
139
+
140
+ reg.addr = (uintptr_t)(&fpr);
141
+ reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
142
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
143
+ if (ret) {
144
+ return ret;
145
+ }
146
+ vfp_set_fpsr(env, fpr);
147
+
148
+ reg.addr = (uintptr_t)(&fpr);
149
+ reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
150
+ ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
151
+ if (ret) {
152
+ return ret;
153
+ }
154
+ vfp_set_fpcr(env, fpr);
155
+
156
+ return 0;
157
+}
158
+
159
int kvm_arch_get_registers(CPUState *cs)
160
{
161
struct kvm_one_reg reg;
162
uint64_t val;
163
- uint32_t fpr;
164
unsigned int el;
165
- int i;
166
- int ret;
167
+ int i, ret;
168
169
ARMCPU *cpu = ARM_CPU(cs);
170
CPUARMState *env = &cpu->env;
171
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
172
env->spsr = env->banked_spsr[i];
173
}
174
175
- /* Advanced SIMD and FP registers */
176
- for (i = 0; i < 32; i++) {
177
- uint64_t *q = aa64_vfp_qreg(env, i);
178
- reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
179
- reg.addr = (uintptr_t)q;
180
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
181
- if (ret) {
182
- return ret;
183
- } else {
184
-#ifdef HOST_WORDS_BIGENDIAN
185
- uint64_t t;
186
- t = q[0], q[0] = q[1], q[1] = t;
187
-#endif
188
- }
189
- }
190
-
191
- reg.addr = (uintptr_t)(&fpr);
192
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpsr);
193
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
194
+ ret = kvm_arch_get_fpsimd(cs);
195
if (ret) {
196
return ret;
197
}
198
- vfp_set_fpsr(env, fpr);
199
-
200
- reg.id = AARCH64_SIMD_CTRL_REG(fp_regs.fpcr);
201
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
202
- if (ret) {
203
- return ret;
204
- }
205
- vfp_set_fpcr(env, fpr);
206
207
ret = kvm_get_vcpu_events(cpu);
208
if (ret) {
209
--
252
--
210
2.20.1
253
2.34.1
211
212
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
This board has a lot of UARTs: there is one UART per CPU in the
2
per-CPU peripheral part of the address map, whose interrupts are
3
connected as per-CPU interrupt lines. Then there are 4 UARTs in the
4
normal part of the peripheral space, whose interrupts are shared
5
peripheral interrupts.
2
6
3
Promote this function from aarch64 to fully general use.
7
Connect and wire them all up; this involves some OR gates where
4
Use it to unify the code sequences for generating illegal
8
multiple overflow interrupts are wired into one GIC input.
5
opcode exceptions.
6
9
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20190807045335.1361-11-richard.henderson@linaro.org
11
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>
12
Message-id: 20240206132931.38376-11-peter.maydell@linaro.org
12
---
13
---
13
target/arm/translate-a64.h | 2 --
14
hw/arm/mps3r.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++
14
target/arm/translate.h | 2 ++
15
1 file changed, 94 insertions(+)
15
target/arm/translate-a64.c | 7 -------
16
target/arm/translate-vfp.inc.c | 3 +--
17
target/arm/translate.c | 22 ++++++++++++----------
18
5 files changed, 15 insertions(+), 21 deletions(-)
19
16
20
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
17
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/translate-a64.h
19
--- a/hw/arm/mps3r.c
23
+++ b/target/arm/translate-a64.h
20
+++ b/hw/arm/mps3r.c
24
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
25
#ifndef TARGET_ARM_TRANSLATE_A64_H
22
#include "qapi/qmp/qlist.h"
26
#define TARGET_ARM_TRANSLATE_A64_H
23
#include "exec/address-spaces.h"
27
24
#include "cpu.h"
28
-void unallocated_encoding(DisasContext *s);
25
+#include "sysemu/sysemu.h"
29
-
26
#include "hw/boards.h"
30
#define unsupported_encoding(s, insn) \
27
+#include "hw/or-irq.h"
31
do { \
28
#include "hw/qdev-properties.h"
32
qemu_log_mask(LOG_UNIMP, \
29
#include "hw/arm/boot.h"
33
diff --git a/target/arm/translate.h b/target/arm/translate.h
30
#include "hw/arm/bsa.h"
34
index XXXXXXX..XXXXXXX 100644
31
+#include "hw/char/cmsdk-apb-uart.h"
35
--- a/target/arm/translate.h
32
#include "hw/intc/arm_gicv3.h"
36
+++ b/target/arm/translate.h
33
37
@@ -XXX,XX +XXX,XX @@ typedef struct DisasCompare {
34
/* Define the layout of RAM and ROM in a board */
38
bool value_global;
35
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
39
} DisasCompare;
36
40
37
#define MPS3R_RAM_MAX 9
41
+void unallocated_encoding(DisasContext *s);
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;
51
};
52
53
#define TYPE_MPS3R_MACHINE "mps3r"
54
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
55
56
OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
57
58
+/*
59
+ * Main clock frequency CLK in Hz (50MHz). In the image there are also
60
+ * ACLK, MCLK, GPUCLK and PERIPHCLK at the same frequency; for our
61
+ * model we just roll them all into one.
62
+ */
63
+#define CLK_FRQ 50000000
42
+
64
+
43
/* Share the TCG temporaries common between 32 and 64 bit modes. */
65
static const RAMInfo an536_raminfo[] = {
44
extern TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF;
66
{
45
extern TCGv_i64 cpu_exclusive_addr;
67
.name = "ATCM",
46
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
68
@@ -XXX,XX +XXX,XX @@ static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate-a64.c
49
+++ b/target/arm/translate-a64.c
50
@@ -XXX,XX +XXX,XX @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
51
}
69
}
52
}
70
}
53
71
54
-void unallocated_encoding(DisasContext *s)
72
+/*
55
-{
73
+ * Create UART uartno, and map it into the MemoryRegion mem at address baseaddr.
56
- /* Unallocated and reserved encodings are uncategorized */
74
+ * The qemu_irq arguments are where we connect the various IRQs from the UART.
57
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
75
+ */
58
- default_exception_el(s));
76
+static void create_uart(MPS3RMachineState *mms, int uartno, MemoryRegion *mem,
59
-}
77
+ hwaddr baseaddr, qemu_irq txirq, qemu_irq rxirq,
60
-
78
+ qemu_irq txoverirq, qemu_irq rxoverirq,
61
static void init_tmp_a64_array(DisasContext *s)
79
+ qemu_irq combirq)
62
{
63
#ifdef CONFIG_DEBUG_TCG
64
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate-vfp.inc.c
67
+++ b/target/arm/translate-vfp.inc.c
68
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
69
70
if (!s->vfp_enabled && !ignore_vfp_enabled) {
71
assert(!arm_dc_feature(s, ARM_FEATURE_M));
72
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
73
- default_exception_el(s));
74
+ unallocated_encoding(s);
75
return false;
76
}
77
78
diff --git a/target/arm/translate.c b/target/arm/translate.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/arm/translate.c
81
+++ b/target/arm/translate.c
82
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
83
s->base.is_jmp = DISAS_NORETURN;
84
}
85
86
+void unallocated_encoding(DisasContext *s)
87
+{
80
+{
88
+ /* Unallocated and reserved encodings are uncategorized */
81
+ g_autofree char *s = g_strdup_printf("uart%d", uartno);
89
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
82
+ SysBusDevice *sbd;
90
+ default_exception_el(s));
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);
91
+}
98
+}
92
+
99
+
93
/* Force a TB lookup after an instruction that changes the CPU state. */
100
static void mps3r_common_init(MachineState *machine)
94
static inline void gen_lookup_tb(DisasContext *s)
95
{
101
{
96
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
102
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
97
return;
103
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
104
MemoryRegion *sysmem = get_system_memory();
105
+ DeviceState *gicdev;
106
107
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
108
MemoryRegion *mr = mr_for_raminfo(mms, ri);
109
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
98
}
110
}
99
111
100
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
112
create_gic(mms, sysmem);
101
- default_exception_el(s));
113
+ gicdev = DEVICE(&mms->gic);
102
+ unallocated_encoding(s);
114
+
103
}
115
+ /*
104
116
+ * UARTs 0 and 1 are per-CPU; their interrupts are wired to
105
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
117
+ * the relevant CPU's PPI 0..3, aka INTID 16..19
106
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
118
+ */
107
}
119
+ for (int i = 0; i < machine->smp.cpus; i++) {
108
120
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
109
if (undef) {
121
+ g_autofree char *s = g_strdup_printf("cpu-uart-oflow-orgate%d", i);
110
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
122
+ DeviceState *orgate;
111
- default_exception_el(s));
123
+
112
+ unallocated_encoding(s);
124
+ /* The two overflow IRQs from the UART are ORed together into PPI 3 */
113
return;
125
+ object_initialize_child(OBJECT(mms), s, &mms->cpu_uart_oflow[i],
114
}
126
+ TYPE_OR_IRQ);
115
127
+ orgate = DEVICE(&mms->cpu_uart_oflow[i]);
116
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
128
+ qdev_prop_set_uint32(orgate, "num-lines", 2);
117
break;
129
+ qdev_realize(orgate, NULL, &error_fatal);
118
default:
130
+ qdev_connect_gpio_out(orgate, 0,
119
illegal_op:
131
+ qdev_get_gpio_in(gicdev, intidbase + 19));
120
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
132
+
121
- default_exception_el(s));
133
+ create_uart(mms, i, &mms->cpu_sysmem[i], 0xe7c00000,
122
+ unallocated_encoding(s);
134
+ qdev_get_gpio_in(gicdev, intidbase + 17), /* tx */
123
break;
135
+ qdev_get_gpio_in(gicdev, intidbase + 16), /* rx */
124
}
136
+ qdev_get_gpio_in(orgate, 0), /* txover */
125
}
137
+ qdev_get_gpio_in(orgate, 1), /* rxover */
126
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
138
+ qdev_get_gpio_in(gicdev, intidbase + 18) /* combined */);
127
}
139
+ }
128
return;
140
+ /*
129
illegal_op:
141
+ * UARTs 2 to 5 are whole-system; all overflow IRQs are ORed
130
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
142
+ * together into IRQ 17
131
- default_exception_el(s));
143
+ */
132
+ unallocated_encoding(s);
144
+ object_initialize_child(OBJECT(mms), "uart-oflow-orgate",
133
}
145
+ &mms->uart_oflow, TYPE_OR_IRQ);
134
146
+ qdev_prop_set_uint32(DEVICE(&mms->uart_oflow), "num-lines",
135
static void disas_thumb_insn(DisasContext *s, uint32_t insn)
147
+ MPS3R_UART_MAX * 2);
136
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
148
+ qdev_realize(DEVICE(&mms->uart_oflow), NULL, &error_fatal);
137
return;
149
+ qdev_connect_gpio_out(DEVICE(&mms->uart_oflow), 0,
138
illegal_op:
150
+ qdev_get_gpio_in(gicdev, 17));
139
undef:
151
+
140
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
152
+ for (int i = 0; i < MPS3R_UART_MAX; i++) {
141
- default_exception_el(s));
153
+ hwaddr baseaddr = 0xe0205000 + i * 0x1000;
142
+ unallocated_encoding(s);
154
+ int rxirq = 5 + i * 2, txirq = 6 + i * 2, combirq = 13 + i;
143
}
155
+
144
156
+ create_uart(mms, i + MPS3R_CPU_MAX, sysmem, baseaddr,
145
static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
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;
146
--
166
--
147
2.20.1
167
2.34.1
148
168
149
169
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
Add the GPIO, watchdog, dual-timer and I2C devices to the mps3-an536
2
board. These are all simple devices that just need to be created and
3
wired up.
2
4
3
A couple return -EINVAL's forgot their '-'s.
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20240206132931.38376-12-peter.maydell@linaro.org
8
---
9
hw/arm/mps3r.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
10
1 file changed, 59 insertions(+)
4
11
5
Signed-off-by: Andrew Jones <drjones@redhat.com>
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
6
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/kvm64.c | 4 ++--
11
1 file changed, 2 insertions(+), 2 deletions(-)
12
13
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/kvm64.c
14
--- a/hw/arm/mps3r.c
16
+++ b/target/arm/kvm64.c
15
+++ b/hw/arm/mps3r.c
17
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
16
@@ -XXX,XX +XXX,XX @@
18
write_cpustate_to_list(cpu, true);
17
#include "sysemu/sysemu.h"
19
18
#include "hw/boards.h"
20
if (!write_list_to_kvmstate(cpu, level)) {
19
#include "hw/or-irq.h"
21
- return EINVAL;
20
+#include "hw/qdev-clock.h"
22
+ return -EINVAL;
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);
50
+
51
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
52
MemoryRegion *mr = mr_for_raminfo(mms, ri);
53
memory_region_add_subregion(sysmem, ri->base, mr);
54
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
55
qdev_get_gpio_in(gicdev, combirq));
23
}
56
}
24
57
25
kvm_arm_sync_mpstate_to_kvm(cpu);
58
+ for (int i = 0; i < 4; i++) {
26
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
59
+ /* CMSDK GPIO controllers */
27
}
60
+ g_autofree char *s = g_strdup_printf("gpio%d", i);
28
61
+ create_unimplemented_device(s, 0xe0000000 + i * 0x1000, 0x1000);
29
if (!write_kvmstate_to_list(cpu)) {
62
+ }
30
- return EINVAL;
63
+
31
+ return -EINVAL;
64
+ object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
32
}
65
+ TYPE_CMSDK_APB_WATCHDOG);
33
/* Note that it's OK to have registers which aren't in CPUState,
66
+ qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->clk);
34
* so we can ignore a failure return here.
67
+ sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
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);
71
+
72
+ object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
73
+ TYPE_CMSDK_APB_DUALTIMER);
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);
83
+
84
+ for (int i = 0; i < ARRAY_SIZE(mms->i2c); i++) {
85
+ static const hwaddr i2cbase[] = {0xe0102000, /* Touch */
86
+ 0xe0103000, /* Audio */
87
+ 0xe0107000, /* Shield0 */
88
+ 0xe0108000, /* Shield1 */
89
+ 0xe0109000}; /* DDR4 EEPROM */
90
+ g_autofree char *s = g_strdup_printf("i2c%d", i);
91
+
92
+ object_initialize_child(OBJECT(mms), s, &mms->i2c[i],
93
+ TYPE_ARM_SBCON_I2C);
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
+ }
103
+ }
104
+
105
mms->bootinfo.ram_size = machine->ram_size;
106
mms->bootinfo.board_id = -1;
107
mms->bootinfo.loader_start = mmc->loader_start;
35
--
108
--
36
2.20.1
109
2.34.1
37
110
38
111
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Add the remaining devices (or unimplemented-device stubs) for
2
this board: SPI controllers, SCC, FPGAIO, I2S, RTC, the
3
QSPI write-config block, and ethernet.
2
4
3
We must update s->base.pc_next when we return from the translate_insn
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
hook to the main translator loop. By incrementing s->base.pc_next
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
immediately after reading the insn word, "pc_next" contains the address
7
Message-id: 20240206132931.38376-13-peter.maydell@linaro.org
6
of the next instruction throughout translation.
8
---
9
hw/arm/mps3r.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++
10
1 file changed, 74 insertions(+)
7
11
8
All remaining uses of s->pc are referencing the address of the next insn,
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
9
so this is now a simple global replacement. Remove the "s->pc" field.
10
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Message-id: 20190807045335.1361-7-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/translate.h | 1 -
18
target/arm/translate-a64.c | 51 +++++++++---------
19
target/arm/translate.c | 103 ++++++++++++++++++-------------------
20
3 files changed, 72 insertions(+), 83 deletions(-)
21
22
diff --git a/target/arm/translate.h b/target/arm/translate.h
23
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/translate.h
14
--- a/hw/arm/mps3r.c
25
+++ b/target/arm/translate.h
15
+++ b/hw/arm/mps3r.c
26
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
16
@@ -XXX,XX +XXX,XX @@
27
DisasContextBase base;
17
#include "hw/char/cmsdk-apb-uart.h"
28
const ARMISARegisters *isar;
18
#include "hw/i2c/arm_sbcon_i2c.h"
29
19
#include "hw/intc/arm_gicv3.h"
30
- target_ulong pc;
20
+#include "hw/misc/mps2-scc.h"
31
/* The address of the current instruction being translated. */
21
+#include "hw/misc/mps2-fpgaio.h"
32
target_ulong pc_curr;
22
#include "hw/misc/unimp.h"
33
target_ulong page_start;
23
+#include "hw/net/lan9118.h"
34
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
24
+#include "hw/rtc/pl031.h"
35
index XXXXXXX..XXXXXXX 100644
25
+#include "hw/ssi/pl022.h"
36
--- a/target/arm/translate-a64.c
26
#include "hw/timer/cmsdk-apb-dualtimer.h"
37
+++ b/target/arm/translate-a64.c
27
#include "hw/watchdog/cmsdk-apb-watchdog.h"
38
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal(int excp)
28
39
29
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
40
static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
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
+};
54
+
55
static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
56
const RAMInfo *raminfo)
41
{
57
{
42
- gen_a64_set_pc_im(s->pc - offset);
58
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
43
+ gen_a64_set_pc_im(s->base.pc_next - offset);
59
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
44
gen_exception_internal(excp);
60
MemoryRegion *sysmem = get_system_memory();
45
s->base.is_jmp = DISAS_NORETURN;
61
DeviceState *gicdev;
46
}
62
+ QList *oscclk;
47
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
63
48
static void gen_exception_insn(DisasContext *s, int offset, int excp,
64
mms->clk = clock_new(OBJECT(machine), "CLK");
49
uint32_t syndrome, uint32_t target_el)
65
clock_set_hz(mms->clk, CLK_FRQ);
50
{
66
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
51
- gen_a64_set_pc_im(s->pc - offset);
52
+ gen_a64_set_pc_im(s->base.pc_next - offset);
53
gen_exception(excp, syndrome, target_el);
54
s->base.is_jmp = DISAS_NORETURN;
55
}
56
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, int offset,
57
{
58
TCGv_i32 tcg_syn;
59
60
- gen_a64_set_pc_im(s->pc - offset);
61
+ gen_a64_set_pc_im(s->base.pc_next - offset);
62
tcg_syn = tcg_const_i32(syndrome);
63
gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
64
tcg_temp_free_i32(tcg_syn);
65
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
66
67
if (insn & (1U << 31)) {
68
/* BL Branch with link */
69
- tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
70
+ tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next);
71
}
72
73
/* B Branch / BL Branch with link */
74
@@ -XXX,XX +XXX,XX @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
75
tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
76
tcg_cmp, 0, label_match);
77
78
- gen_goto_tb(s, 0, s->pc);
79
+ gen_goto_tb(s, 0, s->base.pc_next);
80
gen_set_label(label_match);
81
gen_goto_tb(s, 1, addr);
82
}
83
@@ -XXX,XX +XXX,XX @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn)
84
tcg_gen_brcondi_i64(op ? TCG_COND_NE : TCG_COND_EQ,
85
tcg_cmp, 0, label_match);
86
tcg_temp_free_i64(tcg_cmp);
87
- gen_goto_tb(s, 0, s->pc);
88
+ gen_goto_tb(s, 0, s->base.pc_next);
89
gen_set_label(label_match);
90
gen_goto_tb(s, 1, addr);
91
}
92
@@ -XXX,XX +XXX,XX @@ static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
93
/* genuinely conditional branches */
94
TCGLabel *label_match = gen_new_label();
95
arm_gen_test_cc(cond, label_match);
96
- gen_goto_tb(s, 0, s->pc);
97
+ gen_goto_tb(s, 0, s->base.pc_next);
98
gen_set_label(label_match);
99
gen_goto_tb(s, 1, addr);
100
} else {
101
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
102
* any pending interrupts immediately.
103
*/
104
reset_btype(s);
105
- gen_goto_tb(s, 0, s->pc);
106
+ gen_goto_tb(s, 0, s->base.pc_next);
107
return;
108
109
case 7: /* SB */
110
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
111
* MB and end the TB instead.
112
*/
113
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
114
- gen_goto_tb(s, 0, s->pc);
115
+ gen_goto_tb(s, 0, s->base.pc_next);
116
return;
117
118
default:
119
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
120
gen_a64_set_pc(s, dst);
121
/* BLR also needs to load return address */
122
if (opc == 1) {
123
- tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
124
+ tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next);
125
}
126
break;
127
128
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
129
gen_a64_set_pc(s, dst);
130
/* BLRAA also needs to load return address */
131
if (opc == 9) {
132
- tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
133
+ tcg_gen_movi_i64(cpu_reg(s, 30), s->base.pc_next);
134
}
135
break;
136
137
@@ -XXX,XX +XXX,XX @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
138
{
139
uint32_t insn;
140
141
- s->pc_curr = s->pc;
142
- insn = arm_ldl_code(env, s->pc, s->sctlr_b);
143
+ s->pc_curr = s->base.pc_next;
144
+ insn = arm_ldl_code(env, s->base.pc_next, s->sctlr_b);
145
s->insn = insn;
146
- s->pc += 4;
147
+ s->base.pc_next += 4;
148
149
s->fp_access_checked = false;
150
151
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
152
int bound, core_mmu_idx;
153
154
dc->isar = &arm_cpu->isar;
155
- dc->pc = dc->base.pc_first;
156
dc->condjmp = 0;
157
158
dc->aarch64 = 1;
159
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
160
{
161
DisasContext *dc = container_of(dcbase, DisasContext, base);
162
163
- tcg_gen_insn_start(dc->pc, 0, 0);
164
+ tcg_gen_insn_start(dc->base.pc_next, 0, 0);
165
dc->insn_start = tcg_last_op();
166
}
167
168
@@ -XXX,XX +XXX,XX @@ static bool aarch64_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
169
DisasContext *dc = container_of(dcbase, DisasContext, base);
170
171
if (bp->flags & BP_CPU) {
172
- gen_a64_set_pc_im(dc->pc);
173
+ gen_a64_set_pc_im(dc->base.pc_next);
174
gen_helper_check_breakpoints(cpu_env);
175
/* End the TB early; it likely won't be executed */
176
dc->base.is_jmp = DISAS_TOO_MANY;
177
@@ -XXX,XX +XXX,XX @@ static bool aarch64_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
178
to for it to be properly cleared -- thus we
179
increment the PC here so that the logic setting
180
tb->size below does the right thing. */
181
- dc->pc += 4;
182
+ dc->base.pc_next += 4;
183
dc->base.is_jmp = DISAS_NORETURN;
184
}
185
186
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
187
disas_a64_insn(env, dc);
188
}
189
190
- dc->base.pc_next = dc->pc;
191
translator_loop_temp_check(&dc->base);
192
}
193
194
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
195
*/
196
switch (dc->base.is_jmp) {
197
default:
198
- gen_a64_set_pc_im(dc->pc);
199
+ gen_a64_set_pc_im(dc->base.pc_next);
200
/* fall through */
201
case DISAS_EXIT:
202
case DISAS_JUMP:
203
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
204
switch (dc->base.is_jmp) {
205
case DISAS_NEXT:
206
case DISAS_TOO_MANY:
207
- gen_goto_tb(dc, 1, dc->pc);
208
+ gen_goto_tb(dc, 1, dc->base.pc_next);
209
break;
210
default:
211
case DISAS_UPDATE:
212
- gen_a64_set_pc_im(dc->pc);
213
+ gen_a64_set_pc_im(dc->base.pc_next);
214
/* fall through */
215
case DISAS_EXIT:
216
tcg_gen_exit_tb(NULL, 0);
217
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
218
case DISAS_SWI:
219
break;
220
case DISAS_WFE:
221
- gen_a64_set_pc_im(dc->pc);
222
+ gen_a64_set_pc_im(dc->base.pc_next);
223
gen_helper_wfe(cpu_env);
224
break;
225
case DISAS_YIELD:
226
- gen_a64_set_pc_im(dc->pc);
227
+ gen_a64_set_pc_im(dc->base.pc_next);
228
gen_helper_yield(cpu_env);
229
break;
230
case DISAS_WFI:
231
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
232
*/
233
TCGv_i32 tmp = tcg_const_i32(4);
234
235
- gen_a64_set_pc_im(dc->pc);
236
+ gen_a64_set_pc_im(dc->base.pc_next);
237
gen_helper_wfi(cpu_env, tmp);
238
tcg_temp_free_i32(tmp);
239
/* The helper doesn't necessarily throw an exception, but we
240
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
241
}
242
}
67
}
243
}
68
}
244
-
69
245
- /* Functions above can change dc->pc, so re-align db->pc_next */
70
+ for (int i = 0; i < ARRAY_SIZE(mms->spi); i++) {
246
- dc->base.pc_next = dc->pc;
71
+ g_autofree char *s = g_strdup_printf("spi%d", i);
247
}
72
+ hwaddr baseaddr = 0xe0104000 + i * 0x1000;
248
73
+
249
static void aarch64_tr_disas_log(const DisasContextBase *dcbase,
74
+ object_initialize_child(OBJECT(mms), s, &mms->spi[i], TYPE_PL022);
250
diff --git a/target/arm/translate.c b/target/arm/translate.c
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->spi[i]), &error_fatal);
251
index XXXXXXX..XXXXXXX 100644
76
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->spi[i]), 0, baseaddr);
252
--- a/target/arm/translate.c
77
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->spi[i]), 0,
253
+++ b/target/arm/translate.c
78
+ qdev_get_gpio_in(gicdev, 22 + i));
254
@@ -XXX,XX +XXX,XX @@ static inline void gen_blxns(DisasContext *s, int rm)
79
+ }
255
* We do however need to set the PC, because the blxns helper reads it.
80
+
256
* The blxns helper may throw an exception.
81
+ object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
257
*/
82
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg0", 0);
258
- gen_set_pc_im(s, s->pc);
83
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg4", 0x2);
259
+ gen_set_pc_im(s, s->base.pc_next);
84
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-aid", 0x00200008);
260
gen_helper_v7m_blxns(cpu_env, var);
85
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-id", 0x41055360);
261
tcg_temp_free_i32(var);
86
+ oscclk = qlist_new();
262
s->base.is_jmp = DISAS_EXIT;
87
+ for (int i = 0; i < ARRAY_SIZE(an536_oscclk); i++) {
263
@@ -XXX,XX +XXX,XX @@ static inline void gen_hvc(DisasContext *s, int imm16)
88
+ qlist_append_int(oscclk, an536_oscclk[i]);
264
* for single stepping.)
89
+ }
265
*/
90
+ qdev_prop_set_array(DEVICE(&mms->scc), "oscclk", oscclk);
266
s->svc_imm = imm16;
91
+ sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
267
- gen_set_pc_im(s, s->pc);
92
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->scc), 0, 0xe0200000);
268
+ gen_set_pc_im(s, s->base.pc_next);
93
+
269
s->base.is_jmp = DISAS_HVC;
94
+ create_unimplemented_device("i2s-audio", 0xe0201000, 0x1000);
270
}
95
+
271
96
+ object_initialize_child(OBJECT(mms), "fpgaio", &mms->fpgaio,
272
@@ -XXX,XX +XXX,XX @@ static inline void gen_smc(DisasContext *s)
97
+ TYPE_MPS2_FPGAIO);
273
tmp = tcg_const_i32(syn_aa32_smc());
98
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", an536_oscclk[1]);
274
gen_helper_pre_smc(cpu_env, tmp);
99
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "num-leds", 10);
275
tcg_temp_free_i32(tmp);
100
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-switches", true);
276
- gen_set_pc_im(s, s->pc);
101
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-dbgctrl", false);
277
+ gen_set_pc_im(s, s->base.pc_next);
102
+ sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
278
s->base.is_jmp = DISAS_SMC;
103
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0xe0202000);
279
}
104
+
280
105
+ create_unimplemented_device("clcd", 0xe0209000, 0x1000);
281
static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
106
+
282
{
107
+ object_initialize_child(OBJECT(mms), "rtc", &mms->rtc, TYPE_PL031);
283
gen_set_condexec(s);
108
+ sysbus_realize(SYS_BUS_DEVICE(&mms->rtc), &error_fatal);
284
- gen_set_pc_im(s, s->pc - offset);
109
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->rtc), 0, 0xe020a000);
285
+ gen_set_pc_im(s, s->base.pc_next - offset);
110
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->rtc), 0,
286
gen_exception_internal(excp);
111
+ qdev_get_gpio_in(gicdev, 4));
287
s->base.is_jmp = DISAS_NORETURN;
112
+
288
}
113
+ /*
289
@@ -XXX,XX +XXX,XX @@ static void gen_exception_insn(DisasContext *s, int offset, int excp,
114
+ * In hardware this is a LAN9220; the LAN9118 is software compatible
290
int syn, uint32_t target_el)
115
+ * except that it doesn't support the checksum-offload feature.
291
{
116
+ */
292
gen_set_condexec(s);
117
+ lan9118_init(0xe0300000,
293
- gen_set_pc_im(s, s->pc - offset);
118
+ qdev_get_gpio_in(gicdev, 18));
294
+ gen_set_pc_im(s, s->base.pc_next - offset);
119
+
295
gen_exception(excp, syn, target_el);
120
+ create_unimplemented_device("usb", 0xe0301000, 0x1000);
296
s->base.is_jmp = DISAS_NORETURN;
121
+ create_unimplemented_device("qspi-write-config", 0xe0600000, 0x1000);
297
}
122
+
298
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
123
mms->bootinfo.ram_size = machine->ram_size;
299
TCGv_i32 tcg_syn;
124
mms->bootinfo.board_id = -1;
300
125
mms->bootinfo.loader_start = mmc->loader_start;
301
gen_set_condexec(s);
302
- gen_set_pc_im(s, s->pc - offset);
303
+ gen_set_pc_im(s, s->base.pc_next - offset);
304
tcg_syn = tcg_const_i32(syn);
305
gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
306
tcg_temp_free_i32(tcg_syn);
307
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
308
/* Force a TB lookup after an instruction that changes the CPU state. */
309
static inline void gen_lookup_tb(DisasContext *s)
310
{
311
- tcg_gen_movi_i32(cpu_R[15], s->pc);
312
+ tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
313
s->base.is_jmp = DISAS_EXIT;
314
}
315
316
@@ -XXX,XX +XXX,XX @@ static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
317
{
318
#ifndef CONFIG_USER_ONLY
319
return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
320
- ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
321
+ ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
322
#else
323
return true;
324
#endif
325
@@ -XXX,XX +XXX,XX @@ static void gen_nop_hint(DisasContext *s, int val)
326
*/
327
case 1: /* yield */
328
if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
329
- gen_set_pc_im(s, s->pc);
330
+ gen_set_pc_im(s, s->base.pc_next);
331
s->base.is_jmp = DISAS_YIELD;
332
}
333
break;
334
case 3: /* wfi */
335
- gen_set_pc_im(s, s->pc);
336
+ gen_set_pc_im(s, s->base.pc_next);
337
s->base.is_jmp = DISAS_WFI;
338
break;
339
case 2: /* wfe */
340
if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
341
- gen_set_pc_im(s, s->pc);
342
+ gen_set_pc_im(s, s->base.pc_next);
343
s->base.is_jmp = DISAS_WFE;
344
}
345
break;
346
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
347
if (isread) {
348
return 1;
349
}
350
- gen_set_pc_im(s, s->pc);
351
+ gen_set_pc_im(s, s->base.pc_next);
352
s->base.is_jmp = DISAS_WFI;
353
return 0;
354
default:
355
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
356
* self-modifying code correctly and also to take
357
* any pending interrupts immediately.
358
*/
359
- gen_goto_tb(s, 0, s->pc);
360
+ gen_goto_tb(s, 0, s->base.pc_next);
361
return;
362
case 7: /* sb */
363
if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
364
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
365
* for TCG; MB and end the TB instead.
366
*/
367
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
368
- gen_goto_tb(s, 0, s->pc);
369
+ gen_goto_tb(s, 0, s->base.pc_next);
370
return;
371
default:
372
goto illegal_op;
373
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
374
int32_t offset;
375
376
tmp = tcg_temp_new_i32();
377
- tcg_gen_movi_i32(tmp, s->pc);
378
+ tcg_gen_movi_i32(tmp, s->base.pc_next);
379
store_reg(s, 14, tmp);
380
/* Sign-extend the 24-bit offset */
381
offset = (((int32_t)insn) << 8) >> 8;
382
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
383
/* branch link/exchange thumb (blx) */
384
tmp = load_reg(s, rm);
385
tmp2 = tcg_temp_new_i32();
386
- tcg_gen_movi_i32(tmp2, s->pc);
387
+ tcg_gen_movi_i32(tmp2, s->base.pc_next);
388
store_reg(s, 14, tmp2);
389
gen_bx(s, tmp);
390
break;
391
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
392
/* branch (and link) */
393
if (insn & (1 << 24)) {
394
tmp = tcg_temp_new_i32();
395
- tcg_gen_movi_i32(tmp, s->pc);
396
+ tcg_gen_movi_i32(tmp, s->base.pc_next);
397
store_reg(s, 14, tmp);
398
}
399
offset = sextract32(insn << 2, 0, 26);
400
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
401
break;
402
case 0xf:
403
/* swi */
404
- gen_set_pc_im(s, s->pc);
405
+ gen_set_pc_im(s, s->base.pc_next);
406
s->svc_imm = extract32(insn, 0, 24);
407
s->base.is_jmp = DISAS_SWI;
408
break;
409
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
410
411
if (insn & (1 << 14)) {
412
/* Branch and link. */
413
- tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
414
+ tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
415
}
416
417
offset += read_pc(s);
418
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
419
* and also to take any pending interrupts
420
* immediately.
421
*/
422
- gen_goto_tb(s, 0, s->pc);
423
+ gen_goto_tb(s, 0, s->base.pc_next);
424
break;
425
case 7: /* sb */
426
if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
427
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
428
* for TCG; MB and end the TB instead.
429
*/
430
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
431
- gen_goto_tb(s, 0, s->pc);
432
+ gen_goto_tb(s, 0, s->base.pc_next);
433
break;
434
default:
435
goto illegal_op;
436
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
437
/* BLX/BX */
438
tmp = load_reg(s, rm);
439
if (link) {
440
- val = (uint32_t)s->pc | 1;
441
+ val = (uint32_t)s->base.pc_next | 1;
442
tmp2 = tcg_temp_new_i32();
443
tcg_gen_movi_i32(tmp2, val);
444
store_reg(s, 14, tmp2);
445
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
446
447
if (cond == 0xf) {
448
/* swi */
449
- gen_set_pc_im(s, s->pc);
450
+ gen_set_pc_im(s, s->base.pc_next);
451
s->svc_imm = extract32(insn, 0, 8);
452
s->base.is_jmp = DISAS_SWI;
453
break;
454
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
455
tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
456
457
tmp2 = tcg_temp_new_i32();
458
- tcg_gen_movi_i32(tmp2, s->pc | 1);
459
+ tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
460
store_reg(s, 14, tmp2);
461
gen_bx(s, tmp);
462
break;
463
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
464
tcg_gen_addi_i32(tmp, tmp, offset);
465
466
tmp2 = tcg_temp_new_i32();
467
- tcg_gen_movi_i32(tmp2, s->pc | 1);
468
+ tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
469
store_reg(s, 14, tmp2);
470
gen_bx(s, tmp);
471
} else {
472
@@ -XXX,XX +XXX,XX @@ undef:
473
474
static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
475
{
476
- /* Return true if the insn at dc->pc might cross a page boundary.
477
+ /* Return true if the insn at dc->base.pc_next might cross a page boundary.
478
* (False positives are OK, false negatives are not.)
479
* We know this is a Thumb insn, and our caller ensures we are
480
- * only called if dc->pc is less than 4 bytes from the page
481
+ * only called if dc->base.pc_next is less than 4 bytes from the page
482
* boundary, so we cross the page if the first 16 bits indicate
483
* that this is a 32 bit insn.
484
*/
485
- uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
486
+ uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
487
488
- return !thumb_insn_is_16bit(s, s->pc, insn);
489
+ return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
490
}
491
492
static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
493
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
494
uint32_t condexec, core_mmu_idx;
495
496
dc->isar = &cpu->isar;
497
- dc->pc = dc->base.pc_first;
498
dc->condjmp = 0;
499
500
dc->aarch64 = 0;
501
@@ -XXX,XX +XXX,XX @@ static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
502
{
503
DisasContext *dc = container_of(dcbase, DisasContext, base);
504
505
- tcg_gen_insn_start(dc->pc,
506
+ tcg_gen_insn_start(dc->base.pc_next,
507
(dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
508
0);
509
dc->insn_start = tcg_last_op();
510
@@ -XXX,XX +XXX,XX @@ static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
511
512
if (bp->flags & BP_CPU) {
513
gen_set_condexec(dc);
514
- gen_set_pc_im(dc, dc->pc);
515
+ gen_set_pc_im(dc, dc->base.pc_next);
516
gen_helper_check_breakpoints(cpu_env);
517
/* End the TB early; it's likely not going to be executed */
518
dc->base.is_jmp = DISAS_TOO_MANY;
519
@@ -XXX,XX +XXX,XX @@ static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
520
tb->size below does the right thing. */
521
/* TODO: Advance PC by correct instruction length to
522
* avoid disassembler error messages */
523
- dc->pc += 2;
524
+ dc->base.pc_next += 2;
525
dc->base.is_jmp = DISAS_NORETURN;
526
}
527
528
@@ -XXX,XX +XXX,XX @@ static bool arm_pre_translate_insn(DisasContext *dc)
529
{
530
#ifdef CONFIG_USER_ONLY
531
/* Intercept jump to the magic kernel page. */
532
- if (dc->pc >= 0xffff0000) {
533
+ if (dc->base.pc_next >= 0xffff0000) {
534
/* We always get here via a jump, so know we are not in a
535
conditional execution block. */
536
gen_exception_internal(EXCP_KERNEL_TRAP);
537
@@ -XXX,XX +XXX,XX @@ static void arm_post_translate_insn(DisasContext *dc)
538
gen_set_label(dc->condlabel);
539
dc->condjmp = 0;
540
}
541
- dc->base.pc_next = dc->pc;
542
translator_loop_temp_check(&dc->base);
543
}
544
545
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
546
return;
547
}
548
549
- dc->pc_curr = dc->pc;
550
- insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
551
+ dc->pc_curr = dc->base.pc_next;
552
+ insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
553
dc->insn = insn;
554
- dc->pc += 4;
555
+ dc->base.pc_next += 4;
556
disas_arm_insn(dc, insn);
557
558
arm_post_translate_insn(dc);
559
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
560
return;
561
}
562
563
- dc->pc_curr = dc->pc;
564
- insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
565
- is_16bit = thumb_insn_is_16bit(dc, dc->pc, insn);
566
- dc->pc += 2;
567
+ dc->pc_curr = dc->base.pc_next;
568
+ insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
569
+ is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
570
+ dc->base.pc_next += 2;
571
if (!is_16bit) {
572
- uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
573
+ uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
574
575
insn = insn << 16 | insn2;
576
- dc->pc += 2;
577
+ dc->base.pc_next += 2;
578
}
579
dc->insn = insn;
580
581
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
582
* but isn't very efficient).
583
*/
584
if (dc->base.is_jmp == DISAS_NEXT
585
- && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE
586
- || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3
587
+ && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE
588
+ || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3
589
&& insn_crosses_page(env, dc)))) {
590
dc->base.is_jmp = DISAS_TOO_MANY;
591
}
592
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
593
case DISAS_NEXT:
594
case DISAS_TOO_MANY:
595
case DISAS_UPDATE:
596
- gen_set_pc_im(dc, dc->pc);
597
+ gen_set_pc_im(dc, dc->base.pc_next);
598
/* fall through */
599
default:
600
/* FIXME: Single stepping a WFI insn will not halt the CPU. */
601
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
602
switch(dc->base.is_jmp) {
603
case DISAS_NEXT:
604
case DISAS_TOO_MANY:
605
- gen_goto_tb(dc, 1, dc->pc);
606
+ gen_goto_tb(dc, 1, dc->base.pc_next);
607
break;
608
case DISAS_JUMP:
609
gen_goto_ptr();
610
break;
611
case DISAS_UPDATE:
612
- gen_set_pc_im(dc, dc->pc);
613
+ gen_set_pc_im(dc, dc->base.pc_next);
614
/* fall through */
615
default:
616
/* indicate that the hash table must be used to find the next TB */
617
@@ -XXX,XX +XXX,XX @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
618
gen_set_label(dc->condlabel);
619
gen_set_condexec(dc);
620
if (unlikely(is_singlestepping(dc))) {
621
- gen_set_pc_im(dc, dc->pc);
622
+ gen_set_pc_im(dc, dc->base.pc_next);
623
gen_singlestep_exception(dc);
624
} else {
625
- gen_goto_tb(dc, 1, dc->pc);
626
+ gen_goto_tb(dc, 1, dc->base.pc_next);
627
}
628
}
629
-
630
- /* Functions above can change dc->pc, so re-align db->pc_next */
631
- dc->base.pc_next = dc->pc;
632
}
633
634
static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
635
--
126
--
636
2.20.1
127
2.34.1
637
128
638
129
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Add documentation for the mps3-an536 board type.
2
2
3
While most features are now detected by probing the ID_* registers
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
kernels can (and do) use MIDR_EL1 for working out of they have to
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
apply errata. This can trip up warnings in the kernel as it tries to
5
Message-id: 20240206132931.38376-14-peter.maydell@linaro.org
6
work out if it should apply workarounds to features that don't
6
---
7
actually exist in the reported CPU type.
7
docs/system/arm/mps2.rst | 37 ++++++++++++++++++++++++++++++++++---
8
1 file changed, 34 insertions(+), 3 deletions(-)
8
9
9
Avoid this problem by synthesising our own MIDR value.
10
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
10
11
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190726113950.7499-1-alex.bennee@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/cpu.h | 6 ++++++
18
target/arm/cpu64.c | 19 +++++++++++++++++++
19
2 files changed, 25 insertions(+)
20
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
12
--- a/docs/system/arm/mps2.rst
24
+++ b/target/arm/cpu.h
13
+++ b/docs/system/arm/mps2.rst
25
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_FPCCR, ASPEN, 31, 1)
14
@@ -XXX,XX +XXX,XX @@
26
/*
15
-Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
27
* System register ID fields.
16
-=========================================================================================================================================================
28
*/
17
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an536``, ``mps3-an547``)
29
+FIELD(MIDR_EL1, REVISION, 0, 4)
18
+=========================================================================================================================================================================
30
+FIELD(MIDR_EL1, PARTNUM, 4, 12)
19
31
+FIELD(MIDR_EL1, ARCHITECTURE, 16, 4)
20
-These board models all use Arm M-profile CPUs.
32
+FIELD(MIDR_EL1, VARIANT, 20, 4)
21
+These board models use Arm M-profile or R-profile CPUs.
33
+FIELD(MIDR_EL1, IMPLEMENTER, 24, 8)
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:
34
+
30
+
35
FIELD(ID_ISAR0, SWAP, 0, 4)
31
``mps2-an385``
36
FIELD(ID_ISAR0, BITCOUNT, 4, 4)
32
Cortex-M3 as documented in Arm Application Note AN385
37
FIELD(ID_ISAR0, BITFIELD, 8, 4)
33
``mps2-an386``
38
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
34
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
39
index XXXXXXX..XXXXXXX 100644
35
``mps3-an547``
40
--- a/target/arm/cpu64.c
36
Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
41
+++ b/target/arm/cpu64.c
37
42
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
38
+FPGA images using R-profile CPUs:
43
uint32_t u;
44
aarch64_a57_initfn(obj);
45
46
+ /*
47
+ * Reset MIDR so the guest doesn't mistake our 'max' CPU type for a real
48
+ * one and try to apply errata workarounds or use impdef features we
49
+ * don't provide.
50
+ * An IMPLEMENTER field of 0 means "reserved for software use";
51
+ * ARCHITECTURE must be 0xf indicating "v7 or later, check ID registers
52
+ * to see which features are present";
53
+ * the VARIANT, PARTNUM and REVISION fields are all implementation
54
+ * defined and we choose to define PARTNUM just in case guest
55
+ * code needs to distinguish this QEMU CPU from other software
56
+ * implementations, though this shouldn't be needed.
57
+ */
58
+ t = FIELD_DP64(0, MIDR_EL1, IMPLEMENTER, 0);
59
+ t = FIELD_DP64(t, MIDR_EL1, ARCHITECTURE, 0xf);
60
+ t = FIELD_DP64(t, MIDR_EL1, PARTNUM, 'Q');
61
+ t = FIELD_DP64(t, MIDR_EL1, VARIANT, 0);
62
+ t = FIELD_DP64(t, MIDR_EL1, REVISION, 0);
63
+ cpu->midr = t;
64
+
39
+
65
t = cpu->isar.id_aa64isar0;
40
+``mps3-an536``
66
t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2); /* AES + PMULL */
41
+ Dual Cortex-R52 on an MPS3, as documented in Arm Application Note AN536
67
t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1);
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
""""""""""""""""""""""""
68
--
77
--
69
2.20.1
78
2.34.1
70
79
71
80
diff view generated by jsdifflib