1
The following changes since commit 5a67d7735d4162630769ef495cf813244fc850df:
1
The following changes since commit 5767815218efd3cbfd409505ed824d5f356044ae:
2
2
3
Merge remote-tracking branch 'remotes/berrange-gitlab/tags/tls-deps-pull-request' into staging (2021-07-02 08:22:39 +0100)
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
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210702
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240215
8
8
9
for you to fetch changes up to 04ea4d3cfd0a21b248ece8eb7a9436a3d9898dd8:
9
for you to fetch changes up to f780e63fe731b058fe52d43653600d8729a1b5f2:
10
10
11
target/arm: Implement MVE shifts by register (2021-07-02 11:48:38 +0100)
11
docs: Add documentation for the mps3-an536 board (2024-02-15 14:32:39 +0000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
target-arm queue:
14
target-arm queue:
15
* more MVE instructions
15
* hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
16
* hw/gpio/gpio_pwr: use shutdown function for reboot
16
* linux-user/aarch64: Choose SYNC as the preferred MTE mode
17
* target/arm: Check NaN mode before silencing NaN
17
* Fix some errors in SVE/SME handling of MTE tags
18
* tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
18
* hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
19
* hw/arm: Add basic power management to raspi.
19
* hw/block/tc58128: Don't emit deprecation warning under qtest
20
* docs/system/arm: Add quanta-gbs-bmc, quanta-q7l1-bmc
20
* tests/qtest: Fix handling of npcm7xx and GMAC tests
21
* hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
22
* tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
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)
21
30
22
----------------------------------------------------------------
31
----------------------------------------------------------------
23
Joe Komlodi (1):
32
Luc Michel (1):
24
target/arm: Check NaN mode before silencing NaN
33
hw/arm/smmuv3: add support for stage 1 access fault
25
34
26
Maxim Uvarov (1):
35
Nabih Estefan (1):
27
hw/gpio/gpio_pwr: use shutdown function for reboot
36
tests/qtest: Fix GMAC test to run on a machine in upstream QEMU
28
37
29
Nolan Leake (1):
38
Peter Maydell (22):
30
hw/arm: Add basic power management to raspi.
39
hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
40
hw/block/tc58128: Don't emit deprecation warning under qtest
41
tests/qtest/meson.build: Don't include qtests_npcm7xx in qtests_aarch64
42
tests/qtest/bios-tables-test: Allow changes to virt GTDT
43
hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
44
tests/qtest/bios-tables-tests: Update virt golden reference
45
hw/arm/npcm7xx: Call qemu_configure_nic_device() for GMAC modules
46
tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
47
target/arm: Don't get MDCR_EL2 in pmu_counter_enabled() before checking ARM_FEATURE_PMU
48
target/arm: Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
49
target/arm: The Cortex-R52 has a read-only CBAR
50
target/arm: Add Cortex-R52 IMPDEF sysregs
51
target/arm: Allow access to SPSR_hyp from hyp mode
52
hw/misc/mps2-scc: Fix condition for CFG3 register
53
hw/misc/mps2-scc: Factor out which-board conditionals
54
hw/misc/mps2-scc: Make changes needed for AN536 FPGA image
55
hw/arm/mps3r: Initial skeleton for mps3-an536 board
56
hw/arm/mps3r: Add CPUs, GIC, and per-CPU RAM
57
hw/arm/mps3r: Add UARTs
58
hw/arm/mps3r: Add GPIO, watchdog, dual-timer, I2C devices
59
hw/arm/mps3r: Add remaining devices
60
docs: Add documentation for the mps3-an536 board
31
61
32
Patrick Venture (2):
62
Philippe Mathieu-Daudé (5):
33
docs/system/arm: Add quanta-q7l1-bmc reference
63
hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
34
docs/system/arm: Add quanta-gbs-bmc reference
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
35
68
36
Peter Maydell (18):
69
Richard Henderson (6):
37
target/arm: Fix MVE widening/narrowing VLDR/VSTR offset calculation
70
linux-user/aarch64: Choose SYNC as the preferred MTE mode
38
target/arm: Fix bugs in MVE VRMLALDAVH, VRMLSLDAVH
71
target/arm: Fix nregs computation in do_{ld,st}_zpa
39
target/arm: Make asimd_imm_const() public
72
target/arm: Adjust and validate mtedesc sizem1
40
target/arm: Use asimd_imm_const for A64 decode
73
target/arm: Split out make_svemte_desc
41
target/arm: Use dup_const() instead of bitfield_replicate()
74
target/arm: Handle mte in do_ldrq, do_ldro
42
target/arm: Implement MVE logical immediate insns
75
target/arm: Fix SVE/SME gross MTE suppression checks
43
target/arm: Implement MVE vector shift left by immediate insns
44
target/arm: Implement MVE vector shift right by immediate insns
45
target/arm: Implement MVE VSHLL
46
target/arm: Implement MVE VSRI, VSLI
47
target/arm: Implement MVE VSHRN, VRSHRN
48
target/arm: Implement MVE saturating narrowing shifts
49
target/arm: Implement MVE VSHLC
50
target/arm: Implement MVE VADDLV
51
target/arm: Implement MVE long shifts by immediate
52
target/arm: Implement MVE long shifts by register
53
target/arm: Implement MVE shifts by immediate
54
target/arm: Implement MVE shifts by register
55
76
56
Philippe Mathieu-Daudé (1):
77
MAINTAINERS | 3 +-
57
tests: Boot and halt a Linux guest on the Raspberry Pi 2 machine
78
docs/system/arm/mps2.rst | 37 +-
79
configs/devices/arm-softmmu/default.mak | 1 +
80
hw/arm/smmuv3-internal.h | 1 +
81
include/hw/arm/smmu-common.h | 1 +
82
include/hw/arm/virt.h | 2 +
83
include/hw/misc/mps2-scc.h | 1 +
84
linux-user/aarch64/target_prctl.h | 29 +-
85
target/arm/internals.h | 2 +-
86
target/arm/tcg/translate-a64.h | 2 +
87
hw/arm/mps3r.c | 640 ++++++++++++++++++++++++++++++++
88
hw/arm/npcm7xx.c | 1 +
89
hw/arm/smmu-common.c | 11 +
90
hw/arm/smmuv3.c | 1 +
91
hw/arm/stellaris.c | 47 ++-
92
hw/arm/virt-acpi-build.c | 20 +-
93
hw/arm/virt.c | 60 ++-
94
hw/arm/xilinx_zynq.c | 2 +
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
58
115
59
docs/system/arm/aspeed.rst | 1 +
60
docs/system/arm/nuvoton.rst | 5 +-
61
include/hw/arm/bcm2835_peripherals.h | 3 +-
62
include/hw/misc/bcm2835_powermgt.h | 29 ++
63
target/arm/helper-mve.h | 108 +++++++
64
target/arm/translate.h | 41 +++
65
target/arm/mve.decode | 177 ++++++++++-
66
target/arm/t32.decode | 71 ++++-
67
hw/arm/bcm2835_peripherals.c | 13 +-
68
hw/gpio/gpio_pwr.c | 2 +-
69
hw/misc/bcm2835_powermgt.c | 160 ++++++++++
70
target/arm/helper-a64.c | 12 +-
71
target/arm/mve_helper.c | 524 +++++++++++++++++++++++++++++++--
72
target/arm/translate-a64.c | 86 +-----
73
target/arm/translate-mve.c | 261 +++++++++++++++-
74
target/arm/translate-neon.c | 81 -----
75
target/arm/translate.c | 327 +++++++++++++++++++-
76
target/arm/vfp_helper.c | 24 +-
77
hw/misc/meson.build | 1 +
78
tests/acceptance/boot_linux_console.py | 43 +++
79
20 files changed, 1760 insertions(+), 209 deletions(-)
80
create mode 100644 include/hw/misc/bcm2835_powermgt.h
81
create mode 100644 hw/misc/bcm2835_powermgt.c
82
diff view generated by jsdifflib
1
From: Joe Komlodi <joe.komlodi@xilinx.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
If the CPU is running in default NaN mode (FPCR.DN == 1) and we execute
3
Similarly to commits dadbb58f59..5ae79fe825 for other ARM boards,
4
FRSQRTE, FRECPE, or FRECPX with a signaling NaN, parts_silence_nan_frac() will
4
connect FIQ output of the GIC CPU interfaces to the CPU.
5
assert due to fpst->default_nan_mode being set.
6
5
7
To avoid this, we check to see what NaN mode we're running in before we call
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
floatxx_silence_nan().
7
Message-id: 20240130152548.17855-1-philmd@linaro.org
9
10
Signed-off-by: Joe Komlodi <joe.komlodi@xilinx.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 1624662174-175828-2-git-send-email-joe.komlodi@xilinx.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
target/arm/helper-a64.c | 12 +++++++++---
11
hw/arm/xilinx_zynq.c | 2 ++
17
target/arm/vfp_helper.c | 24 ++++++++++++++++++------
12
1 file changed, 2 insertions(+)
18
2 files changed, 27 insertions(+), 9 deletions(-)
19
13
20
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
14
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper-a64.c
16
--- a/hw/arm/xilinx_zynq.c
23
+++ b/target/arm/helper-a64.c
17
+++ b/hw/arm/xilinx_zynq.c
24
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
18
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
25
float16 nan = a;
19
sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
26
if (float16_is_signaling_nan(a, fpst)) {
20
sysbus_connect_irq(busdev, 0,
27
float_raise(float_flag_invalid, fpst);
21
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
28
- nan = float16_silence_nan(a, fpst);
22
+ sysbus_connect_irq(busdev, 1,
29
+ if (!fpst->default_nan_mode) {
23
+ qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ));
30
+ nan = float16_silence_nan(a, fpst);
24
31
+ }
25
for (n = 0; n < 64; n++) {
32
}
26
pic[n] = qdev_get_gpio_in(dev, n);
33
if (fpst->default_nan_mode) {
34
nan = float16_default_nan(fpst);
35
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
36
float32 nan = a;
37
if (float32_is_signaling_nan(a, fpst)) {
38
float_raise(float_flag_invalid, fpst);
39
- nan = float32_silence_nan(a, fpst);
40
+ if (!fpst->default_nan_mode) {
41
+ nan = float32_silence_nan(a, fpst);
42
+ }
43
}
44
if (fpst->default_nan_mode) {
45
nan = float32_default_nan(fpst);
46
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
47
float64 nan = a;
48
if (float64_is_signaling_nan(a, fpst)) {
49
float_raise(float_flag_invalid, fpst);
50
- nan = float64_silence_nan(a, fpst);
51
+ if (!fpst->default_nan_mode) {
52
+ nan = float64_silence_nan(a, fpst);
53
+ }
54
}
55
if (fpst->default_nan_mode) {
56
nan = float64_default_nan(fpst);
57
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/vfp_helper.c
60
+++ b/target/arm/vfp_helper.c
61
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
62
float16 nan = f16;
63
if (float16_is_signaling_nan(f16, fpst)) {
64
float_raise(float_flag_invalid, fpst);
65
- nan = float16_silence_nan(f16, fpst);
66
+ if (!fpst->default_nan_mode) {
67
+ nan = float16_silence_nan(f16, fpst);
68
+ }
69
}
70
if (fpst->default_nan_mode) {
71
nan = float16_default_nan(fpst);
72
@@ -XXX,XX +XXX,XX @@ float32 HELPER(recpe_f32)(float32 input, void *fpstp)
73
float32 nan = f32;
74
if (float32_is_signaling_nan(f32, fpst)) {
75
float_raise(float_flag_invalid, fpst);
76
- nan = float32_silence_nan(f32, fpst);
77
+ if (!fpst->default_nan_mode) {
78
+ nan = float32_silence_nan(f32, fpst);
79
+ }
80
}
81
if (fpst->default_nan_mode) {
82
nan = float32_default_nan(fpst);
83
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
84
float64 nan = f64;
85
if (float64_is_signaling_nan(f64, fpst)) {
86
float_raise(float_flag_invalid, fpst);
87
- nan = float64_silence_nan(f64, fpst);
88
+ if (!fpst->default_nan_mode) {
89
+ nan = float64_silence_nan(f64, fpst);
90
+ }
91
}
92
if (fpst->default_nan_mode) {
93
nan = float64_default_nan(fpst);
94
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(rsqrte_f16)(uint32_t input, void *fpstp)
95
float16 nan = f16;
96
if (float16_is_signaling_nan(f16, s)) {
97
float_raise(float_flag_invalid, s);
98
- nan = float16_silence_nan(f16, s);
99
+ if (!s->default_nan_mode) {
100
+ nan = float16_silence_nan(f16, fpstp);
101
+ }
102
}
103
if (s->default_nan_mode) {
104
nan = float16_default_nan(s);
105
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
106
float32 nan = f32;
107
if (float32_is_signaling_nan(f32, s)) {
108
float_raise(float_flag_invalid, s);
109
- nan = float32_silence_nan(f32, s);
110
+ if (!s->default_nan_mode) {
111
+ nan = float32_silence_nan(f32, fpstp);
112
+ }
113
}
114
if (s->default_nan_mode) {
115
nan = float32_default_nan(s);
116
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
117
float64 nan = f64;
118
if (float64_is_signaling_nan(f64, s)) {
119
float_raise(float_flag_invalid, s);
120
- nan = float64_silence_nan(f64, s);
121
+ if (!s->default_nan_mode) {
122
+ nan = float64_silence_nan(f64, fpstp);
123
+ }
124
}
125
if (s->default_nan_mode) {
126
nan = float64_default_nan(s);
127
--
27
--
128
2.20.1
28
2.34.1
129
29
130
30
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The API does not generate an error for setting ASYNC | SYNC; that merely
4
constrains the selection vs the per-cpu default. For qemu linux-user,
5
choose SYNC as the default.
6
7
Cc: qemu-stable@nongnu.org
8
Reported-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
11
Message-id: 20240207025210.8837-2-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
linux-user/aarch64/target_prctl.h | 29 +++++++++++++++++------------
15
1 file changed, 17 insertions(+), 12 deletions(-)
16
17
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/linux-user/aarch64/target_prctl.h
20
+++ b/linux-user/aarch64/target_prctl.h
21
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
22
env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE;
23
24
if (cpu_isar_feature(aa64_mte, cpu)) {
25
- switch (arg2 & PR_MTE_TCF_MASK) {
26
- case PR_MTE_TCF_NONE:
27
- case PR_MTE_TCF_SYNC:
28
- case PR_MTE_TCF_ASYNC:
29
- break;
30
- default:
31
- return -EINVAL;
32
- }
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].
60
--
61
2.34.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
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.
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")
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
14
Message-id: 20240207025210.8837-3-richard.henderson@linaro.org
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
target/arm/tcg/translate-sve.c | 16 ++++++++--------
19
1 file changed, 8 insertions(+), 8 deletions(-)
20
21
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/tcg/translate-sve.c
24
+++ b/target/arm/tcg/translate-sve.c
25
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
26
TCGv_ptr t_pg;
27
int desc = 0;
28
29
- /*
30
- * For e.g. LD4, there are not enough arguments to pass all 4
31
- * registers as pointers, so encode the regno into the data field.
32
- * For consistency, do this even for LD1.
33
- */
34
+ assert(mte_n >= 1 && mte_n <= 4);
35
if (s->mte_active[0]) {
36
int msz = dtype_msz(dtype);
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);
56
}
57
58
static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a)
59
@@ -XXX,XX +XXX,XX @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
60
if (nreg == 0) {
61
/* ST1 */
62
fn = fn_single[s->mte_active[0]][be][msz][esz];
63
- nreg = 1;
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)
75
--
76
2.34.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
When we added SVE_MTEDESC_SHIFT, we effectively limited the
4
maximum size of MTEDESC. Adjust SIZEM1 to consume the remaining
5
bits (32 - 10 - 5 - 12 == 5). Assert that the data to be stored
6
fits within the field (expecting 8 * 4 - 1 == 31, exact fit).
7
8
Cc: qemu-stable@nongnu.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
12
Message-id: 20240207025210.8837-4-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/internals.h | 2 +-
16
target/arm/tcg/translate-sve.c | 7 ++++---
17
2 files changed, 5 insertions(+), 4 deletions(-)
18
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/internals.h
22
+++ b/target/arm/internals.h
23
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, TBI, 4, 2)
24
FIELD(MTEDESC, TCMA, 6, 2)
25
FIELD(MTEDESC, WRITE, 8, 1)
26
FIELD(MTEDESC, ALIGN, 9, 3)
27
-FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - 12) /* size - 1 */
28
+FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - SVE_MTEDESC_SHIFT - 12) /* size - 1 */
29
30
bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
31
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
32
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/tcg/translate-sve.c
35
+++ b/target/arm/tcg/translate-sve.c
36
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
37
{
38
unsigned vsz = vec_full_reg_size(s);
39
TCGv_ptr t_pg;
40
+ uint32_t sizem1;
41
int desc = 0;
42
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);
58
--
59
2.34.1
diff view generated by jsdifflib
1
Implement the MVE shifts by immediate, which perform shifts
1
From: Richard Henderson <richard.henderson@linaro.org>
2
on a single general-purpose register.
3
2
4
These patterns overlap with the long-shift-by-immediates,
3
Share code that creates mtedesc and embeds within simd_desc.
5
so we have to rearrange the grouping a little here.
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>
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Message-id: 20240207025210.8837-5-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210628135835.6690-18-peter.maydell@linaro.org
10
---
11
---
11
target/arm/helper-mve.h | 3 ++
12
target/arm/tcg/translate-a64.h | 2 ++
12
target/arm/translate.h | 1 +
13
target/arm/tcg/translate-sme.c | 15 +++--------
13
target/arm/t32.decode | 31 ++++++++++++++-----
14
target/arm/tcg/translate-sve.c | 47 ++++++++++++++++++----------------
14
target/arm/mve_helper.c | 10 ++++++
15
3 files changed, 31 insertions(+), 33 deletions(-)
15
target/arm/translate.c | 68 +++++++++++++++++++++++++++++++++++++++--
16
5 files changed, 104 insertions(+), 9 deletions(-)
17
16
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
17
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper-mve.h
19
--- a/target/arm/tcg/translate-a64.h
21
+++ b/target/arm/helper-mve.h
20
+++ b/target/arm/tcg/translate-a64.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
21
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
23
DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
22
bool sve_access_check(DisasContext *s);
24
DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
23
bool sme_enabled_check(DisasContext *s);
25
DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
24
bool sme_enabled_check_with_svcr(DisasContext *s, unsigned);
25
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
26
+ uint32_t msz, bool is_write, uint32_t data);
27
28
/* This function corresponds to CheckStreamingSVEEnabled. */
29
static inline bool sme_sm_enabled_check(DisasContext *s)
30
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/tcg/translate-sme.c
33
+++ b/target/arm/tcg/translate-sme.c
34
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
35
36
TCGv_ptr t_za, t_pg;
37
TCGv_i64 addr;
38
- int svl, desc = 0;
39
+ uint32_t desc;
40
bool be = s->be_data == MO_BE;
41
bool mte = s->mte_active[0];
42
43
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
44
tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->esz);
45
tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
46
47
- if (mte) {
48
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
49
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
50
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
51
- desc = FIELD_DP32(desc, MTEDESC, WRITE, a->st);
52
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << a->esz) - 1);
53
- desc <<= SVE_MTEDESC_SHIFT;
54
- } else {
55
+ if (!mte) {
56
addr = clean_data_tbi(s, addr);
57
}
58
- svl = streaming_vec_reg_size(s);
59
- desc = simd_desc(svl, svl, desc);
26
+
60
+
27
+DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
61
+ desc = make_svemte_desc(s, streaming_vec_reg_size(s), 1, a->esz, a->st, 0);
28
+DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
62
29
diff --git a/target/arm/translate.h b/target/arm/translate.h
63
fns[a->esz][be][a->v][mte][a->st](tcg_env, t_za, t_pg, addr,
64
tcg_constant_i32(desc));
65
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
30
index XXXXXXX..XXXXXXX 100644
66
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate.h
67
--- a/target/arm/tcg/translate-sve.c
32
+++ b/target/arm/translate.h
68
+++ b/target/arm/tcg/translate-sve.c
33
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
69
@@ -XXX,XX +XXX,XX @@ static const uint8_t dtype_esz[16] = {
34
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
70
3, 2, 1, 3
35
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
71
};
36
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
72
37
+typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
73
-static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
38
74
- int dtype, uint32_t mte_n, bool is_write,
39
/**
75
- gen_helper_gvec_mem *fn)
40
* arm_tbflags_from_tb:
76
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
41
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
77
+ uint32_t msz, bool is_write, uint32_t data)
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/t32.decode
44
+++ b/target/arm/t32.decode
45
@@ -XXX,XX +XXX,XX @@
46
47
&mve_shl_ri rdalo rdahi shim
48
&mve_shl_rr rdalo rdahi rm
49
+&mve_sh_ri rda shim
50
51
# rdahi: bits [3:1] from insn, bit 0 is 1
52
# rdalo: bits [3:1] from insn, bit 0 is 0
53
@@ -XXX,XX +XXX,XX @@
54
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
55
@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
56
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
57
+@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
58
+ &mve_sh_ri shim=%imm5_12_6
59
60
{
78
{
61
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
79
- unsigned vsz = vec_full_reg_size(s);
62
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
80
- TCGv_ptr t_pg;
63
# the rest fall through (where ORR_rrri and MOV_rxri will end up
81
uint32_t sizem1;
64
# handling them as r13 and r15 accesses with the same semantics as A32).
82
- int desc = 0;
65
[
83
+ uint32_t desc = 0;
66
- LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
84
67
- LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
85
- assert(mte_n >= 1 && mte_n <= 4);
68
- ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
86
- sizem1 = (mte_n << dtype_msz(dtype)) - 1;
69
+ {
87
+ /* Assert all of the data fits, with or without MTE enabled. */
70
+ UQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 00 1111 @mve_sh_ri
88
+ assert(nregs >= 1 && nregs <= 4);
71
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
89
+ sizem1 = (nregs << msz) - 1;
72
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
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 {
73
+ }
101
+ }
74
102
+ return simd_desc(vsz, vsz, desc | data);
75
- UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
76
- URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
77
- SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
78
- SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
79
+ {
80
+ URSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 01 1111 @mve_sh_ri
81
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
82
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
83
+ }
84
+
85
+ {
86
+ SRSHR_ri 1110101 0010 1 .... 0 ... 1111 .. 10 1111 @mve_sh_ri
87
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
88
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
89
+ }
90
+
91
+ {
92
+ SQSHL_ri 1110101 0010 1 .... 0 ... 1111 .. 11 1111 @mve_sh_ri
93
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
94
+ }
95
96
LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
97
ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
98
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/mve_helper.c
101
+++ b/target/arm/mve_helper.c
102
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
103
{
104
return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
105
}
106
+
107
+uint32_t HELPER(mve_uqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
108
+{
109
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
110
+}
103
+}
111
+
104
+
112
+uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
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)
113
+{
108
+{
114
+ return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
109
+ TCGv_ptr t_pg;
115
+}
110
+ uint32_t desc;
116
diff --git a/target/arm/translate.c b/target/arm/translate.c
111
+
117
index XXXXXXX..XXXXXXX 100644
112
+ if (!s->mte_active[0]) {
118
--- a/target/arm/translate.c
113
addr = clean_data_tbi(s, addr);
119
+++ b/target/arm/translate.c
114
}
120
@@ -XXX,XX +XXX,XX @@ static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
115
121
116
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
122
static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
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)
123
{
129
{
124
- TCGv_i32 t = tcg_temp_new_i32();
130
- unsigned vsz = vec_full_reg_size(s);
125
+ TCGv_i32 t;
131
TCGv_ptr t_zm = tcg_temp_new_ptr();
126
132
TCGv_ptr t_pg = tcg_temp_new_ptr();
127
+ /* Handle shift by the input size for the benefit of trans_SRSHR_ri */
133
TCGv_ptr t_zt = tcg_temp_new_ptr();
128
+ if (sh == 32) {
134
- int desc = 0;
129
+ tcg_gen_movi_i32(d, 0);
135
-
130
+ return;
136
- if (s->mte_active[0]) {
131
+ }
137
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
132
+ t = tcg_temp_new_i32();
138
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
133
tcg_gen_extract_i32(t, a, sh - 1, 1);
139
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
134
tcg_gen_sari_i32(d, a, sh);
140
- desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
135
tcg_gen_add_i32(d, d, t);
141
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << msz) - 1);
136
@@ -XXX,XX +XXX,XX @@ static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
142
- desc <<= SVE_MTEDESC_SHIFT;
137
143
- }
138
static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
144
- desc = simd_desc(vsz, vsz, desc | scale);
139
{
145
+ uint32_t desc;
140
- TCGv_i32 t = tcg_temp_new_i32();
146
141
+ TCGv_i32 t;
147
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
142
148
tcg_gen_addi_ptr(t_zm, tcg_env, vec_full_reg_offset(s, zm));
143
+ /* Handle shift by the input size for the benefit of trans_URSHR_ri */
149
tcg_gen_addi_ptr(t_zt, tcg_env, vec_full_reg_offset(s, zt));
144
+ if (sh == 32) {
150
+
145
+ tcg_gen_extract_i32(d, a, sh - 1, 1);
151
+ desc = make_svemte_desc(s, vec_full_reg_size(s), 1, msz, is_write, scale);
146
+ return;
152
fn(tcg_env, t_zt, t_pg, t_zm, scalar, tcg_constant_i32(desc));
147
+ }
148
+ t = tcg_temp_new_i32();
149
tcg_gen_extract_i32(t, a, sh - 1, 1);
150
tcg_gen_shri_i32(d, a, sh);
151
tcg_gen_add_i32(d, d, t);
152
@@ -XXX,XX +XXX,XX @@ static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
153
return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
154
}
153
}
155
154
156
+static bool do_mve_sh_ri(DisasContext *s, arg_mve_sh_ri *a, ShiftImmFn *fn)
157
+{
158
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
159
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
160
+ return false;
161
+ }
162
+ if (!dc_isar_feature(aa32_mve, s) ||
163
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
164
+ a->rda == 13 || a->rda == 15) {
165
+ /* These rda cases are UNPREDICTABLE; we choose to UNDEF */
166
+ unallocated_encoding(s);
167
+ return true;
168
+ }
169
+
170
+ if (a->shim == 0) {
171
+ a->shim = 32;
172
+ }
173
+ fn(cpu_R[a->rda], cpu_R[a->rda], a->shim);
174
+
175
+ return true;
176
+}
177
+
178
+static bool trans_URSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
179
+{
180
+ return do_mve_sh_ri(s, a, gen_urshr32_i32);
181
+}
182
+
183
+static bool trans_SRSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
184
+{
185
+ return do_mve_sh_ri(s, a, gen_srshr32_i32);
186
+}
187
+
188
+static void gen_mve_sqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
189
+{
190
+ gen_helper_mve_sqshl(r, cpu_env, n, tcg_constant_i32(shift));
191
+}
192
+
193
+static bool trans_SQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
194
+{
195
+ return do_mve_sh_ri(s, a, gen_mve_sqshl);
196
+}
197
+
198
+static void gen_mve_uqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
199
+{
200
+ gen_helper_mve_uqshl(r, cpu_env, n, tcg_constant_i32(shift));
201
+}
202
+
203
+static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
204
+{
205
+ return do_mve_sh_ri(s, a, gen_mve_uqshl);
206
+}
207
+
208
/*
209
* Multiply and multiply accumulate
210
*/
211
--
155
--
212
2.20.1
156
2.34.1
213
214
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
These functions "use the standard load helpers", but
4
fail to clean_data_tbi or populate mtedesc.
5
6
Cc: qemu-stable@nongnu.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
10
Message-id: 20240207025210.8837-6-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/tcg/translate-sve.c | 15 +++++++++++++--
14
1 file changed, 13 insertions(+), 2 deletions(-)
15
16
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/tcg/translate-sve.c
19
+++ b/target/arm/tcg/translate-sve.c
20
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
21
unsigned vsz = vec_full_reg_size(s);
22
TCGv_ptr t_pg;
23
int poff;
24
+ uint32_t desc;
25
26
/* Load the first quadword using the normal predicated load helpers. */
27
+ if (!s->mte_active[0]) {
28
+ addr = clean_data_tbi(s, addr);
29
+ }
30
+
31
poff = pred_full_reg_offset(s, pg);
32
if (vsz > 16) {
33
/*
34
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
35
36
gen_helper_gvec_mem *fn
37
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
38
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(16, 16, zt)));
39
+ desc = make_svemte_desc(s, 16, 1, dtype_msz(dtype), false, zt);
40
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
41
42
/* Replicate that first quadword. */
43
if (vsz > 16) {
44
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
45
unsigned vsz_r32;
46
TCGv_ptr t_pg;
47
int poff, doff;
48
+ uint32_t desc;
49
50
if (vsz < 32) {
51
/*
52
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
53
}
54
55
/* Load the first octaword using the normal predicated load helpers. */
56
+ if (!s->mte_active[0]) {
57
+ addr = clean_data_tbi(s, addr);
58
+ }
59
60
poff = pred_full_reg_offset(s, pg);
61
if (vsz > 32) {
62
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
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.
72
--
73
2.34.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The TBI and TCMA bits are located within mtedesc, not desc.
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>
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Message-id: 20240207025210.8837-7-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/tcg/sme_helper.c | 8 ++++----
13
target/arm/tcg/sve_helper.c | 12 ++++++------
14
2 files changed, 10 insertions(+), 10 deletions(-)
15
16
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/tcg/sme_helper.c
19
+++ b/target/arm/tcg/sme_helper.c
20
@@ -XXX,XX +XXX,XX @@ void sme_ld1_mte(CPUARMState *env, void *za, uint64_t *vg,
21
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
22
23
/* Perform gross MTE suppression early. */
24
- if (!tbi_check(desc, bit55) ||
25
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
26
+ if (!tbi_check(mtedesc, bit55) ||
27
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
28
mtedesc = 0;
29
}
30
31
@@ -XXX,XX +XXX,XX @@ void sme_st1_mte(CPUARMState *env, void *za, uint64_t *vg, target_ulong addr,
32
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
33
34
/* Perform gross MTE suppression early. */
35
- if (!tbi_check(desc, bit55) ||
36
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
37
+ if (!tbi_check(mtedesc, bit55) ||
38
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
39
mtedesc = 0;
40
}
41
42
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/tcg/sve_helper.c
45
+++ b/target/arm/tcg/sve_helper.c
46
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
47
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
48
49
/* Perform gross MTE suppression early. */
50
- if (!tbi_check(desc, bit55) ||
51
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
52
+ if (!tbi_check(mtedesc, bit55) ||
53
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
54
mtedesc = 0;
55
}
56
57
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r_mte(CPUARMState *env, void *vg, target_ulong addr,
58
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
59
60
/* Perform gross MTE suppression early. */
61
- if (!tbi_check(desc, bit55) ||
62
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
63
+ if (!tbi_check(mtedesc, bit55) ||
64
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
65
mtedesc = 0;
66
}
67
68
@@ -XXX,XX +XXX,XX @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
69
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
70
71
/* Perform gross MTE suppression early. */
72
- if (!tbi_check(desc, bit55) ||
73
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
74
+ if (!tbi_check(mtedesc, bit55) ||
75
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
76
mtedesc = 0;
77
}
78
79
--
80
2.34.1
diff view generated by jsdifflib
1
From: Patrick Venture <venture@google.com>
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
Adds a line-item reference to the supported quanta-q71l-bmc aspeed
11
Fortunately raven_io_read() and raven_io_write() will correctly deal
4
entry.
12
with the case of being passed an unaligned address, so we can fix the
13
missing unaligned access support by setting .impl.unaligned in the
14
MemoryRegionOps struct.
5
15
6
Signed-off-by: Patrick Venture <venture@google.com>
16
Fixes: 9a1839164c9c8f06 ("raven: Implement non-contiguous I/O region")
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20210615192848.1065297-2-venture@google.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Tested-by: Cédric Le Goater <clg@redhat.com>
19
Reviewed-by: Cédric Le Goater <clg@redhat.com>
20
Message-id: 20240112134640.1775041-1-peter.maydell@linaro.org
10
---
21
---
11
docs/system/arm/aspeed.rst | 1 +
22
hw/pci-host/raven.c | 1 +
12
1 file changed, 1 insertion(+)
23
1 file changed, 1 insertion(+)
13
24
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
25
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
15
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/aspeed.rst
27
--- a/hw/pci-host/raven.c
17
+++ b/docs/system/arm/aspeed.rst
28
+++ b/hw/pci-host/raven.c
18
@@ -XXX,XX +XXX,XX @@ etc.
29
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps raven_io_ops = {
19
AST2400 SoC based machines :
30
.write = raven_io_write,
20
31
.endianness = DEVICE_LITTLE_ENDIAN,
21
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
32
.impl.max_access_size = 4,
22
+- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
33
+ .impl.unaligned = true,
23
34
.valid.unaligned = true,
24
AST2500 SoC based machines :
35
};
25
36
26
--
37
--
27
2.20.1
38
2.34.1
28
39
29
40
diff view generated by jsdifflib
1
Implement the MVE long shifts by register, which perform shifts on a
1
Suppress the deprecation warning when we're running under qtest,
2
pair of general-purpose registers treated as a 64-bit quantity, with
2
to avoid "make check" including warning messages in its output.
3
the shift count in another general-purpose register, which might be
4
either positive or negative.
5
6
Like the long-shifts-by-immediate, these encodings sit in the space
7
that was previously the UNPREDICTABLE MOVS/ORRS with Rm==13,15.
8
Because LSLL_rr and ASRL_rr overlap with both MOV_rxri/ORR_rrri and
9
also with CSEL (as one of the previously-UNPREDICTABLE Rm==13 cases),
10
we have to move the CSEL pattern into the same decodetree group.
11
3
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Message-id: 20210628135835.6690-17-peter.maydell@linaro.org
6
Message-id: 20240206154151.155620-1-peter.maydell@linaro.org
15
---
7
---
16
target/arm/helper-mve.h | 6 +++
8
hw/block/tc58128.c | 4 +++-
17
target/arm/translate.h | 1 +
9
1 file changed, 3 insertions(+), 1 deletion(-)
18
target/arm/t32.decode | 16 +++++--
19
target/arm/mve_helper.c | 93 +++++++++++++++++++++++++++++++++++++++++
20
target/arm/translate.c | 69 ++++++++++++++++++++++++++++++
21
5 files changed, 182 insertions(+), 3 deletions(-)
22
10
23
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
11
diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c
24
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper-mve.h
13
--- a/hw/block/tc58128.c
26
+++ b/target/arm/helper-mve.h
14
+++ b/hw/block/tc58128.c
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
15
@@ -XXX,XX +XXX,XX @@ static sh7750_io_device tc58128 = {
28
16
29
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
17
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2)
30
31
+DEF_HELPER_FLAGS_3(mve_sshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
32
+DEF_HELPER_FLAGS_3(mve_ushll, TCG_CALL_NO_RWG, i64, env, i64, i32)
33
DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
34
DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
35
+DEF_HELPER_FLAGS_3(mve_sqrshrl, TCG_CALL_NO_RWG, i64, env, i64, i32)
36
+DEF_HELPER_FLAGS_3(mve_uqrshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
37
+DEF_HELPER_FLAGS_3(mve_sqrshrl48, TCG_CALL_NO_RWG, i64, env, i64, i32)
38
+DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
39
diff --git a/target/arm/translate.h b/target/arm/translate.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate.h
42
+++ b/target/arm/translate.h
43
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
44
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
45
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
46
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
47
+typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
48
49
/**
50
* arm_tbflags_from_tb:
51
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/t32.decode
54
+++ b/target/arm/t32.decode
55
@@ -XXX,XX +XXX,XX @@
56
&mcrr !extern cp opc1 crm rt rt2
57
58
&mve_shl_ri rdalo rdahi shim
59
+&mve_shl_rr rdalo rdahi rm
60
61
# rdahi: bits [3:1] from insn, bit 0 is 1
62
# rdalo: bits [3:1] from insn, bit 0 is 0
63
@@ -XXX,XX +XXX,XX @@
64
65
@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
66
&mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
67
+@mve_shl_rr ....... .... . ... . rm:4 ... . .. .. .... \
68
+ &mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
69
70
{
18
{
71
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
19
- warn_report_once("The TC58128 flash device is deprecated");
72
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
20
+ if (!qtest_enabled()) {
73
URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
21
+ warn_report_once("The TC58128 flash device is deprecated");
74
SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
75
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
76
+
77
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
78
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
79
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
80
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
81
+ UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
82
+ SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
83
]
84
85
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
86
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
87
+
88
+ # v8.1M CSEL and friends
89
+ CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
90
}
91
{
92
MVN_rxri 1110101 0011 . 1111 0 ... .... .... .... @s_rxr_shi
93
@@ -XXX,XX +XXX,XX @@ SBC_rrri 1110101 1011 . .... 0 ... .... .... .... @s_rrr_shi
94
}
95
RSB_rrri 1110101 1110 . .... 0 ... .... .... .... @s_rrr_shi
96
97
-# v8.1M CSEL and friends
98
-CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
99
-
100
# Data-processing (register-shifted register)
101
102
MOV_rxrr 1111 1010 0 shty:2 s:1 rm:4 1111 rd:4 0000 rs:4 \
103
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/target/arm/mve_helper.c
106
+++ b/target/arm/mve_helper.c
107
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
108
return rdm;
109
}
110
111
+uint64_t HELPER(mve_sshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
112
+{
113
+ return do_sqrshl_d(n, -(int8_t)shift, false, NULL);
114
+}
115
+
116
+uint64_t HELPER(mve_ushll)(CPUARMState *env, uint64_t n, uint32_t shift)
117
+{
118
+ return do_uqrshl_d(n, (int8_t)shift, false, NULL);
119
+}
120
+
121
uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
122
{
123
return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
124
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
125
{
126
return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
127
}
128
+
129
+uint64_t HELPER(mve_sqrshrl)(CPUARMState *env, uint64_t n, uint32_t shift)
130
+{
131
+ return do_sqrshl_d(n, -(int8_t)shift, true, &env->QF);
132
+}
133
+
134
+uint64_t HELPER(mve_uqrshll)(CPUARMState *env, uint64_t n, uint32_t shift)
135
+{
136
+ return do_uqrshl_d(n, (int8_t)shift, true, &env->QF);
137
+}
138
+
139
+/* Operate on 64-bit values, but saturate at 48 bits */
140
+static inline int64_t do_sqrshl48_d(int64_t src, int64_t shift,
141
+ bool round, uint32_t *sat)
142
+{
143
+ if (shift <= -48) {
144
+ /* Rounding the sign bit always produces 0. */
145
+ if (round) {
146
+ return 0;
147
+ }
148
+ return src >> 63;
149
+ } else if (shift < 0) {
150
+ if (round) {
151
+ src >>= -shift - 1;
152
+ return (src >> 1) + (src & 1);
153
+ }
154
+ return src >> -shift;
155
+ } else if (shift < 48) {
156
+ int64_t val = src << shift;
157
+ int64_t extval = sextract64(val, 0, 48);
158
+ if (!sat || val == extval) {
159
+ return extval;
160
+ }
161
+ } else if (!sat || src == 0) {
162
+ return 0;
163
+ }
22
+ }
164
+
23
init_dev(&tc58128_devs[0], zone1);
165
+ *sat = 1;
24
init_dev(&tc58128_devs[1], zone2);
166
+ return (1ULL << 47) - (src >= 0);
25
return sh7750_register_io_device(s, &tc58128);
167
+}
168
+
169
+/* Operate on 64-bit values, but saturate at 48 bits */
170
+static inline uint64_t do_uqrshl48_d(uint64_t src, int64_t shift,
171
+ bool round, uint32_t *sat)
172
+{
173
+ uint64_t val, extval;
174
+
175
+ if (shift <= -(48 + round)) {
176
+ return 0;
177
+ } else if (shift < 0) {
178
+ if (round) {
179
+ val = src >> (-shift - 1);
180
+ val = (val >> 1) + (val & 1);
181
+ } else {
182
+ val = src >> -shift;
183
+ }
184
+ extval = extract64(val, 0, 48);
185
+ if (!sat || val == extval) {
186
+ return extval;
187
+ }
188
+ } else if (shift < 48) {
189
+ uint64_t val = src << shift;
190
+ uint64_t extval = extract64(val, 0, 48);
191
+ if (!sat || val == extval) {
192
+ return extval;
193
+ }
194
+ } else if (!sat || src == 0) {
195
+ return 0;
196
+ }
197
+
198
+ *sat = 1;
199
+ return MAKE_64BIT_MASK(0, 48);
200
+}
201
+
202
+uint64_t HELPER(mve_sqrshrl48)(CPUARMState *env, uint64_t n, uint32_t shift)
203
+{
204
+ return do_sqrshl48_d(n, -(int8_t)shift, true, &env->QF);
205
+}
206
+
207
+uint64_t HELPER(mve_uqrshll48)(CPUARMState *env, uint64_t n, uint32_t shift)
208
+{
209
+ return do_uqrshl48_d(n, (int8_t)shift, true, &env->QF);
210
+}
211
diff --git a/target/arm/translate.c b/target/arm/translate.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/target/arm/translate.c
214
+++ b/target/arm/translate.c
215
@@ -XXX,XX +XXX,XX @@ static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
216
return do_mve_shl_ri(s, a, gen_urshr64_i64);
217
}
218
219
+static bool do_mve_shl_rr(DisasContext *s, arg_mve_shl_rr *a, WideShiftFn *fn)
220
+{
221
+ TCGv_i64 rda;
222
+ TCGv_i32 rdalo, rdahi;
223
+
224
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
225
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
226
+ return false;
227
+ }
228
+ if (a->rdahi == 15) {
229
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
230
+ return false;
231
+ }
232
+ if (!dc_isar_feature(aa32_mve, s) ||
233
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
234
+ a->rdahi == 13 || a->rm == 13 || a->rm == 15 ||
235
+ a->rm == a->rdahi || a->rm == a->rdalo) {
236
+ /* These rdahi/rdalo/rm cases are UNPREDICTABLE; we choose to UNDEF */
237
+ unallocated_encoding(s);
238
+ return true;
239
+ }
240
+
241
+ rda = tcg_temp_new_i64();
242
+ rdalo = load_reg(s, a->rdalo);
243
+ rdahi = load_reg(s, a->rdahi);
244
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
245
+
246
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
247
+ fn(rda, cpu_env, rda, cpu_R[a->rm]);
248
+
249
+ tcg_gen_extrl_i64_i32(rdalo, rda);
250
+ tcg_gen_extrh_i64_i32(rdahi, rda);
251
+ store_reg(s, a->rdalo, rdalo);
252
+ store_reg(s, a->rdahi, rdahi);
253
+ tcg_temp_free_i64(rda);
254
+
255
+ return true;
256
+}
257
+
258
+static bool trans_LSLL_rr(DisasContext *s, arg_mve_shl_rr *a)
259
+{
260
+ return do_mve_shl_rr(s, a, gen_helper_mve_ushll);
261
+}
262
+
263
+static bool trans_ASRL_rr(DisasContext *s, arg_mve_shl_rr *a)
264
+{
265
+ return do_mve_shl_rr(s, a, gen_helper_mve_sshrl);
266
+}
267
+
268
+static bool trans_UQRSHLL64_rr(DisasContext *s, arg_mve_shl_rr *a)
269
+{
270
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll);
271
+}
272
+
273
+static bool trans_SQRSHRL64_rr(DisasContext *s, arg_mve_shl_rr *a)
274
+{
275
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl);
276
+}
277
+
278
+static bool trans_UQRSHLL48_rr(DisasContext *s, arg_mve_shl_rr *a)
279
+{
280
+ return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll48);
281
+}
282
+
283
+static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
284
+{
285
+ return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
286
+}
287
+
288
/*
289
* Multiply and multiply accumulate
290
*/
291
--
26
--
292
2.20.1
27
2.34.1
293
28
294
29
diff view generated by jsdifflib
1
The MVE extension to v8.1M includes some new shift instructions which
1
We deliberately don't include qtests_npcm7xx in qtests_aarch64,
2
sit entirely within the non-coprocessor part of the encoding space
2
because we already get the coverage of those tests via qtests_arm,
3
and which operate only on general-purpose registers. They take up
3
and we don't want to use extra CI minutes testing them twice.
4
the space which was previously UNPREDICTABLE MOVS and ORRS encodings
5
with Rm == 13 or 15.
6
4
7
Implement the long shifts by immediate, which perform shifts on a
5
In commit 327b680877b79c4b we added it to qtests_aarch64; revert
8
pair of general-purpose registers treated as a 64-bit quantity, with
6
that change.
9
an immediate shift count between 1 and 32.
10
7
11
Awkwardly, because the MOVS and ORRS trans functions do not UNDEF for
8
Fixes: 327b680877b79c4b ("tests/qtest: Creating qtest for GMAC Module")
12
the Rm==13,15 case, we need to explicitly emit code to UNDEF for the
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
cases where v8.1M now requires that. (Trying to change MOVS and ORRS
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
is too difficult, because the functions that generate the code are
11
Message-id: 20240206163043.315535-1-peter.maydell@linaro.org
15
shared between a dozen different kinds of arithmetic or logical
12
---
16
instruction for all A32, T16 and T32 encodings, and for some insns
13
tests/qtest/meson.build | 1 -
17
and some encodings Rm==13,15 are valid.)
14
1 file changed, 1 deletion(-)
18
15
19
We make the helper functions we need for UQSHLL and SQSHLL take
16
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
20
a 32-bit value which the helper casts to int8_t because we'll need
21
these helpers also for the shift-by-register insns, where the shift
22
count might be < 0 or > 32.
23
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20210628135835.6690-16-peter.maydell@linaro.org
27
---
28
target/arm/helper-mve.h | 3 ++
29
target/arm/translate.h | 1 +
30
target/arm/t32.decode | 28 +++++++++++++
31
target/arm/mve_helper.c | 10 +++++
32
target/arm/translate.c | 90 +++++++++++++++++++++++++++++++++++++++++
33
5 files changed, 132 insertions(+)
34
35
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
36
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper-mve.h
18
--- a/tests/qtest/meson.build
38
+++ b/target/arm/helper-mve.h
19
+++ b/tests/qtest/meson.build
39
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
@@ -XXX,XX +XXX,XX @@ qtests_aarch64 = \
40
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
41
22
(config_all_accel.has_key('CONFIG_TCG') and \
42
DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
23
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
43
+
24
- (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
44
+DEF_HELPER_FLAGS_3(mve_sqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
25
['arm-cpu-features',
45
+DEF_HELPER_FLAGS_3(mve_uqshll, TCG_CALL_NO_RWG, i64, env, i64, i32)
26
'numa-test',
46
diff --git a/target/arm/translate.h b/target/arm/translate.h
27
'boot-serial-test',
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate.h
49
+++ b/target/arm/translate.h
50
@@ -XXX,XX +XXX,XX @@ typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
51
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
52
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
53
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
54
+typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
55
56
/**
57
* arm_tbflags_from_tb:
58
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/t32.decode
61
+++ b/target/arm/t32.decode
62
@@ -XXX,XX +XXX,XX @@
63
&mcr !extern cp opc1 crn crm opc2 rt
64
&mcrr !extern cp opc1 crm rt rt2
65
66
+&mve_shl_ri rdalo rdahi shim
67
+
68
+# rdahi: bits [3:1] from insn, bit 0 is 1
69
+# rdalo: bits [3:1] from insn, bit 0 is 0
70
+%rdahi_9 9:3 !function=times_2_plus_1
71
+%rdalo_17 17:3 !function=times_2
72
+
73
# Data-processing (register)
74
75
%imm5_12_6 12:3 6:2
76
@@ -XXX,XX +XXX,XX @@
77
@S_xrr_shi ....... .... . rn:4 .... .... .. shty:2 rm:4 \
78
&s_rrr_shi shim=%imm5_12_6 s=1 rd=0
79
80
+@mve_shl_ri ....... .... . ... . . ... ... . .. .. .... \
81
+ &mve_shl_ri shim=%imm5_12_6 rdalo=%rdalo_17 rdahi=%rdahi_9
82
+
83
{
84
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
85
AND_rrri 1110101 0000 . .... 0 ... .... .... .... @s_rrr_shi
86
}
87
BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
88
{
89
+ # The v8.1M MVE shift insns overlap in encoding with MOVS/ORRS
90
+ # and are distinguished by having Rm==13 or 15. Those are UNPREDICTABLE
91
+ # cases for MOVS/ORRS. We decode the MVE cases first, ensuring that
92
+ # they explicitly call unallocated_encoding() for cases that must UNDEF
93
+ # (eg "using a new shift insn on a v8.1M CPU without MVE"), and letting
94
+ # the rest fall through (where ORR_rrri and MOV_rxri will end up
95
+ # handling them as r13 and r15 accesses with the same semantics as A32).
96
+ [
97
+ LSLL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 00 1111 @mve_shl_ri
98
+ LSRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 01 1111 @mve_shl_ri
99
+ ASRL_ri 1110101 0010 1 ... 0 0 ... ... 1 .. 10 1111 @mve_shl_ri
100
+
101
+ UQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 00 1111 @mve_shl_ri
102
+ URSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 01 1111 @mve_shl_ri
103
+ SRSHRL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 10 1111 @mve_shl_ri
104
+ SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
105
+ ]
106
+
107
MOV_rxri 1110101 0010 . 1111 0 ... .... .... .... @s_rxr_shi
108
ORR_rrri 1110101 0010 . .... 0 ... .... .... .... @s_rrr_shi
109
}
110
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/target/arm/mve_helper.c
113
+++ b/target/arm/mve_helper.c
114
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
115
mve_advance_vpt(env);
116
return rdm;
117
}
118
+
119
+uint64_t HELPER(mve_sqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
120
+{
121
+ return do_sqrshl_d(n, (int8_t)shift, false, &env->QF);
122
+}
123
+
124
+uint64_t HELPER(mve_uqshll)(CPUARMState *env, uint64_t n, uint32_t shift)
125
+{
126
+ return do_uqrshl_d(n, (int8_t)shift, false, &env->QF);
127
+}
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/target/arm/translate.c
131
+++ b/target/arm/translate.c
132
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
133
return true;
134
}
135
136
+/*
137
+ * v8.1M MVE wide-shifts
138
+ */
139
+static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
140
+ WideShiftImmFn *fn)
141
+{
142
+ TCGv_i64 rda;
143
+ TCGv_i32 rdalo, rdahi;
144
+
145
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
146
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
147
+ return false;
148
+ }
149
+ if (a->rdahi == 15) {
150
+ /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
151
+ return false;
152
+ }
153
+ if (!dc_isar_feature(aa32_mve, s) ||
154
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
155
+ a->rdahi == 13) {
156
+ /* RdaHi == 13 is UNPREDICTABLE; we choose to UNDEF */
157
+ unallocated_encoding(s);
158
+ return true;
159
+ }
160
+
161
+ if (a->shim == 0) {
162
+ a->shim = 32;
163
+ }
164
+
165
+ rda = tcg_temp_new_i64();
166
+ rdalo = load_reg(s, a->rdalo);
167
+ rdahi = load_reg(s, a->rdahi);
168
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
169
+
170
+ fn(rda, rda, a->shim);
171
+
172
+ tcg_gen_extrl_i64_i32(rdalo, rda);
173
+ tcg_gen_extrh_i64_i32(rdahi, rda);
174
+ store_reg(s, a->rdalo, rdalo);
175
+ store_reg(s, a->rdahi, rdahi);
176
+ tcg_temp_free_i64(rda);
177
+
178
+ return true;
179
+}
180
+
181
+static bool trans_ASRL_ri(DisasContext *s, arg_mve_shl_ri *a)
182
+{
183
+ return do_mve_shl_ri(s, a, tcg_gen_sari_i64);
184
+}
185
+
186
+static bool trans_LSLL_ri(DisasContext *s, arg_mve_shl_ri *a)
187
+{
188
+ return do_mve_shl_ri(s, a, tcg_gen_shli_i64);
189
+}
190
+
191
+static bool trans_LSRL_ri(DisasContext *s, arg_mve_shl_ri *a)
192
+{
193
+ return do_mve_shl_ri(s, a, tcg_gen_shri_i64);
194
+}
195
+
196
+static void gen_mve_sqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
197
+{
198
+ gen_helper_mve_sqshll(r, cpu_env, n, tcg_constant_i32(shift));
199
+}
200
+
201
+static bool trans_SQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
202
+{
203
+ return do_mve_shl_ri(s, a, gen_mve_sqshll);
204
+}
205
+
206
+static void gen_mve_uqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
207
+{
208
+ gen_helper_mve_uqshll(r, cpu_env, n, tcg_constant_i32(shift));
209
+}
210
+
211
+static bool trans_UQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
212
+{
213
+ return do_mve_shl_ri(s, a, gen_mve_uqshll);
214
+}
215
+
216
+static bool trans_SRSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
217
+{
218
+ return do_mve_shl_ri(s, a, gen_srshr64_i64);
219
+}
220
+
221
+static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
222
+{
223
+ return do_mve_shl_ri(s, a, gen_urshr64_i64);
224
+}
225
+
226
/*
227
* Multiply and multiply accumulate
228
*/
229
--
28
--
230
2.20.1
29
2.34.1
231
30
232
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
Implement the MVE logical-immediate insns (VMOV, VMVN,
1
Armv8.1+ CPUs have the Virtual Host Extension (VHE) which adds a
2
VORR and VBIC). These have essentially the same encoding
2
non-secure EL2 virtual timer. We implemented the timer itself in the
3
as their Neon equivalents, and we implement the decode
3
CPU model, but never wired up its IRQ line to the GIC.
4
in the same way.
4
5
Wire up the IRQ line (this is always safe whether the CPU has the
6
interrupt or not, since it always creates the outbound IRQ line).
7
Report it to the guest via dtb and ACPI if the CPU has the feature.
8
9
The DTB binding is documented in the kernel's
10
Documentation/devicetree/bindings/timer/arm\,arch_timer.yaml
11
and the ACPI table entries are documented in the ACPI specification
12
version 6.3 or later.
13
14
Because the IRQ line ACPI binding is new in 6.3, we need to bump the
15
FADT table rev to show that we might be using 6.3 features.
16
17
Note that exposing this IRQ in the DTB will trigger a bug in EDK2
18
versions prior to edk2-stable202311, for users who use the virt board
19
with 'virtualization=on' to enable EL2 emulation and are booting an
20
EDK2 guest BIOS, if that EDK2 has assertions enabled. The effect is
21
that EDK2 will assert on bootup:
22
23
ASSERT [ArmTimerDxe] /home/kraxel/projects/qemu/roms/edk2/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.c(72): PropSize == 36 || PropSize == 48
24
25
If you see that assertion you should do one of:
26
* update your EDK2 binaries to edk2-stable202311 or newer
27
* use the 'virt-8.2' versioned machine type
28
* not use 'virtualization=on'
29
30
(The versions shipped with QEMU itself have the fix.)
5
31
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
33
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
8
Message-id: 20210628135835.6690-7-peter.maydell@linaro.org
34
Message-id: 20240122143537.233498-3-peter.maydell@linaro.org
9
---
35
---
10
target/arm/helper-mve.h | 4 +++
36
include/hw/arm/virt.h | 2 ++
11
target/arm/mve.decode | 17 +++++++++++++
37
hw/arm/virt-acpi-build.c | 20 ++++++++++----
12
target/arm/mve_helper.c | 24 ++++++++++++++++++
38
hw/arm/virt.c | 60 ++++++++++++++++++++++++++++++++++------
13
target/arm/translate-mve.c | 50 ++++++++++++++++++++++++++++++++++++++
39
3 files changed, 67 insertions(+), 15 deletions(-)
14
4 files changed, 95 insertions(+)
40
15
41
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
17
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-mve.h
43
--- a/include/hw/arm/virt.h
19
+++ b/target/arm/helper-mve.h
44
+++ b/include/hw/arm/virt.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvsh, TCG_CALL_NO_WG, i32, env, ptr, i32)
45
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
21
DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
46
/* Machines < 6.2 have no support for describing cpu topology to guest */
22
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
47
bool no_cpu_topology;
23
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
48
bool no_tcg_lpa2;
24
+
49
+ bool no_ns_el2_virt_timer_irq;
25
+DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
50
};
26
+DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
51
27
+DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
52
struct VirtMachineState {
28
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
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
29
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/mve.decode
63
--- a/hw/arm/virt-acpi-build.c
31
+++ b/target/arm/mve.decode
64
+++ b/hw/arm/virt-acpi-build.c
32
@@ -XXX,XX +XXX,XX @@
65
@@ -XXX,XX +XXX,XX @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
33
# VQDMULL has size in bit 28: 0 for 16 bit, 1 for 32 bit
66
}
34
%size_28 28:1 !function=plus_1
67
35
68
/*
36
+# 1imm format immediate
69
- * ACPI spec, Revision 5.1
37
+%imm_28_16_0 28:1 16:3 0:4
70
- * 5.2.24 Generic Timer Description Table (GTDT)
38
+
71
+ * ACPI spec, Revision 6.5
39
&vldr_vstr rn qd imm p a w size l u
72
+ * 5.2.25 Generic Timer Description Table (GTDT)
40
&1op qd qm size
73
*/
41
&2op qd qm qn size
74
static void
42
&2scalar qd qn rm size
75
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
43
+&1imm qd imm cmode op
76
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
44
77
uint32_t irqflags = vmc->claim_edge_triggered_timers ?
45
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
78
1 : /* Interrupt is Edge triggered */
46
# Note that both Rn and Qd are 3 bits only (no D bit)
79
0; /* Interrupt is Level triggered */
47
@@ -XXX,XX +XXX,XX @@
80
- AcpiTable table = { .sig = "GTDT", .rev = 2, .oem_id = vms->oem_id,
48
@2op_nosz .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn size=0
81
+ AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id,
49
@2op_sz28 .... .... .... .... .... .... .... .... &2op qd=%qd qm=%qm qn=%qn \
82
.oem_table_id = vms->oem_table_id };
50
size=%size_28
83
51
+@1imm .... .... .... .... .... cmode:4 .. op:1 . .... &1imm qd=%qd imm=%imm_28_16_0
84
acpi_table_begin(&table, table_data);
52
85
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
53
# The _rev suffix indicates that Vn and Vm are reversed. This is
86
build_append_int_noprefix(table_data, 0, 4);
54
# the case for shifts. In the Arm ARM these insns are documented
87
/* Platform Timer Offset */
55
@@ -XXX,XX +XXX,XX @@ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rd
88
build_append_int_noprefix(table_data, 0, 4);
56
# Predicate operations
89
-
57
%mask_22_13 22:1 13:3
90
+ if (vms->ns_el2_virt_timer_irq) {
58
VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
91
+ /* Virtual EL2 Timer GSIV */
59
+
92
+ build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL2_VIRT_IRQ, 4);
60
+# Logical immediate operations (1 reg and modified-immediate)
93
+ /* Virtual EL2 Timer Flags */
61
+
94
+ build_append_int_noprefix(table_data, irqflags, 4);
62
+# The cmode/op bits here decode VORR/VBIC/VMOV/VMVN, but
95
+ } else {
63
+# not in a way we can conveniently represent in decodetree without
96
+ build_append_int_noprefix(table_data, 0, 4);
64
+# a lot of repetition:
97
+ build_append_int_noprefix(table_data, 0, 4);
65
+# VORR: op=0, (cmode & 1) && cmode < 12
98
+ }
66
+# VBIC: op=1, (cmode & 1) && cmode < 12
99
acpi_table_end(linker, &table);
67
+# VMOV: everything else
100
}
68
+# So we have a single decode line and check the cmode/op in the
101
69
+# trans function.
102
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
70
+Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
103
static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker,
71
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
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
72
index XXXXXXX..XXXXXXX 100644
116
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/mve_helper.c
117
--- a/hw/arm/virt.c
74
+++ b/target/arm/mve_helper.c
118
+++ b/hw/arm/virt.c
75
@@ -XXX,XX +XXX,XX @@ DO_1OP(vnegw, 4, int32_t, DO_NEG)
119
@@ -XXX,XX +XXX,XX @@ static void create_randomness(MachineState *ms, const char *node)
76
DO_1OP(vfnegh, 8, uint64_t, DO_FNEGH)
120
qemu_fdt_setprop(ms->fdt, node, "rng-seed", seed.rng, sizeof(seed.rng));
77
DO_1OP(vfnegs, 8, uint64_t, DO_FNEGS)
121
}
78
122
79
+/*
123
+/*
80
+ * 1 operand immediates: Vda is destination and possibly also one source.
124
+ * The CPU object always exposes the NS EL2 virt timer IRQ line,
81
+ * All these insns work at 64-bit widths.
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.
82
+ */
127
+ */
83
+#define DO_1OP_IMM(OP, FN) \
128
+static bool ns_el2_virt_timer_present(void)
84
+ void HELPER(mve_##OP)(CPUARMState *env, void *vda, uint64_t imm) \
129
+{
85
+ { \
130
+ ARMCPU *cpu = ARM_CPU(qemu_get_cpu(0));
86
+ uint64_t *da = vda; \
131
+ CPUARMState *env = &cpu->env;
87
+ uint16_t mask = mve_element_mask(env); \
132
+
88
+ unsigned e; \
133
+ return arm_feature(env, ARM_FEATURE_AARCH64) &&
89
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
134
+ arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu);
90
+ mergemask(&da[H8(e)], FN(da[H8(e)], imm), mask); \
135
+}
91
+ } \
136
+
92
+ mve_advance_vpt(env); \
137
static void create_fdt(VirtMachineState *vms)
138
{
139
MachineState *ms = MACHINE(vms);
140
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
141
"arm,armv7-timer");
142
}
143
qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0);
144
- qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
145
- GIC_FDT_IRQ_TYPE_PPI,
146
- INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
147
- GIC_FDT_IRQ_TYPE_PPI,
148
- INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
149
- GIC_FDT_IRQ_TYPE_PPI,
150
- INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
151
- GIC_FDT_IRQ_TYPE_PPI,
152
- INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
153
+ if (vms->ns_el2_virt_timer_irq) {
154
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
155
+ GIC_FDT_IRQ_TYPE_PPI,
156
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
157
+ GIC_FDT_IRQ_TYPE_PPI,
158
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
159
+ GIC_FDT_IRQ_TYPE_PPI,
160
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
161
+ GIC_FDT_IRQ_TYPE_PPI,
162
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags,
163
+ GIC_FDT_IRQ_TYPE_PPI,
164
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_VIRT_IRQ), irqflags);
165
+ } else {
166
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
167
+ GIC_FDT_IRQ_TYPE_PPI,
168
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
169
+ GIC_FDT_IRQ_TYPE_PPI,
170
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
171
+ GIC_FDT_IRQ_TYPE_PPI,
172
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
173
+ GIC_FDT_IRQ_TYPE_PPI,
174
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
93
+ }
175
+ }
94
+
176
}
95
+#define DO_MOVI(N, I) (I)
177
96
+#define DO_ANDI(N, I) ((N) & (I))
178
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
97
+#define DO_ORRI(N, I) ((N) | (I))
179
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
98
+
180
[GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
99
+DO_1OP_IMM(vmovi, DO_MOVI)
181
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
100
+DO_1OP_IMM(vandi, DO_ANDI)
182
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
101
+DO_1OP_IMM(vorri, DO_ORRI)
183
+ [GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
102
+
184
};
103
#define DO_2OP(OP, ESIZE, TYPE, FN) \
185
104
void HELPER(glue(mve_, OP))(CPUARMState *env, \
186
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
105
void *vd, void *vn, void *vm) \
187
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
106
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
188
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
107
index XXXXXXX..XXXXXXX 100644
189
object_unref(cpuobj);
108
--- a/target/arm/translate-mve.c
190
}
109
+++ b/target/arm/translate-mve.c
191
+
110
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
192
+ /* Now we've created the CPUs we can see if they have the hypvirt timer */
111
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
193
+ vms->ns_el2_virt_timer_irq = ns_el2_virt_timer_present() &&
112
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
194
+ !vmc->no_ns_el2_virt_timer_irq;
113
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
195
+
114
+typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
196
fdt_add_timer_nodes(vms);
115
197
fdt_add_cpu_nodes(vms);
116
/* Return the offset of a Qn register (same semantics as aa32_vfp_qreg()) */
198
117
static inline long mve_qreg_offset(unsigned reg)
199
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(9, 0)
118
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
200
119
mve_update_eci(s);
201
static void virt_machine_8_2_options(MachineClass *mc)
120
return true;
202
{
121
}
203
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
122
+
204
+
123
+static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
205
virt_machine_9_0_options(mc);
124
+{
206
compat_props_add(mc->compat_props, hw_compat_8_2, hw_compat_8_2_len);
125
+ TCGv_ptr qd;
207
+ /*
126
+ uint64_t imm;
208
+ * Don't expose NS_EL2_VIRT timer IRQ in DTB on ACPI on 8.2 and
127
+
209
+ * earlier machines. (Exposing it tickles a bug in older EDK2
128
+ if (!dc_isar_feature(aa32_mve, s) ||
210
+ * guest BIOS binaries.)
129
+ !mve_check_qreg_bank(s, a->qd) ||
211
+ */
130
+ !fn) {
212
+ vmc->no_ns_el2_virt_timer_irq = true;
131
+ return false;
213
}
132
+ }
214
DEFINE_VIRT_MACHINE(8, 2)
133
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
215
134
+ return true;
135
+ }
136
+
137
+ imm = asimd_imm_const(a->imm, a->cmode, a->op);
138
+
139
+ qd = mve_qreg_ptr(a->qd);
140
+ fn(cpu_env, qd, tcg_constant_i64(imm));
141
+ tcg_temp_free_ptr(qd);
142
+ mve_update_eci(s);
143
+ return true;
144
+}
145
+
146
+static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
147
+{
148
+ /* Handle decode of cmode/op here between VORR/VBIC/VMOV */
149
+ MVEGenOneOpImmFn *fn;
150
+
151
+ if ((a->cmode & 1) && a->cmode < 12) {
152
+ if (a->op) {
153
+ /*
154
+ * For op=1, the immediate will be inverted by asimd_imm_const(),
155
+ * so the VBIC becomes a logical AND operation.
156
+ */
157
+ fn = gen_helper_mve_vandi;
158
+ } else {
159
+ fn = gen_helper_mve_vorri;
160
+ }
161
+ } else {
162
+ /* There is one unallocated cmode/op combination in this space */
163
+ if (a->cmode == 15 && a->op == 1) {
164
+ return false;
165
+ }
166
+ /* asimd_imm_const() sorts out VMVNI vs VMOVI for us */
167
+ fn = gen_helper_mve_vmovi;
168
+ }
169
+ return do_1imm(s, a, fn);
170
+}
171
--
216
--
172
2.20.1
217
2.34.1
173
174
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
The initial implementation of the MVE VRMLALDAVH and VRMLSLDAVH
1
It doesn't make sense to read the value of MDCR_EL2 on a non-A-profile
2
insns had some bugs:
2
CPU, and in fact if you try to do it we will assert:
3
* the 32x32 multiply of elements was being done as 32x32->32,
4
not 32x32->64
5
* we were incorrectly maintaining the accumulator in its full
6
72-bit form across all 4 beats of the insn; in the pseudocode
7
it is squashed back into the 64 bits of the RdaHi:RdaLo
8
registers after each beat
9
3
10
In particular, fixing the second of these allows us to recast
4
#6 0x00007ffff4b95e96 in __GI___assert_fail
11
the implementation to avoid 128-bit arithmetic entirely.
5
(assertion=0x5555565a8c70 "!arm_feature(env, ARM_FEATURE_M)", file=0x5555565a6e5c "../../target/arm/helper.c", line=12600, function=0x5555565a9560 <__PRETTY_FUNCTION__.0> "arm_security_space_below_el3") at ./assert/assert.c:101
6
#7 0x0000555555ebf412 in arm_security_space_below_el3 (env=0x555557bc8190) at ../../target/arm/helper.c:12600
7
#8 0x0000555555ea6f89 in arm_is_el2_enabled (env=0x555557bc8190) at ../../target/arm/cpu.h:2595
8
#9 0x0000555555ea942f in arm_mdcr_el2_eff (env=0x555557bc8190) at ../../target/arm/internals.h:1512
12
9
13
Since the element size here is always 4, we can also drop the
10
We might call pmu_counter_enabled() on an M-profile CPU (for example
14
parameterization of ESIZE to make the code a little more readable.
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.
15
13
16
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
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
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210628135835.6690-3-peter.maydell@linaro.org
25
Message-id: 20240208153346.970021-1-peter.maydell@linaro.org
20
---
26
---
21
target/arm/mve_helper.c | 38 +++++++++++++++++++++-----------------
27
target/arm/helper.c | 12 ++++++++++--
22
1 file changed, 21 insertions(+), 17 deletions(-)
28
1 file changed, 10 insertions(+), 2 deletions(-)
23
29
24
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/mve_helper.c
32
--- a/target/arm/helper.c
27
+++ b/target/arm/mve_helper.c
33
+++ b/target/arm/helper.c
28
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
29
*/
35
bool enabled, prohibited = false, filtered;
30
36
bool secure = arm_is_secure(env);
31
#include "qemu/osdep.h"
37
int el = arm_current_el(env);
32
-#include "qemu/int128.h"
38
- uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
33
#include "cpu.h"
39
- uint8_t hpmn = mdcr_el2 & MDCR_HPMN;
34
#include "internals.h"
40
+ uint64_t mdcr_el2;
35
#include "vec_internal.h"
41
+ uint8_t hpmn;
36
@@ -XXX,XX +XXX,XX @@ DO_LDAV(vmlsldavsw, 4, int32_t, false, +=, -=)
42
37
DO_LDAV(vmlsldavxsw, 4, int32_t, true, +=, -=)
43
+ /*
38
44
+ * We might be called for M-profile cores where MDCR_EL2 doesn't
39
/*
45
+ * exist and arm_mdcr_el2_eff() will assert, so this early-exit check
40
- * Rounding multiply add long dual accumulate high: we must keep
46
+ * must be before we read that value.
41
- * a 72-bit internal accumulator value and return the top 64 bits.
47
+ */
42
+ * Rounding multiply add long dual accumulate high. In the pseudocode
48
if (!arm_feature(env, ARM_FEATURE_PMU)) {
43
+ * this is implemented with a 72-bit internal accumulator value of which
49
return false;
44
+ * the top 64 bits are returned. We optimize this to avoid having to
45
+ * use 128-bit arithmetic -- we can do this because the 74-bit accumulator
46
+ * is squashed back into 64-bits after each beat.
47
*/
48
-#define DO_LDAVH(OP, ESIZE, TYPE, XCHG, EVENACC, ODDACC, TO128) \
49
+#define DO_LDAVH(OP, TYPE, LTYPE, XCHG, SUB) \
50
uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vn, \
51
void *vm, uint64_t a) \
52
{ \
53
uint16_t mask = mve_element_mask(env); \
54
unsigned e; \
55
TYPE *n = vn, *m = vm; \
56
- Int128 acc = int128_lshift(TO128(a), 8); \
57
- for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
58
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
59
if (mask & 1) { \
60
+ LTYPE mul; \
61
if (e & 1) { \
62
- acc = ODDACC(acc, TO128(n[H##ESIZE(e - 1 * XCHG)] * \
63
- m[H##ESIZE(e)])); \
64
+ mul = (LTYPE)n[H4(e - 1 * XCHG)] * m[H4(e)]; \
65
+ if (SUB) { \
66
+ mul = -mul; \
67
+ } \
68
} else { \
69
- acc = EVENACC(acc, TO128(n[H##ESIZE(e + 1 * XCHG)] * \
70
- m[H##ESIZE(e)])); \
71
+ mul = (LTYPE)n[H4(e + 1 * XCHG)] * m[H4(e)]; \
72
} \
73
- acc = int128_add(acc, int128_make64(1 << 7)); \
74
+ mul = (mul >> 8) + ((mul >> 7) & 1); \
75
+ a += mul; \
76
} \
77
} \
78
mve_advance_vpt(env); \
79
- return int128_getlo(int128_rshift(acc, 8)); \
80
+ return a; \
81
}
50
}
82
51
83
-DO_LDAVH(vrmlaldavhsw, 4, int32_t, false, int128_add, int128_add, int128_makes64)
52
+ mdcr_el2 = arm_mdcr_el2_eff(env);
84
-DO_LDAVH(vrmlaldavhxsw, 4, int32_t, true, int128_add, int128_add, int128_makes64)
53
+ hpmn = mdcr_el2 & MDCR_HPMN;
85
+DO_LDAVH(vrmlaldavhsw, int32_t, int64_t, false, false)
54
+
86
+DO_LDAVH(vrmlaldavhxsw, int32_t, int64_t, true, false)
55
if (!arm_feature(env, ARM_FEATURE_EL2) ||
87
56
(counter < hpmn || counter == 31)) {
88
-DO_LDAVH(vrmlaldavhuw, 4, uint32_t, false, int128_add, int128_add, int128_make64)
57
e = env->cp15.c9_pmcr & PMCRE;
89
+DO_LDAVH(vrmlaldavhuw, uint32_t, uint64_t, false, false)
90
91
-DO_LDAVH(vrmlsldavhsw, 4, int32_t, false, int128_add, int128_sub, int128_makes64)
92
-DO_LDAVH(vrmlsldavhxsw, 4, int32_t, true, int128_add, int128_sub, int128_makes64)
93
+DO_LDAVH(vrmlsldavhsw, int32_t, int64_t, false, true)
94
+DO_LDAVH(vrmlsldavhxsw, int32_t, int64_t, true, true)
95
96
/* Vector add across vector */
97
#define DO_VADDV(OP, ESIZE, TYPE) \
98
--
58
--
99
2.20.1
59
2.34.1
100
60
101
61
diff view generated by jsdifflib
New patch
1
From: Nabih Estefan <nabihestefan@google.com>
1
2
3
Fix the nocm_gmac-test.c file to run on a nuvoton 7xx machine instead
4
of 8xx. Also fix comments referencing this and values expecting 8xx.
5
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
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
[PMM: commit message tweaks]
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
tests/qtest/npcm_gmac-test.c | 84 +-----------------------------------
15
tests/qtest/meson.build | 3 +-
16
2 files changed, 4 insertions(+), 83 deletions(-)
17
18
diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/tests/qtest/npcm_gmac-test.c
21
+++ b/tests/qtest/npcm_gmac-test.c
22
@@ -XXX,XX +XXX,XX @@ typedef struct TestData {
23
const GMACModule *module;
24
} TestData;
25
26
-/* Values extracted from hw/arm/npcm8xx.c */
27
+/* Values extracted from hw/arm/npcm7xx.c */
28
static const GMACModule gmac_module_list[] = {
29
{
30
.irq = 14,
31
@@ -XXX,XX +XXX,XX @@ static const GMACModule gmac_module_list[] = {
32
.irq = 15,
33
.base_addr = 0xf0804000
34
},
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);
48
}
49
50
-static uint16_t pcs_read(QTestState *qts, const GMACModule *mod,
51
- NPCMRegister regno)
52
-{
53
- uint32_t write_value = (regno & 0x3ffe00) >> 9;
54
- qtest_writel(qts, PCS_BASE_ADDRESS + NPCM_PCS_IND_AC_BA, write_value);
55
- uint32_t read_offset = regno & 0x1ff;
56
- return qtest_readl(qts, PCS_BASE_ADDRESS + read_offset);
57
-}
58
-
59
/* Check that GMAC registers are reset to default value */
60
static void test_init(gconstpointer test_data)
61
{
62
const TestData *td = test_data;
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
146
index XXXXXXX..XXXXXXX 100644
147
--- a/tests/qtest/meson.build
148
+++ b/tests/qtest/meson.build
149
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
150
'npcm7xx_sdhci-test',
151
'npcm7xx_smbus-test',
152
'npcm7xx_timer-test',
153
- 'npcm7xx_watchdog_timer-test'] + \
154
+ 'npcm7xx_watchdog_timer-test',
155
+ 'npcm_gmac-test'] + \
156
(slirp.found() ? ['npcm7xx_emc-test'] : [])
157
qtests_aspeed = \
158
['aspeed_hace-test',
159
--
160
2.34.1
diff view generated by jsdifflib
New patch
1
From: Luc Michel <luc.michel@amd.com>
1
2
3
An access fault is raised when the Access Flag is not set in the
4
looked-up PTE and the AFFD field is not set in the corresponding context
5
descriptor. This was already implemented for stage 2. Implement it for
6
stage 1 as well.
7
8
Signed-off-by: Luc Michel <luc.michel@amd.com>
9
Reviewed-by: Mostafa Saleh <smostafa@google.com>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Tested-by: Mostafa Saleh <smostafa@google.com>
12
Message-id: 20240213082211.3330400-1-luc.michel@amd.com
13
[PMM: tweaked comment text]
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
hw/arm/smmuv3-internal.h | 1 +
17
include/hw/arm/smmu-common.h | 1 +
18
hw/arm/smmu-common.c | 11 +++++++++++
19
hw/arm/smmuv3.c | 1 +
20
4 files changed, 14 insertions(+)
21
22
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/arm/smmuv3-internal.h
25
+++ b/hw/arm/smmuv3-internal.h
26
@@ -XXX,XX +XXX,XX @@ static inline int pa_range(STE *ste)
27
#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
28
#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
29
#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
30
+#define CD_AFFD(x) extract32((x)->word[1], 3 , 1)
31
#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
32
#define CD_HD(x) extract32((x)->word[1], 10 , 1)
33
#define CD_HA(x) extract32((x)->word[1], 11 , 1)
34
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/arm/smmu-common.h
37
+++ b/include/hw/arm/smmu-common.h
38
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
39
bool disabled; /* smmu is disabled */
40
bool bypassed; /* translation is bypassed */
41
bool aborted; /* translation is aborted */
42
+ bool affd; /* AF fault disable */
43
uint32_t iotlb_hits; /* counts IOTLB hits */
44
uint32_t iotlb_misses; /* counts IOTLB misses*/
45
/* Used by stage-1 only. */
46
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/smmu-common.c
49
+++ b/hw/arm/smmu-common.c
50
@@ -XXX,XX +XXX,XX @@ static int smmu_ptw_64_s1(SMMUTransCfg *cfg,
51
pte_addr, pte, iova, gpa,
52
block_size >> 20);
53
}
54
+
55
+ /*
56
+ * QEMU does not currently implement HTTU, so if AFFD and PTE.AF
57
+ * are 0 we take an Access flag fault. (5.4. Context Descriptor)
58
+ * An Access flag fault takes priority over a Permission fault.
59
+ */
60
+ if (!PTE_AF(pte) && !cfg->affd) {
61
+ info->type = SMMU_PTW_ERR_ACCESS;
62
+ goto error;
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
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/arm/smmuv3.c
71
+++ b/hw/arm/smmuv3.c
72
@@ -XXX,XX +XXX,XX @@ static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
73
cfg->oas = MIN(oas2bits(SMMU_IDR5_OAS), cfg->oas);
74
cfg->tbi = CD_TBI(cd);
75
cfg->asid = CD_ASID(cd);
76
+ cfg->affd = CD_AFFD(cd);
77
78
trace_smmuv3_decode_cd(cfg->oas);
79
80
--
81
2.34.1
diff view generated by jsdifflib
1
From: Maxim Uvarov <maxim.uvarov@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
qemu has 2 type of functions: shutdown and reboot. Shutdown
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
function has to be used for machine shutdown. Otherwise we cause
5
a reset with a bogus "cause" value, when we intended a shutdown.
6
7
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20210625111842.3790-3-maxim.uvarov@linaro.org
5
Message-id: 20240213155214.13619-2-philmd@linaro.org
10
[PMM: tweaked commit message]
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
7
---
13
hw/gpio/gpio_pwr.c | 2 +-
8
hw/arm/stellaris.c | 6 ++++--
14
1 file changed, 1 insertion(+), 1 deletion(-)
9
1 file changed, 4 insertions(+), 2 deletions(-)
15
10
16
diff --git a/hw/gpio/gpio_pwr.c b/hw/gpio/gpio_pwr.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/hw/gpio/gpio_pwr.c
13
--- a/hw/arm/stellaris.c
19
+++ b/hw/gpio/gpio_pwr.c
14
+++ b/hw/arm/stellaris.c
20
@@ -XXX,XX +XXX,XX @@ static void gpio_pwr_reset(void *opaque, int n, int level)
15
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_trigger(void *opaque, int irq, int level)
21
static void gpio_pwr_shutdown(void *opaque, int n, int level)
22
{
23
if (level) {
24
- qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
25
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
26
}
16
}
27
}
17
}
28
18
19
-static void stellaris_adc_reset(StellarisADCState *s)
20
+static void stellaris_adc_reset_hold(Object *obj)
21
{
22
+ StellarisADCState *s = STELLARIS_ADC(obj);
23
int n;
24
25
for (n = 0; n < 4; n++) {
26
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_init(Object *obj)
27
memory_region_init_io(&s->iomem, obj, &stellaris_adc_ops, s,
28
"adc", 0x1000);
29
sysbus_init_mmio(sbd, &s->iomem);
30
- stellaris_adc_reset(s);
31
qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
32
}
33
34
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stellaris_i2c_info = {
35
static void stellaris_adc_class_init(ObjectClass *klass, void *data)
36
{
37
DeviceClass *dc = DEVICE_CLASS(klass);
38
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
39
40
+ rc->phases.hold = stellaris_adc_reset_hold;
41
dc->vmsd = &vmstate_stellaris_adc;
42
}
43
29
--
44
--
30
2.20.1
45
2.34.1
31
46
32
47
diff view generated by jsdifflib
1
Implement the MVE VHLL (vector shift left long) insn. This has two
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
encodings: the T1 encoding is the usual shift-by-immediate format,
3
and the T2 encoding is a special case where the shift count is always
4
equal to the element size.
5
2
3
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Message-id: 20240213155214.13619-3-philmd@linaro.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-10-peter.maydell@linaro.org
9
---
8
---
10
target/arm/helper-mve.h | 9 +++++++
9
hw/arm/stellaris.c | 26 ++++++++++++++++++++++----
11
target/arm/mve.decode | 53 +++++++++++++++++++++++++++++++++++---
10
1 file changed, 22 insertions(+), 4 deletions(-)
12
target/arm/mve_helper.c | 32 +++++++++++++++++++++++
13
target/arm/translate-mve.c | 15 +++++++++++
14
4 files changed, 105 insertions(+), 4 deletions(-)
15
11
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
12
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-mve.h
14
--- a/hw/arm/stellaris.c
19
+++ b/target/arm/helper-mve.h
15
+++ b/hw/arm/stellaris.c
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
16
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_instance_init(Object *obj)
21
DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
17
s->sysclk = qdev_init_clock_out(DEVICE(s), "SYSCLK");
22
DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
18
}
23
DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
19
20
-/* I2C controller. */
21
+/*
22
+ * I2C controller.
23
+ * ??? For now we only implement the master interface.
24
+ */
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);
24
+
36
+
25
+DEF_HELPER_FLAGS_4(mve_vshllbsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
26
+DEF_HELPER_FLAGS_4(mve_vshllbsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
38
i2c_end_transfer(s->bus);
27
+DEF_HELPER_FLAGS_4(mve_vshllbub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vshllbuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
36
+++ b/target/arm/mve.decode
37
@@ -XXX,XX +XXX,XX @@
38
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
39
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
40
41
+@2_shll_b .... .... ... 01 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
42
+@2_shll_h .... .... ... 1 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
43
+# VSHLL encoding T2 where shift == esize
44
+@2_shll_esize_b .... .... .... 00 .. .... .... .... .... &2shift \
45
+ qd=%qd qm=%qm size=0 shift=8
46
+@2_shll_esize_h .... .... .... 01 .. .... .... .... .... &2shift \
47
+ qd=%qd qm=%qm size=1 shift=16
48
+
49
# Right shifts are encoded as N - shift, where N is the element size in bits.
50
%rshift_i5 16:5 !function=rsub_32
51
%rshift_i4 16:4 !function=rsub_16
52
@@ -XXX,XX +XXX,XX @@ VADD 1110 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
53
VSUB 1111 1111 0 . .. ... 0 ... 0 1000 . 1 . 0 ... 0 @2op
54
VMUL 1110 1111 0 . .. ... 0 ... 0 1001 . 1 . 1 ... 0 @2op
55
56
-VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
57
-VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
58
+# The VSHLL T2 encoding is not a @2op pattern, but is here because it
59
+# overlaps what would be size=0b11 VMULH/VRMULH
60
+{
61
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
62
+ VSHLL_BS 111 0 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
63
64
-VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
65
-VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
66
+ VMULH_S 111 0 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
67
+}
39
+}
68
+
40
+
41
+static void stellaris_i2c_reset_hold(Object *obj)
69
+{
42
+{
70
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_b
43
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
71
+ VSHLL_BU 111 1 1110 0 . 11 .. 01 ... 0 1110 0 0 . 0 ... 1 @2_shll_esize_h
44
72
+
45
s->msa = 0;
73
+ VMULH_U 111 1 1110 0 . .. ...1 ... 0 1110 . 0 . 0 ... 1 @2op
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;
74
+}
51
+}
75
+
52
+
53
+static void stellaris_i2c_reset_exit(Object *obj)
76
+{
54
+{
77
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
55
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
78
+ VSHLL_TS 111 0 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
79
+
56
+
80
+ VRMULH_S 111 0 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
57
stellaris_i2c_update(s);
81
+}
58
}
82
+
59
83
+{
60
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_init(Object *obj)
84
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_b
61
memory_region_init_io(&s->iomem, obj, &stellaris_i2c_ops, s,
85
+ VSHLL_TU 111 1 1110 0 . 11 .. 01 ... 1 1110 0 0 . 0 ... 1 @2_shll_esize_h
62
"i2c", 0x1000);
86
+
63
sysbus_init_mmio(sbd, &s->iomem);
87
+ VRMULH_U 111 1 1110 0 . .. ...1 ... 1 1110 . 0 . 0 ... 1 @2op
64
- /* ??? For now we only implement the master interface. */
88
+}
65
- stellaris_i2c_reset(s);
89
66
}
90
VMAX_S 111 0 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
67
91
VMAX_U 111 1 1111 0 . .. ... 0 ... 0 0110 . 1 . 0 ... 0 @2op
68
/* Analogue to Digital Converter. This is only partially implemented,
92
@@ -XXX,XX +XXX,XX @@ VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
69
@@ -XXX,XX +XXX,XX @@ type_init(stellaris_machine_init)
93
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
70
static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
94
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
71
{
95
VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
72
DeviceClass *dc = DEVICE_CLASS(klass);
96
+
73
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
97
+# VSHLL T1 encoding; the T2 VSHLL encoding is elsewhere in this file
74
98
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
75
+ rc->phases.enter = stellaris_i2c_reset_enter;
99
+VSHLL_BS 111 0 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
76
+ rc->phases.hold = stellaris_i2c_reset_hold;
100
+
77
+ rc->phases.exit = stellaris_i2c_reset_exit;
101
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_b
78
dc->vmsd = &vmstate_stellaris_i2c;
102
+VSHLL_BU 111 1 1110 1 . 1 .. ... ... 0 1111 0 1 . 0 ... 0 @2_shll_h
79
}
103
+
80
104
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
105
+VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
106
+
107
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
108
+VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
109
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/mve_helper.c
112
+++ b/target/arm/mve_helper.c
113
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
114
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
115
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
116
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
117
+
118
+/*
119
+ * Long shifts taking half-sized inputs from top or bottom of the input
120
+ * vector and producing a double-width result. ESIZE, TYPE are for
121
+ * the input, and LESIZE, LTYPE for the output.
122
+ * Unlike the normal shift helpers, we do not handle negative shift counts,
123
+ * because the long shift is strictly left-only.
124
+ */
125
+#define DO_VSHLL(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE) \
126
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
127
+ void *vm, uint32_t shift) \
128
+ { \
129
+ LTYPE *d = vd; \
130
+ TYPE *m = vm; \
131
+ uint16_t mask = mve_element_mask(env); \
132
+ unsigned le; \
133
+ assert(shift <= 16); \
134
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
135
+ LTYPE r = (LTYPE)m[H##ESIZE(le * 2 + TOP)] << shift; \
136
+ mergemask(&d[H##LESIZE(le)], r, mask); \
137
+ } \
138
+ mve_advance_vpt(env); \
139
+ }
140
+
141
+#define DO_VSHLL_ALL(OP, TOP) \
142
+ DO_VSHLL(OP##sb, TOP, 1, int8_t, 2, int16_t) \
143
+ DO_VSHLL(OP##ub, TOP, 1, uint8_t, 2, uint16_t) \
144
+ DO_VSHLL(OP##sh, TOP, 2, int16_t, 4, int32_t) \
145
+ DO_VSHLL(OP##uh, TOP, 2, uint16_t, 4, uint32_t) \
146
+
147
+DO_VSHLL_ALL(vshllb, false)
148
+DO_VSHLL_ALL(vshllt, true)
149
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/translate-mve.c
152
+++ b/target/arm/translate-mve.c
153
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_S, vshli_s, true)
154
DO_2SHIFT(VSHRI_U, vshli_u, true)
155
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
157
+
158
+#define DO_VSHLL(INSN, FN) \
159
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
160
+ { \
161
+ static MVEGenTwoOpShiftFn * const fns[] = { \
162
+ gen_helper_mve_##FN##b, \
163
+ gen_helper_mve_##FN##h, \
164
+ }; \
165
+ return do_2shift(s, a, fns[a->size], false); \
166
+ }
167
+
168
+DO_VSHLL(VSHLL_BS, vshllbs)
169
+DO_VSHLL(VSHLL_BU, vshllbu)
170
+DO_VSHLL(VSHLL_TS, vshllts)
171
+DO_VSHLL(VSHLL_TU, vshlltu)
172
--
81
--
173
2.20.1
82
2.34.1
174
83
175
84
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Add a test booting and quickly shutdown a raspi2 machine,
3
QDev objects created with qdev_new() need to manually add
4
to test the power management model:
4
their parent relationship with object_property_add_child().
5
5
6
(1/1) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_raspi2_initrd:
6
This commit plug the devices which aren't part of the SoC;
7
console: [ 0.000000] Booting Linux on physical CPU 0xf00
7
they will be plugged into a SoC container in the next one.
8
console: [ 0.000000] Linux version 4.14.98-v7+ (dom@dom-XPS-13-9370) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1200 SMP Tue Feb 12 20:27:48 GMT 2019
9
console: [ 0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d
10
console: [ 0.000000] CPU: div instructions available: patching division code
11
console: [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
12
console: [ 0.000000] OF: fdt: Machine model: Raspberry Pi 2 Model B
13
...
14
console: Boot successful.
15
console: cat /proc/cpuinfo
16
console: / # cat /proc/cpuinfo
17
...
18
console: processor : 3
19
console: model name : ARMv7 Processor rev 5 (v7l)
20
console: BogoMIPS : 125.00
21
console: Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
22
console: CPU implementer : 0x41
23
console: CPU architecture: 7
24
console: CPU variant : 0x0
25
console: CPU part : 0xc07
26
console: CPU revision : 5
27
console: Hardware : BCM2835
28
console: Revision : 0000
29
console: Serial : 0000000000000000
30
console: cat /proc/iomem
31
console: / # cat /proc/iomem
32
console: 00000000-3bffffff : System RAM
33
console: 00008000-00afffff : Kernel code
34
console: 00c00000-00d468ef : Kernel data
35
console: 3f006000-3f006fff : dwc_otg
36
console: 3f007000-3f007eff : /soc/dma@7e007000
37
console: 3f00b880-3f00b8bf : /soc/mailbox@7e00b880
38
console: 3f100000-3f100027 : /soc/watchdog@7e100000
39
console: 3f101000-3f102fff : /soc/cprman@7e101000
40
console: 3f200000-3f2000b3 : /soc/gpio@7e200000
41
PASS (24.59 s)
42
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
43
JOB TIME : 25.02 s
44
8
45
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
46
Reviewed-by: Wainer dos Santos Moschetta <wainersm@redhat.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
47
Message-id: 20210531113837.1689775-1-f4bug@amsat.org
11
Message-id: 20240213155214.13619-4-philmd@linaro.org
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
49
---
13
---
50
tests/acceptance/boot_linux_console.py | 43 ++++++++++++++++++++++++++
14
hw/arm/stellaris.c | 4 ++++
51
1 file changed, 43 insertions(+)
15
1 file changed, 4 insertions(+)
52
16
53
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
17
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
54
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
55
--- a/tests/acceptance/boot_linux_console.py
19
--- a/hw/arm/stellaris.c
56
+++ b/tests/acceptance/boot_linux_console.py
20
+++ b/hw/arm/stellaris.c
57
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
58
from avocado import skip
22
&error_fatal);
59
from avocado import skipUnless
23
60
from avocado_qemu import Test
24
ssddev = qdev_new("ssd0323");
61
+from avocado_qemu import exec_command
25
+ object_property_add_child(OBJECT(ms), "oled", OBJECT(ssddev));
62
from avocado_qemu import exec_command_and_wait_for_pattern
26
qdev_prop_set_uint8(ssddev, "cs", 1);
63
from avocado_qemu import interrupt_interactive_console_until_pattern
27
qdev_realize_and_unref(ssddev, bus, &error_fatal);
64
from avocado_qemu import wait_for_console_pattern
28
65
@@ -XXX,XX +XXX,XX @@ def test_arm_raspi2_uart0(self):
29
gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
66
"""
30
+ object_property_add_child(OBJECT(ms), "splitter",
67
self.do_test_arm_raspi2(0)
31
+ OBJECT(gpio_d_splitter));
68
32
qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
69
+ def test_arm_raspi2_initrd(self):
33
qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
70
+ """
34
qdev_connect_gpio_out(
71
+ :avocado: tags=arch:arm
35
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
72
+ :avocado: tags=machine:raspi2
36
DeviceState *gpad;
73
+ """
37
74
+ deb_url = ('http://archive.raspberrypi.org/debian/'
38
gpad = qdev_new(TYPE_STELLARIS_GAMEPAD);
75
+ 'pool/main/r/raspberrypi-firmware/'
39
+ object_property_add_child(OBJECT(ms), "gamepad", OBJECT(gpad));
76
+ 'raspberrypi-kernel_1.20190215-1_armhf.deb')
40
for (i = 0; i < ARRAY_SIZE(gpad_keycode); i++) {
77
+ deb_hash = 'cd284220b32128c5084037553db3c482426f3972'
41
qlist_append_int(gpad_keycode_list, gpad_keycode[i]);
78
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
42
}
79
+ kernel_path = self.extract_from_deb(deb_path, '/boot/kernel7.img')
80
+ dtb_path = self.extract_from_deb(deb_path, '/boot/bcm2709-rpi-2-b.dtb')
81
+
82
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
83
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
84
+ 'arm/rootfs-armv7a.cpio.gz')
85
+ initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c'
86
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
87
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
88
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
89
+
90
+ self.vm.set_console()
91
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
92
+ 'earlycon=pl011,0x3f201000 console=ttyAMA0 '
93
+ 'panic=-1 noreboot ' +
94
+ 'dwc_otg.fiq_fsm_enable=0')
95
+ self.vm.add_args('-kernel', kernel_path,
96
+ '-dtb', dtb_path,
97
+ '-initrd', initrd_path,
98
+ '-append', kernel_command_line,
99
+ '-no-reboot')
100
+ self.vm.launch()
101
+ self.wait_for_console_pattern('Boot successful.')
102
+
103
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
104
+ 'BCM2835')
105
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
106
+ '/soc/cprman@7e101000')
107
+ exec_command(self, 'halt')
108
+ # Wait for VM to shut down gracefully
109
+ self.vm.wait()
110
+
111
def test_arm_exynos4210_initrd(self):
112
"""
113
:avocado: tags=arch:arm
114
--
43
--
115
2.20.1
44
2.34.1
116
45
117
46
diff view generated by jsdifflib
1
From: Patrick Venture <venture@google.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Add line item reference to quanta-gbs-bmc machine.
3
QDev objects created with qdev_new() need to manually add
4
their parent relationship with object_property_add_child().
4
5
5
Signed-off-by: Patrick Venture <venture@google.com>
6
Since we don't model the SoC, just use a QOM container.
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
7
Message-id: 20210615192848.1065297-3-venture@google.com
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
[PMM: fixed underline Sphinx warning]
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
docs/system/arm/nuvoton.rst | 5 +++--
13
hw/arm/stellaris.c | 11 ++++++++++-
12
1 file changed, 3 insertions(+), 2 deletions(-)
14
1 file changed, 10 insertions(+), 1 deletion(-)
13
15
14
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
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/docs/system/arm/nuvoton.rst
18
--- a/hw/arm/stellaris.c
17
+++ b/docs/system/arm/nuvoton.rst
19
+++ b/hw/arm/stellaris.c
18
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
19
-Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
21
* 400fe000 system control
20
-=====================================================
22
*/
21
+Nuvoton iBMC boards (``*-bmc``, ``npcm750-evb``, ``quanta-gsj``)
23
22
+================================================================
24
+ Object *soc_container;
23
25
DeviceState *gpio_dev[7], *nvic;
24
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
26
qemu_irq gpio_in[7][8];
25
designed to be used as Baseboard Management Controllers (BMCs) in various
27
qemu_irq gpio_out[7][8];
26
@@ -XXX,XX +XXX,XX @@ segment. The following machines are based on this chip :
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
27
The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
29
flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
28
Hyperscale applications. The following machines are based on this chip :
30
sram_size = ((board->dc0 >> 18) + 1) * 1024;
29
31
30
+- ``quanta-gbs-bmc`` Quanta GBS server BMC
32
+ soc_container = object_new("container");
31
- ``quanta-gsj`` Quanta GSJ server BMC
33
+ object_property_add_child(OBJECT(ms), "soc", soc_container);
32
34
+
33
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
35
/* Flash programming is done via the SCU, so pretend it is ROM. */
36
memory_region_init_rom(flash, NULL, "stellaris.flash", flash_size,
37
&error_fatal);
38
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
39
* need its sysclk output.
40
*/
41
ssys_dev = qdev_new(TYPE_STELLARIS_SYS);
42
+ object_property_add_child(soc_container, "sys", OBJECT(ssys_dev));
43
44
/*
45
* Most devices come preprogrammed with a MAC address in the user data.
46
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
47
sysbus_realize_and_unref(SYS_BUS_DEVICE(ssys_dev), &error_fatal);
48
49
nvic = qdev_new(TYPE_ARMV7M);
50
+ object_property_add_child(soc_container, "v7m", OBJECT(nvic));
51
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
52
qdev_prop_set_uint8(nvic, "num-prio-bits", NUM_PRIO_BITS);
53
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
54
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
55
56
dev = qdev_new(TYPE_STELLARIS_GPTM);
57
sbd = SYS_BUS_DEVICE(dev);
58
+ object_property_add_child(soc_container, "gptm[*]", OBJECT(dev));
59
qdev_connect_clock_in(dev, "clk",
60
qdev_get_clock_out(ssys_dev, "SYSCLK"));
61
sysbus_realize_and_unref(sbd, &error_fatal);
62
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
63
64
if (board->dc1 & (1 << 3)) { /* watchdog present */
65
dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
66
-
67
+ object_property_add_child(soc_container, "wdg", OBJECT(dev));
68
qdev_connect_clock_in(dev, "WDOGCLK",
69
qdev_get_clock_out(ssys_dev, "SYSCLK"));
70
71
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
72
SysBusDevice *sbd;
73
74
dev = qdev_new("pl011_luminary");
75
+ object_property_add_child(soc_container, "uart[*]", OBJECT(dev));
76
sbd = SYS_BUS_DEVICE(dev);
77
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
78
sysbus_realize_and_unref(sbd, &error_fatal);
79
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
80
DeviceState *enet;
81
82
enet = qdev_new("stellaris_enet");
83
+ object_property_add_child(soc_container, "enet", OBJECT(enet));
84
if (nd) {
85
qdev_set_nic_properties(enet, nd);
86
} else {
34
--
87
--
35
2.20.1
88
2.34.1
36
89
37
90
diff view generated by jsdifflib
1
Implement the MVE VADDLV insn; this is similar to VADDV, except
1
We support two different encodings for the AArch32 IMPDEF
2
that it accumulates 32-bit elements into a 64-bit accumulator
2
CBAR register -- older cores like the Cortex A9, A7, A15
3
stored in a pair of general-purpose registers.
3
have this at 4, c15, c0, 0; newer cores like the
4
Cortex A35, A53, A57 and A72 have it at 1 c15 c0 0.
5
6
When we implemented this we picked which encoding to
7
use based on whether the CPU set ARM_FEATURE_AARCH64.
8
However this isn't right for three cases:
9
* the qemu-system-arm 'max' CPU, which is supposed to be
10
a variant on a Cortex-A57; it ought to use the same
11
encoding the A57 does and which the AArch64 'max'
12
exposes to AArch32 guest code
13
* the Cortex-R52, which is AArch32-only but has the CBAR
14
at the newer encoding (and where we incorrectly are
15
not yet setting ARM_FEATURE_CBAR_RO anyway)
16
* any possible future support for other v8 AArch32
17
only CPUs, or for supporting "boot the CPU into
18
AArch32 mode" on our existing cores like the A57 etc
19
20
Make the decision of the encoding be based on whether
21
the CPU implements the ARM_FEATURE_V8 flag instead.
22
23
This changes the behaviour only for the qemu-system-arm
24
'-cpu max'. We don't expect anybody to be relying on the
25
old behaviour because:
26
* it's not what the real hardware Cortex-A57 does
27
(and that's what our ID register claims we are)
28
* we don't implement the memory-mapped GICv3 support
29
which is the only thing that exists at the peripheral
30
base address pointed to by the register
4
31
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-15-peter.maydell@linaro.org
34
Message-id: 20240206132931.38376-2-peter.maydell@linaro.org
8
---
35
---
9
target/arm/helper-mve.h | 3 ++
36
target/arm/helper.c | 2 +-
10
target/arm/mve.decode | 6 +++-
37
1 file changed, 1 insertion(+), 1 deletion(-)
11
target/arm/mve_helper.c | 19 ++++++++++++
12
target/arm/translate-mve.c | 63 ++++++++++++++++++++++++++++++++++++++
13
4 files changed, 90 insertions(+), 1 deletion(-)
14
38
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-mve.h
41
--- a/target/arm/helper.c
18
+++ b/target/arm/helper-mve.h
42
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuh, TCG_CALL_NO_WG, i32, env, ptr, i32)
43
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
20
DEF_HELPER_FLAGS_3(mve_vaddvsw, TCG_CALL_NO_WG, i32, env, ptr, i32)
44
* AArch64 cores we might need to add a specific feature flag
21
DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
45
* to indicate cores with "flavour 2" CBAR.
22
46
*/
23
+DEF_HELPER_FLAGS_3(mve_vaddlv_s, TCG_CALL_NO_WG, i64, env, ptr, i64)
47
- if (arm_feature(env, ARM_FEATURE_AARCH64)) {
24
+DEF_HELPER_FLAGS_3(mve_vaddlv_u, TCG_CALL_NO_WG, i64, env, ptr, i64)
48
+ if (arm_feature(env, ARM_FEATURE_V8)) {
25
+
49
/* 32 bit view is [31:18] 0...0 [43:32]. */
26
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
50
uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18)
27
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
51
| extract64(cpu->reset_cbar, 32, 12);
28
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
29
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/mve.decode
32
+++ b/target/arm/mve.decode
33
@@ -XXX,XX +XXX,XX @@ VQDMULH_scalar 1110 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
34
VQRDMULH_scalar 1111 1110 0 . .. ... 1 ... 0 1110 . 110 .... @2scalar
35
36
# Vector add across vector
37
-VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
38
+{
39
+ VADDV 111 u:1 1110 1111 size:2 01 ... 0 1111 0 0 a:1 0 qm:3 0 rda=%rdalo
40
+ VADDLV 111 u:1 1110 1 ... 1001 ... 0 1111 00 a:1 0 qm:3 0 \
41
+ rdahi=%rdahi rdalo=%rdalo
42
+}
43
44
# Predicate operations
45
%mask_22_13 22:1 13:3
46
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/mve_helper.c
49
+++ b/target/arm/mve_helper.c
50
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvub, 1, uint8_t)
51
DO_VADDV(vaddvuh, 2, uint16_t)
52
DO_VADDV(vaddvuw, 4, uint32_t)
53
54
+#define DO_VADDLV(OP, TYPE, LTYPE) \
55
+ uint64_t HELPER(glue(mve_, OP))(CPUARMState *env, void *vm, \
56
+ uint64_t ra) \
57
+ { \
58
+ uint16_t mask = mve_element_mask(env); \
59
+ unsigned e; \
60
+ TYPE *m = vm; \
61
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) { \
62
+ if (mask & 1) { \
63
+ ra += (LTYPE)m[H4(e)]; \
64
+ } \
65
+ } \
66
+ mve_advance_vpt(env); \
67
+ return ra; \
68
+ } \
69
+
70
+DO_VADDLV(vaddlv_s, int32_t, int64_t)
71
+DO_VADDLV(vaddlv_u, uint32_t, uint64_t)
72
+
73
/* Shifts by immediate */
74
#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
75
void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
76
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/translate-mve.c
79
+++ b/target/arm/translate-mve.c
80
@@ -XXX,XX +XXX,XX @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
81
return true;
82
}
83
84
+static bool trans_VADDLV(DisasContext *s, arg_VADDLV *a)
85
+{
86
+ /*
87
+ * Vector Add Long Across Vector: accumulate the 32-bit
88
+ * elements of the vector into a 64-bit result stored in
89
+ * a pair of general-purpose registers.
90
+ * No need to check Qm's bank: it is only 3 bits in decode.
91
+ */
92
+ TCGv_ptr qm;
93
+ TCGv_i64 rda;
94
+ TCGv_i32 rdalo, rdahi;
95
+
96
+ if (!dc_isar_feature(aa32_mve, s)) {
97
+ return false;
98
+ }
99
+ /*
100
+ * rdahi == 13 is UNPREDICTABLE; rdahi == 15 is a related
101
+ * encoding; rdalo always has bit 0 clear so cannot be 13 or 15.
102
+ */
103
+ if (a->rdahi == 13 || a->rdahi == 15) {
104
+ return false;
105
+ }
106
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
107
+ return true;
108
+ }
109
+
110
+ /*
111
+ * This insn is subject to beat-wise execution. Partial execution
112
+ * of an A=0 (no-accumulate) insn which does not execute the first
113
+ * beat must start with the current value of RdaHi:RdaLo, not zero.
114
+ */
115
+ if (a->a || mve_skip_first_beat(s)) {
116
+ /* Accumulate input from RdaHi:RdaLo */
117
+ rda = tcg_temp_new_i64();
118
+ rdalo = load_reg(s, a->rdalo);
119
+ rdahi = load_reg(s, a->rdahi);
120
+ tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
121
+ tcg_temp_free_i32(rdalo);
122
+ tcg_temp_free_i32(rdahi);
123
+ } else {
124
+ /* Accumulate starting at zero */
125
+ rda = tcg_const_i64(0);
126
+ }
127
+
128
+ qm = mve_qreg_ptr(a->qm);
129
+ if (a->u) {
130
+ gen_helper_mve_vaddlv_u(rda, cpu_env, qm, rda);
131
+ } else {
132
+ gen_helper_mve_vaddlv_s(rda, cpu_env, qm, rda);
133
+ }
134
+ tcg_temp_free_ptr(qm);
135
+
136
+ rdalo = tcg_temp_new_i32();
137
+ rdahi = tcg_temp_new_i32();
138
+ tcg_gen_extrl_i64_i32(rdalo, rda);
139
+ tcg_gen_extrh_i64_i32(rdahi, rda);
140
+ store_reg(s, a->rdalo, rdalo);
141
+ store_reg(s, a->rdahi, rdahi);
142
+ tcg_temp_free_i64(rda);
143
+ mve_update_eci(s);
144
+ return true;
145
+}
146
+
147
static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
148
{
149
TCGv_ptr qd;
150
--
52
--
151
2.20.1
53
2.34.1
152
153
diff view generated by jsdifflib
1
Implement the MVE VSHLC insn, which performs a shift left of the
1
The Cortex-R52 implements the Configuration Base Address Register
2
entire vector with carry in bits provided from a general purpose
2
(CBAR), as a read-only register. Add ARM_FEATURE_CBAR_RO to this CPU
3
register and carry out bits written back to that register.
3
type, so that our implementation provides the register and the
4
associated qdev property.
4
5
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-14-peter.maydell@linaro.org
8
Message-id: 20240206132931.38376-3-peter.maydell@linaro.org
8
---
9
---
9
target/arm/helper-mve.h | 2 ++
10
target/arm/tcg/cpu32.c | 1 +
10
target/arm/mve.decode | 2 ++
11
1 file changed, 1 insertion(+)
11
target/arm/mve_helper.c | 38 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate-mve.c | 30 ++++++++++++++++++++++++++++++
13
4 files changed, 72 insertions(+)
14
12
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-mve.h
15
--- a/target/arm/tcg/cpu32.c
18
+++ b/target/arm/helper-mve.h
16
+++ b/target/arm/tcg/cpu32.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
20
DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
18
set_feature(&cpu->env, ARM_FEATURE_PMSA);
21
DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
19
set_feature(&cpu->env, ARM_FEATURE_NEON);
22
DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
23
+
21
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
24
+DEF_HELPER_FLAGS_4(mve_vshlc, TCG_CALL_NO_WG, i32, env, ptr, i32, i32)
22
cpu->midr = 0x411fd133; /* r1p3 */
25
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
23
cpu->revidr = 0x00000000;
26
index XXXXXXX..XXXXXXX 100644
24
cpu->reset_fpsid = 0x41034023;
27
--- a/target/arm/mve.decode
28
+++ b/target/arm/mve.decode
29
@@ -XXX,XX +XXX,XX @@ VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
30
VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
31
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
32
VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
33
+
34
+VSHLC 111 0 1110 1 . 1 imm:5 ... 0 1111 1100 rdm:4 qd=%qd
35
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/mve_helper.c
38
+++ b/target/arm/mve_helper.c
39
@@ -XXX,XX +XXX,XX @@ DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
40
DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
41
DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
42
DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
43
+
44
+uint32_t HELPER(mve_vshlc)(CPUARMState *env, void *vd, uint32_t rdm,
45
+ uint32_t shift)
46
+{
47
+ uint32_t *d = vd;
48
+ uint16_t mask = mve_element_mask(env);
49
+ unsigned e;
50
+ uint32_t r;
51
+
52
+ /*
53
+ * For each 32-bit element, we shift it left, bringing in the
54
+ * low 'shift' bits of rdm at the bottom. Bits shifted out at
55
+ * the top become the new rdm, if the predicate mask permits.
56
+ * The final rdm value is returned to update the register.
57
+ * shift == 0 here means "shift by 32 bits".
58
+ */
59
+ if (shift == 0) {
60
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
61
+ r = rdm;
62
+ if (mask & 1) {
63
+ rdm = d[H4(e)];
64
+ }
65
+ mergemask(&d[H4(e)], r, mask);
66
+ }
67
+ } else {
68
+ uint32_t shiftmask = MAKE_64BIT_MASK(0, shift);
69
+
70
+ for (e = 0; e < 16 / 4; e++, mask >>= 4) {
71
+ r = (d[H4(e)] << shift) | (rdm & shiftmask);
72
+ if (mask & 1) {
73
+ rdm = d[H4(e)] >> (32 - shift);
74
+ }
75
+ mergemask(&d[H4(e)], r, mask);
76
+ }
77
+ }
78
+ mve_advance_vpt(env);
79
+ return rdm;
80
+}
81
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/translate-mve.c
84
+++ b/target/arm/translate-mve.c
85
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
86
DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
87
DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
88
DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
89
+
90
+static bool trans_VSHLC(DisasContext *s, arg_VSHLC *a)
91
+{
92
+ /*
93
+ * Whole Vector Left Shift with Carry. The carry is taken
94
+ * from a general purpose register and written back there.
95
+ * An imm of 0 means "shift by 32".
96
+ */
97
+ TCGv_ptr qd;
98
+ TCGv_i32 rdm;
99
+
100
+ if (!dc_isar_feature(aa32_mve, s) || !mve_check_qreg_bank(s, a->qd)) {
101
+ return false;
102
+ }
103
+ if (a->rdm == 13 || a->rdm == 15) {
104
+ /* CONSTRAINED UNPREDICTABLE: we UNDEF */
105
+ return false;
106
+ }
107
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
108
+ return true;
109
+ }
110
+
111
+ qd = mve_qreg_ptr(a->qd);
112
+ rdm = load_reg(s, a->rdm);
113
+ gen_helper_mve_vshlc(rdm, cpu_env, qd, rdm, tcg_constant_i32(a->imm));
114
+ store_reg(s, a->rdm, rdm);
115
+ tcg_temp_free_ptr(qd);
116
+ mve_update_eci(s);
117
+ return true;
118
+}
119
--
25
--
120
2.20.1
26
2.34.1
121
122
diff view generated by jsdifflib
1
The function asimd_imm_const() in translate-neon.c is an
1
Add the Cortex-R52 IMPDEF sysregs, by defining them here and
2
implementation of the pseudocode AdvSIMDExpandImm(), which we will
2
also by enabling the AUXCR feature which defines the ACTLR
3
also want for MVE. Move the implementation to translate.c, with a
3
and HACTLR registers. As is our usual practice, we make these
4
prototype in translate.h.
4
simple reads-as-zero stubs for now.
5
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-4-peter.maydell@linaro.org
8
Message-id: 20240206132931.38376-4-peter.maydell@linaro.org
9
---
9
---
10
target/arm/translate.h | 16 ++++++++++
10
target/arm/tcg/cpu32.c | 108 +++++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-neon.c | 63 -------------------------------------
11
1 file changed, 108 insertions(+)
12
target/arm/translate.c | 57 +++++++++++++++++++++++++++++++++
13
3 files changed, 73 insertions(+), 63 deletions(-)
14
12
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
15
--- a/target/arm/tcg/cpu32.c
18
+++ b/target/arm/translate.h
16
+++ b/target/arm/tcg/cpu32.c
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
20
return opc | s->be_data;
18
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
21
}
19
}
22
20
23
+/**
21
+static const ARMCPRegInfo cortex_r52_cp_reginfo[] = {
24
+ * asimd_imm_const: Expand an encoded SIMD constant value
22
+ { .name = "CPUACTLR", .cp = 15, .opc1 = 0, .crm = 15,
25
+ *
23
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
26
+ * Expand a SIMD constant value. This is essentially the pseudocode
24
+ { .name = "IMP_ATCMREGIONR",
27
+ * AdvSIMDExpandImm, except that we also perform the boolean NOT needed for
25
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
28
+ * VMVN and VBIC (when cmode < 14 && op == 1).
26
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
29
+ *
27
+ { .name = "IMP_BTCMREGIONR",
30
+ * The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
28
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
31
+ * callers must catch this.
29
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
32
+ *
30
+ { .name = "IMP_CTCMREGIONR",
33
+ * cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
31
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 2,
34
+ * is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
32
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
35
+ * we produce an immediate constant value of 0 in these cases.
33
+ { .name = "IMP_CSCTLR",
36
+ */
34
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 0,
37
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
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
+};
38
+
124
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
125
+
40
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
126
static void cortex_r52_initfn(Object *obj)
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-neon.c
43
+++ b/target/arm/translate-neon.c
44
@@ -XXX,XX +XXX,XX @@ DO_FP_2SH(VCVT_UH, gen_helper_gvec_vcvt_uh)
45
DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_hs)
46
DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_hu)
47
48
-static uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
49
-{
50
- /*
51
- * Expand the encoded constant.
52
- * Note that cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
53
- * We choose to not special-case this and will behave as if a
54
- * valid constant encoding of 0 had been given.
55
- * cmode = 15 op = 1 must UNDEF; we assume decode has handled that.
56
- */
57
- switch (cmode) {
58
- case 0: case 1:
59
- /* no-op */
60
- break;
61
- case 2: case 3:
62
- imm <<= 8;
63
- break;
64
- case 4: case 5:
65
- imm <<= 16;
66
- break;
67
- case 6: case 7:
68
- imm <<= 24;
69
- break;
70
- case 8: case 9:
71
- imm |= imm << 16;
72
- break;
73
- case 10: case 11:
74
- imm = (imm << 8) | (imm << 24);
75
- break;
76
- case 12:
77
- imm = (imm << 8) | 0xff;
78
- break;
79
- case 13:
80
- imm = (imm << 16) | 0xffff;
81
- break;
82
- case 14:
83
- if (op) {
84
- /*
85
- * This is the only case where the top and bottom 32 bits
86
- * of the encoded constant differ.
87
- */
88
- uint64_t imm64 = 0;
89
- int n;
90
-
91
- for (n = 0; n < 8; n++) {
92
- if (imm & (1 << n)) {
93
- imm64 |= (0xffULL << (n * 8));
94
- }
95
- }
96
- return imm64;
97
- }
98
- imm |= (imm << 8) | (imm << 16) | (imm << 24);
99
- break;
100
- case 15:
101
- imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
102
- | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
103
- break;
104
- }
105
- if (op) {
106
- imm = ~imm;
107
- }
108
- return dup_const(MO_32, imm);
109
-}
110
-
111
static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
112
GVecGen2iFn *fn)
113
{
127
{
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
128
ARMCPU *cpu = ARM_CPU(obj);
115
index XXXXXXX..XXXXXXX 100644
129
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
116
--- a/target/arm/translate.c
130
set_feature(&cpu->env, ARM_FEATURE_NEON);
117
+++ b/target/arm/translate.c
131
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
118
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
132
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
119
a64_translate_init();
133
+ set_feature(&cpu->env, ARM_FEATURE_AUXCR);
134
cpu->midr = 0x411fd133; /* r1p3 */
135
cpu->revidr = 0x00000000;
136
cpu->reset_fpsid = 0x41034023;
137
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
138
139
cpu->pmsav7_dregion = 16;
140
cpu->pmsav8r_hdregion = 16;
141
+
142
+ define_arm_cp_regs(cpu, cortex_r52_cp_reginfo);
120
}
143
}
121
144
122
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
145
static void cortex_r5f_initfn(Object *obj)
123
+{
124
+ /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
125
+ switch (cmode) {
126
+ case 0: case 1:
127
+ /* no-op */
128
+ break;
129
+ case 2: case 3:
130
+ imm <<= 8;
131
+ break;
132
+ case 4: case 5:
133
+ imm <<= 16;
134
+ break;
135
+ case 6: case 7:
136
+ imm <<= 24;
137
+ break;
138
+ case 8: case 9:
139
+ imm |= imm << 16;
140
+ break;
141
+ case 10: case 11:
142
+ imm = (imm << 8) | (imm << 24);
143
+ break;
144
+ case 12:
145
+ imm = (imm << 8) | 0xff;
146
+ break;
147
+ case 13:
148
+ imm = (imm << 16) | 0xffff;
149
+ break;
150
+ case 14:
151
+ if (op) {
152
+ /*
153
+ * This is the only case where the top and bottom 32 bits
154
+ * of the encoded constant differ.
155
+ */
156
+ uint64_t imm64 = 0;
157
+ int n;
158
+
159
+ for (n = 0; n < 8; n++) {
160
+ if (imm & (1 << n)) {
161
+ imm64 |= (0xffULL << (n * 8));
162
+ }
163
+ }
164
+ return imm64;
165
+ }
166
+ imm |= (imm << 8) | (imm << 16) | (imm << 24);
167
+ break;
168
+ case 15:
169
+ imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
170
+ | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
171
+ break;
172
+ }
173
+ if (op) {
174
+ imm = ~imm;
175
+ }
176
+ return dup_const(MO_32, imm);
177
+}
178
+
179
/* Generate a label used for skipping this instruction */
180
void arm_gen_condlabel(DisasContext *s)
181
{
182
--
146
--
183
2.20.1
147
2.34.1
184
185
diff view generated by jsdifflib
1
The A64 AdvSIMD modified-immediate grouping uses almost the same
1
Architecturally, the AArch32 MSR/MRS to/from banked register
2
constant encoding that A32 Neon does; reuse asimd_imm_const() (to
2
instructions are UNPREDICTABLE for attempts to access a banked
3
which we add the AArch64-specific case for cmode 15 op 1) instead of
3
register that the guest could access in a more direct way (e.g.
4
reimplementing it all.
4
using this insn to access r8_fiq when already in FIQ mode). QEMU has
5
chosen to UNDEF on all of these.
6
7
However, for the case of accessing SPSR_hyp from hyp mode, it turns
8
out that real hardware permits this, with the same effect as if the
9
guest had directly written to SPSR. Further, there is some
10
guest code out there that assumes it can do this, because it
11
happens to work on hardware: an example Cortex-R52 startup code
12
fragment uses this, and it got copied into various other places,
13
including Zephyr. Zephyr was fixed to not use this:
14
https://github.com/zephyrproject-rtos/zephyr/issues/47330
15
but other examples are still out there, like the selftest
16
binary for the MPS3-AN536.
17
18
For convenience of being able to run guest code, permit
19
this UNPREDICTABLE access instead of UNDEFing it.
5
20
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-5-peter.maydell@linaro.org
23
Message-id: 20240206132931.38376-5-peter.maydell@linaro.org
9
---
24
---
10
target/arm/translate.h | 3 +-
25
target/arm/tcg/op_helper.c | 43 ++++++++++++++++++++++++++------------
11
target/arm/translate-a64.c | 86 ++++----------------------------------
26
target/arm/tcg/translate.c | 19 +++++++++++------
12
target/arm/translate.c | 17 +++++++-
27
2 files changed, 43 insertions(+), 19 deletions(-)
13
3 files changed, 24 insertions(+), 82 deletions(-)
14
28
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
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/target/arm/translate.h
31
--- a/target/arm/tcg/op_helper.c
18
+++ b/target/arm/translate.h
32
+++ b/target/arm/tcg/op_helper.c
19
@@ -XXX,XX +XXX,XX @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
33
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
20
* VMVN and VBIC (when cmode < 14 && op == 1).
34
*/
21
*
35
int curmode = env->uncached_cpsr & CPSR_M;
22
* The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
36
23
- * callers must catch this.
37
- if (regno == 17) {
24
+ * callers must catch this; we return the 64-bit constant value defined
38
- /* ELR_Hyp: a special case because access from tgtmode is OK */
25
+ * for AArch64.
39
- if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
26
*
40
- goto undef;
27
* cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
41
+ if (tgtmode == ARM_CPU_MODE_HYP) {
28
* is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
42
+ /*
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
43
+ * Handle Hyp target regs first because some are special cases
30
index XXXXXXX..XXXXXXX 100644
44
+ * which don't want the usual "not accessible from tgtmode" check.
31
--- a/target/arm/translate-a64.c
45
+ */
32
+++ b/target/arm/translate-a64.c
46
+ switch (regno) {
33
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
47
+ case 16 ... 17: /* ELR_Hyp, SPSR_Hyp */
34
{
48
+ if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
35
int rd = extract32(insn, 0, 5);
49
+ goto undef;
36
int cmode = extract32(insn, 12, 4);
50
+ }
37
- int cmode_3_1 = extract32(cmode, 1, 3);
51
+ break;
38
- int cmode_0 = extract32(cmode, 0, 1);
52
+ case 13:
39
int o2 = extract32(insn, 11, 1);
53
+ if (curmode != ARM_CPU_MODE_MON) {
40
uint64_t abcdefgh = extract32(insn, 5, 5) | (extract32(insn, 16, 3) << 5);
54
+ goto undef;
41
bool is_neg = extract32(insn, 29, 1);
55
+ }
42
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
56
+ break;
57
+ default:
58
+ g_assert_not_reached();
59
}
43
return;
60
return;
44
}
61
}
45
62
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
46
- /* See AdvSIMDExpandImm() in ARM ARM */
63
}
47
- switch (cmode_3_1) {
64
}
48
- case 0: /* Replicate(Zeros(24):imm8, 2) */
65
49
- case 1: /* Replicate(Zeros(16):imm8:Zeros(8), 2) */
66
- if (tgtmode == ARM_CPU_MODE_HYP) {
50
- case 2: /* Replicate(Zeros(8):imm8:Zeros(16), 2) */
67
- /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
51
- case 3: /* Replicate(imm8:Zeros(24), 2) */
68
- if (curmode != ARM_CPU_MODE_MON) {
52
- {
69
- goto undef;
53
- int shift = cmode_3_1 * 8;
54
- imm = bitfield_replicate(abcdefgh << shift, 32);
55
- break;
56
- }
57
- case 4: /* Replicate(Zeros(8):imm8, 4) */
58
- case 5: /* Replicate(imm8:Zeros(8), 4) */
59
- {
60
- int shift = (cmode_3_1 & 0x1) * 8;
61
- imm = bitfield_replicate(abcdefgh << shift, 16);
62
- break;
63
- }
64
- case 6:
65
- if (cmode_0) {
66
- /* Replicate(Zeros(8):imm8:Ones(16), 2) */
67
- imm = (abcdefgh << 16) | 0xffff;
68
- } else {
69
- /* Replicate(Zeros(16):imm8:Ones(8), 2) */
70
- imm = (abcdefgh << 8) | 0xff;
71
- }
70
- }
72
- imm = bitfield_replicate(imm, 32);
73
- break;
74
- case 7:
75
- if (!cmode_0 && !is_neg) {
76
- imm = bitfield_replicate(abcdefgh, 8);
77
- } else if (!cmode_0 && is_neg) {
78
- int i;
79
- imm = 0;
80
- for (i = 0; i < 8; i++) {
81
- if ((abcdefgh) & (1 << i)) {
82
- imm |= 0xffULL << (i * 8);
83
- }
84
- }
85
- } else if (cmode_0) {
86
- if (is_neg) {
87
- imm = (abcdefgh & 0x3f) << 48;
88
- if (abcdefgh & 0x80) {
89
- imm |= 0x8000000000000000ULL;
90
- }
91
- if (abcdefgh & 0x40) {
92
- imm |= 0x3fc0000000000000ULL;
93
- } else {
94
- imm |= 0x4000000000000000ULL;
95
- }
96
- } else {
97
- if (o2) {
98
- /* FMOV (vector, immediate) - half-precision */
99
- imm = vfp_expand_imm(MO_16, abcdefgh);
100
- /* now duplicate across the lanes */
101
- imm = bitfield_replicate(imm, 16);
102
- } else {
103
- imm = (abcdefgh & 0x3f) << 19;
104
- if (abcdefgh & 0x80) {
105
- imm |= 0x80000000;
106
- }
107
- if (abcdefgh & 0x40) {
108
- imm |= 0x3e000000;
109
- } else {
110
- imm |= 0x40000000;
111
- }
112
- imm |= (imm << 32);
113
- }
114
- }
115
- }
116
- break;
117
- default:
118
- g_assert_not_reached();
119
- }
71
- }
120
-
72
-
121
- if (cmode_3_1 != 7 && is_neg) {
73
return;
122
- imm = ~imm;
74
123
+ if (cmode == 15 && o2 && !is_neg) {
75
undef:
124
+ /* FMOV (vector, immediate) - half-precision */
76
@@ -XXX,XX +XXX,XX @@ void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
125
+ imm = vfp_expand_imm(MO_16, abcdefgh);
77
126
+ /* now duplicate across the lanes */
78
switch (regno) {
127
+ imm = bitfield_replicate(imm, 16);
79
case 16: /* SPSRs */
128
+ } else {
80
- env->banked_spsr[bank_number(tgtmode)] = value;
129
+ imm = asimd_imm_const(abcdefgh, cmode, is_neg);
81
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
130
}
82
+ /* Only happens for SPSR_Hyp access in Hyp mode */
131
83
+ env->spsr = value;
132
if (!((cmode & 0x9) == 0x1 || (cmode & 0xd) == 0x9)) {
84
+ } else {
133
diff --git a/target/arm/translate.c b/target/arm/translate.c
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
134
index XXXXXXX..XXXXXXX 100644
105
index XXXXXXX..XXXXXXX 100644
135
--- a/target/arm/translate.c
106
--- a/target/arm/tcg/translate.c
136
+++ b/target/arm/translate.c
107
+++ b/target/arm/tcg/translate.c
137
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
108
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
138
case 14:
139
if (op) {
140
/*
141
- * This is the only case where the top and bottom 32 bits
142
- * of the encoded constant differ.
143
+ * This and cmode == 15 op == 1 are the only cases where
144
+ * the top and bottom 32 bits of the encoded constant differ.
145
*/
146
uint64_t imm64 = 0;
147
int n;
148
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
149
imm |= (imm << 8) | (imm << 16) | (imm << 24);
150
break;
109
break;
151
case 15:
110
case ARM_CPU_MODE_HYP:
152
+ if (op) {
111
/*
153
+ /* Reserved encoding for AArch32; valid for AArch64 */
112
- * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
154
+ uint64_t imm64 = (uint64_t)(imm & 0x3f) << 48;
113
- * (and so we can forbid accesses from EL2 or below). elr_hyp
155
+ if (imm & 0x80) {
114
- * can be accessed also from Hyp mode, so forbid accesses from
156
+ imm64 |= 0x8000000000000000ULL;
115
- * EL0 or EL1.
157
+ }
116
+ * r13_hyp can only be accessed from Monitor mode, and so we
158
+ if (imm & 0x40) {
117
+ * can forbid accesses from EL2 or below.
159
+ imm64 |= 0x3fc0000000000000ULL;
118
+ * elr_hyp can be accessed also from Hyp mode, so forbid
160
+ } else {
119
+ * accesses from EL0 or EL1.
161
+ imm64 |= 0x4000000000000000ULL;
120
+ * SPSR_hyp is supposed to be in the same category as r13_hyp
162
+ }
121
+ * and UNPREDICTABLE if accessed from anything except Monitor
163
+ return imm64;
122
+ * mode. However there is some real-world code that will do
164
+ }
123
+ * it because at least some hardware happens to permit the
165
imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
124
+ * access. (Notably a standard Cortex-R52 startup code fragment
166
| ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
125
+ * does this.) So we permit SPSR_hyp from Hyp mode also, to allow
126
+ * this (incorrect) guest code to run.
127
*/
128
- if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
129
- (s->current_el < 3 && *regno != 17)) {
130
+ if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2
131
+ || (s->current_el < 3 && *regno != 16 && *regno != 17)) {
132
goto undef;
133
}
167
break;
134
break;
168
--
135
--
169
2.20.1
136
2.34.1
170
171
diff view generated by jsdifflib
1
Use dup_const() instead of bitfield_replicate() in
1
We currently guard the CFG3 register read with
2
disas_simd_mod_imm().
2
(scc_partno(s) == 0x524 && scc_partno(s) == 0x547)
3
which is clearly wrong as it is never true.
3
4
4
(We can't replace the other use of bitfield_replicate() in this file,
5
This register is present on all board types except AN524
5
in logic_imm_decode_wmask(), because that location needs to handle 2
6
and AN527; correct the condition.
6
and 4 bit elements, which dup_const() cannot.)
7
7
8
Fixes: 6ac80818941829c0 ("hw/misc/mps2-scc: Implement changes for AN547")
8
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>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210628135835.6690-6-peter.maydell@linaro.org
12
Message-id: 20240206132931.38376-6-peter.maydell@linaro.org
11
---
13
---
12
target/arm/translate-a64.c | 2 +-
14
hw/misc/mps2-scc.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 1 insertion(+), 1 deletion(-)
14
16
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
19
--- a/hw/misc/mps2-scc.c
18
+++ b/target/arm/translate-a64.c
20
+++ b/hw/misc/mps2-scc.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
21
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
20
/* FMOV (vector, immediate) - half-precision */
22
r = s->cfg2;
21
imm = vfp_expand_imm(MO_16, abcdefgh);
23
break;
22
/* now duplicate across the lanes */
24
case A_CFG3:
23
- imm = bitfield_replicate(imm, 16);
25
- if (scc_partno(s) == 0x524 && scc_partno(s) == 0x547) {
24
+ imm = dup_const(MO_16, imm);
26
+ if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
25
} else {
27
/* CFG3 reserved on AN524 */
26
imm = asimd_imm_const(abcdefgh, cmode, is_neg);
28
goto bad_offset;
27
}
29
}
28
--
30
--
29
2.20.1
31
2.34.1
30
32
31
33
diff view generated by jsdifflib
1
Implement the MVE vector shift right by immediate insns VSHRI and
1
The MPS SCC device has a lot of different flavours for the various
2
VRSHRI. As with Neon, we implement these by using helper functions
2
different MPS FPGA images, which look mostly similar but have
3
which perform left shifts but allow negative shift counts to indicate
3
differences in how particular registers are handled. Currently we
4
right shifts.
4
deal with this with a lot of open-coded checks on scc_partno(), but
5
as we add more board types this is getting a bit hard to read.
6
7
Factor out the conditions into some functions which we can
8
give more descriptive names to.
5
9
6
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>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210628135835.6690-9-peter.maydell@linaro.org
13
Message-id: 20240206132931.38376-7-peter.maydell@linaro.org
9
---
14
---
10
target/arm/helper-mve.h | 12 ++++++++++++
15
hw/misc/mps2-scc.c | 45 +++++++++++++++++++++++++++++++--------------
11
target/arm/translate.h | 20 ++++++++++++++++++++
16
1 file changed, 31 insertions(+), 14 deletions(-)
12
target/arm/mve.decode | 28 ++++++++++++++++++++++++++++
13
target/arm/mve_helper.c | 7 +++++++
14
target/arm/translate-mve.c | 5 +++++
15
target/arm/translate-neon.c | 18 ------------------
16
6 files changed, 72 insertions(+), 18 deletions(-)
17
17
18
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.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/helper-mve.h
20
--- a/hw/misc/mps2-scc.c
21
+++ b/target/arm/helper-mve.h
21
+++ b/hw/misc/mps2-scc.c
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
22
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
23
return extract32(s->id, 4, 8);
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
25
26
+DEF_HELPER_FLAGS_4(mve_vshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(mve_vshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(mve_vshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
+
30
DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+
38
+DEF_HELPER_FLAGS_4(mve_vrshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_4(mve_vrshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(mve_vrshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
+
42
+DEF_HELPER_FLAGS_4(mve_vrshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_4(mve_vrshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_4(mve_vrshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
diff --git a/target/arm/translate.h b/target/arm/translate.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/translate.h
48
+++ b/target/arm/translate.h
49
@@ -XXX,XX +XXX,XX @@ static inline int times_2_plus_1(DisasContext *s, int x)
50
return x * 2 + 1;
51
}
24
}
52
25
53
+static inline int rsub_64(DisasContext *s, int x)
26
+/* Is CFG_REG2 present? */
27
+static bool have_cfg2(MPS2SCC *s)
54
+{
28
+{
55
+ return 64 - x;
29
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
56
+}
30
+}
57
+
31
+
58
+static inline int rsub_32(DisasContext *s, int x)
32
+/* Is CFG_REG3 present? */
33
+static bool have_cfg3(MPS2SCC *s)
59
+{
34
+{
60
+ return 32 - x;
35
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
61
+}
36
+}
62
+
37
+
63
+static inline int rsub_16(DisasContext *s, int x)
38
+/* Is CFG_REG5 present? */
39
+static bool have_cfg5(MPS2SCC *s)
64
+{
40
+{
65
+ return 16 - x;
41
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
66
+}
42
+}
67
+
43
+
68
+static inline int rsub_8(DisasContext *s, int x)
44
+/* Is CFG_REG6 present? */
45
+static bool have_cfg6(MPS2SCC *s)
69
+{
46
+{
70
+ return 8 - x;
47
+ return scc_partno(s) == 0x524;
71
+}
48
+}
72
+
49
+
73
static inline int arm_dc_feature(DisasContext *dc, int feature)
50
/* Handle a write via the SYS_CFG channel to the specified function/device.
74
{
51
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
75
return (dc->features & (1ULL << feature)) != 0;
52
*/
76
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
53
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
77
index XXXXXXX..XXXXXXX 100644
54
r = s->cfg1;
78
--- a/target/arm/mve.decode
55
break;
79
+++ b/target/arm/mve.decode
56
case A_CFG2:
80
@@ -XXX,XX +XXX,XX @@
57
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
81
@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
58
- /* CFG2 reserved on other boards */
82
@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
59
+ if (!have_cfg2(s)) {
83
60
goto bad_offset;
84
+# Right shifts are encoded as N - shift, where N is the element size in bits.
61
}
85
+%rshift_i5 16:5 !function=rsub_32
62
r = s->cfg2;
86
+%rshift_i4 16:4 !function=rsub_16
63
break;
87
+%rshift_i3 16:3 !function=rsub_8
64
case A_CFG3:
88
+
65
- if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
89
+@2_shr_b .... .... .. 001 ... .... .... .... .... &2shift qd=%qd qm=%qm \
66
- /* CFG3 reserved on AN524 */
90
+ size=0 shift=%rshift_i3
67
+ if (!have_cfg3(s)) {
91
+@2_shr_h .... .... .. 01 .... .... .... .... .... &2shift qd=%qd qm=%qm \
68
goto bad_offset;
92
+ size=1 shift=%rshift_i4
69
}
93
+@2_shr_w .... .... .. 1 ..... .... .... .... .... &2shift qd=%qd qm=%qm \
70
/* These are user-settable DIP switches on the board. We don't
94
+ size=2 shift=%rshift_i5
71
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
95
+
72
r = s->cfg4;
96
# Vector loads and stores
73
break;
97
74
case A_CFG5:
98
# Widening loads and narrowing stores:
75
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
99
@@ -XXX,XX +XXX,XX @@ VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
76
- /* CFG5 reserved on other boards */
100
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
77
+ if (!have_cfg5(s)) {
101
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
78
goto bad_offset;
102
VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
79
}
103
+
80
r = s->cfg5;
104
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
81
break;
105
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
82
case A_CFG6:
106
+VSHRI_S 111 0 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
83
- if (scc_partno(s) != 0x524) {
107
+
84
- /* CFG6 reserved on other boards */
108
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_b
85
+ if (!have_cfg6(s)) {
109
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_h
86
goto bad_offset;
110
+VSHRI_U 111 1 1111 1 . ... ... ... 0 0000 0 1 . 1 ... 0 @2_shr_w
87
}
111
+
88
r = s->cfg6;
112
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
89
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
113
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
90
}
114
+VRSHRI_S 111 0 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
91
break;
115
+
92
case A_CFG2:
116
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_b
93
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
117
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_h
94
- /* CFG2 reserved on other boards */
118
+VRSHRI_U 111 1 1111 1 . ... ... ... 0 0010 0 1 . 1 ... 0 @2_shr_w
95
+ if (!have_cfg2(s)) {
119
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
96
goto bad_offset;
120
index XXXXXXX..XXXXXXX 100644
97
}
121
--- a/target/arm/mve_helper.c
98
/* AN524: QSPI Select signal */
122
+++ b/target/arm/mve_helper.c
99
s->cfg2 = value;
123
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
100
break;
124
DO_2SHIFT(OP##b, 1, uint8_t, FN) \
101
case A_CFG5:
125
DO_2SHIFT(OP##h, 2, uint16_t, FN) \
102
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
126
DO_2SHIFT(OP##w, 4, uint32_t, FN)
103
- /* CFG5 reserved on other boards */
127
+#define DO_2SHIFT_S(OP, FN) \
104
+ if (!have_cfg5(s)) {
128
+ DO_2SHIFT(OP##b, 1, int8_t, FN) \
105
goto bad_offset;
129
+ DO_2SHIFT(OP##h, 2, int16_t, FN) \
106
}
130
+ DO_2SHIFT(OP##w, 4, int32_t, FN)
107
/* AN524: ACLK frequency in Hz */
131
108
s->cfg5 = value;
132
#define DO_2SHIFT_SAT_U(OP, FN) \
109
break;
133
DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
110
case A_CFG6:
134
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvuw, 4, uint32_t)
111
- if (scc_partno(s) != 0x524) {
135
DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
112
- /* CFG6 reserved on other boards */
136
113
+ if (!have_cfg6(s)) {
137
DO_2SHIFT_U(vshli_u, DO_VSHLU)
114
goto bad_offset;
138
+DO_2SHIFT_S(vshli_s, DO_VSHLS)
115
}
139
DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
116
/* AN524: Clock divider for BRAM */
140
DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
141
DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
142
+DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
143
+DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
144
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/target/arm/translate-mve.c
147
+++ b/target/arm/translate-mve.c
148
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHLI, vshli_u, false)
149
DO_2SHIFT(VQSHLI_S, vqshli_s, false)
150
DO_2SHIFT(VQSHLI_U, vqshli_u, false)
151
DO_2SHIFT(VQSHLUI, vqshlui_s, false)
152
+/* These right shifts use a left-shift helper with negated shift count */
153
+DO_2SHIFT(VSHRI_S, vshli_s, true)
154
+DO_2SHIFT(VSHRI_U, vshli_u, true)
155
+DO_2SHIFT(VRSHRI_S, vrshli_s, true)
156
+DO_2SHIFT(VRSHRI_U, vrshli_u, true)
157
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/target/arm/translate-neon.c
160
+++ b/target/arm/translate-neon.c
161
@@ -XXX,XX +XXX,XX @@ static inline int plus1(DisasContext *s, int x)
162
return x + 1;
163
}
164
165
-static inline int rsub_64(DisasContext *s, int x)
166
-{
167
- return 64 - x;
168
-}
169
-
170
-static inline int rsub_32(DisasContext *s, int x)
171
-{
172
- return 32 - x;
173
-}
174
-static inline int rsub_16(DisasContext *s, int x)
175
-{
176
- return 16 - x;
177
-}
178
-static inline int rsub_8(DisasContext *s, int x)
179
-{
180
- return 8 - x;
181
-}
182
-
183
static inline int neon_3same_fp_size(DisasContext *s, int x)
184
{
185
/* Convert 0==fp32, 1==fp16 into a MO_* value */
186
--
117
--
187
2.20.1
118
2.34.1
188
119
189
120
diff view generated by jsdifflib
1
Implement the MVE shift-right-and-narrow insn VSHRN and VRSHRN.
1
The MPS2 SCC device is broadly the same for all FPGA images, but has
2
2
minor differences in the behaviour of the CFG registers depending on
3
do_urshr() is borrowed from sve_helper.c.
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.
4
34
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
36
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210628135835.6690-12-peter.maydell@linaro.org
37
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
38
Message-id: 20240206132931.38376-8-peter.maydell@linaro.org
8
---
39
---
9
target/arm/helper-mve.h | 10 ++++++++++
40
include/hw/misc/mps2-scc.h | 1 +
10
target/arm/mve.decode | 11 +++++++++++
41
hw/misc/mps2-scc.c | 101 +++++++++++++++++++++++++++++++++----
11
target/arm/mve_helper.c | 40 ++++++++++++++++++++++++++++++++++++++
42
2 files changed, 92 insertions(+), 10 deletions(-)
12
target/arm/translate-mve.c | 15 ++++++++++++++
43
13
4 files changed, 76 insertions(+)
44
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
14
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
16
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-mve.h
46
--- a/include/hw/misc/mps2-scc.h
18
+++ b/target/arm/helper-mve.h
47
+++ b/include/hw/misc/mps2-scc.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
48
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
20
DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
49
uint32_t cfg4;
21
DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
50
uint32_t cfg5;
22
DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
51
uint32_t cfg6;
23
+
52
+ uint32_t cfg7;
24
+DEF_HELPER_FLAGS_4(mve_vshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
53
uint32_t cfgdata_rtn;
25
+DEF_HELPER_FLAGS_4(mve_vshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
54
uint32_t cfgdata_out;
26
+DEF_HELPER_FLAGS_4(mve_vshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
55
uint32_t cfgctrl;
27
+DEF_HELPER_FLAGS_4(mve_vshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
56
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
28
+
29
+DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
34
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/mve.decode
58
--- a/hw/misc/mps2-scc.c
36
+++ b/target/arm/mve.decode
59
+++ b/hw/misc/mps2-scc.c
37
@@ -XXX,XX +XXX,XX @@ VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
60
@@ -XXX,XX +XXX,XX @@ REG32(CFG3, 0xc)
38
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
61
REG32(CFG4, 0x10)
39
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
62
REG32(CFG5, 0x14)
40
VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
63
REG32(CFG6, 0x18)
41
+
64
+REG32(CFG7, 0x1c)
42
+# Narrowing shifts (which only support b and h sizes)
65
REG32(CFGDATA_RTN, 0xa0)
43
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
66
REG32(CFGDATA_OUT, 0xa4)
44
+VSHRNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
67
REG32(CFGCTRL, 0xa8)
45
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
68
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
46
+VSHRNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
69
/* Is CFG_REG2 present? */
47
+
70
static bool have_cfg2(MPS2SCC *s)
48
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
71
{
49
+VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
72
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
50
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
73
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
51
+VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
74
+ scc_partno(s) == 0x536;
52
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
75
}
53
index XXXXXXX..XXXXXXX 100644
76
54
--- a/target/arm/mve_helper.c
77
/* Is CFG_REG3 present? */
55
+++ b/target/arm/mve_helper.c
78
static bool have_cfg3(MPS2SCC *s)
56
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
79
{
57
80
- return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
58
DO_VSHLL_ALL(vshllb, false)
81
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547 &&
59
DO_VSHLL_ALL(vshllt, true)
82
+ scc_partno(s) != 0x536;
60
+
83
}
61
+/*
84
62
+ * Narrowing right shifts, taking a double sized input, shifting it
85
/* Is CFG_REG5 present? */
63
+ * and putting the result in either the top or bottom half of the output.
86
static bool have_cfg5(MPS2SCC *s)
64
+ * ESIZE, TYPE are the output, and LESIZE, LTYPE the input.
87
{
65
+ */
88
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
66
+#define DO_VSHRN(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
89
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
67
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
90
+ scc_partno(s) == 0x536;
68
+ void *vm, uint32_t shift) \
91
}
69
+ { \
92
70
+ LTYPE *m = vm; \
93
/* Is CFG_REG6 present? */
71
+ TYPE *d = vd; \
94
static bool have_cfg6(MPS2SCC *s)
72
+ uint16_t mask = mve_element_mask(env); \
95
{
73
+ unsigned le; \
96
- return scc_partno(s) == 0x524;
74
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
97
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x536;
75
+ TYPE r = FN(m[H##LESIZE(le)], shift); \
98
+}
76
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
99
+
77
+ } \
100
+/* Is CFG_REG7 present? */
78
+ mve_advance_vpt(env); \
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()
79
+ }
233
+ }
80
+
234
+};
81
+#define DO_VSHRN_ALL(OP, FN) \
235
+
82
+ DO_VSHRN(OP##bb, false, 1, uint8_t, 2, uint16_t, FN) \
236
static const VMStateDescription mps2_scc_vmstate = {
83
+ DO_VSHRN(OP##bh, false, 2, uint16_t, 4, uint32_t, FN) \
237
.name = "mps2-scc",
84
+ DO_VSHRN(OP##tb, true, 1, uint8_t, 2, uint16_t, FN) \
238
.version_id = 3,
85
+ DO_VSHRN(OP##th, true, 2, uint16_t, 4, uint32_t, FN)
239
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_scc_vmstate = {
86
+
240
VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
87
+static inline uint64_t do_urshr(uint64_t x, unsigned sh)
241
0, vmstate_info_uint32, uint32_t),
88
+{
242
VMSTATE_END_OF_LIST()
89
+ if (likely(sh < 64)) {
243
+ },
90
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
244
+ .subsections = (const VMStateDescription * const []) {
91
+ } else if (sh == 64) {
245
+ &vmstate_cfg7,
92
+ return x >> 63;
246
+ NULL
93
+ } else {
247
}
94
+ return 0;
248
};
95
+ }
249
96
+}
97
+
98
+DO_VSHRN_ALL(vshrn, DO_SHR)
99
+DO_VSHRN_ALL(vrshrn, do_urshr)
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/translate-mve.c
103
+++ b/target/arm/translate-mve.c
104
@@ -XXX,XX +XXX,XX @@ DO_VSHLL(VSHLL_BS, vshllbs)
105
DO_VSHLL(VSHLL_BU, vshllbu)
106
DO_VSHLL(VSHLL_TS, vshllts)
107
DO_VSHLL(VSHLL_TU, vshlltu)
108
+
109
+#define DO_2SHIFT_N(INSN, FN) \
110
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
111
+ { \
112
+ static MVEGenTwoOpShiftFn * const fns[] = { \
113
+ gen_helper_mve_##FN##b, \
114
+ gen_helper_mve_##FN##h, \
115
+ }; \
116
+ return do_2shift(s, a, fns[a->size], false); \
117
+ }
118
+
119
+DO_2SHIFT_N(VSHRNB, vshrnb)
120
+DO_2SHIFT_N(VSHRNT, vshrnt)
121
+DO_2SHIFT_N(VRSHRNB, vrshrnb)
122
+DO_2SHIFT_N(VRSHRNT, vrshrnt)
123
--
250
--
124
2.20.1
251
2.34.1
125
252
126
253
diff view generated by jsdifflib
1
From: Nolan Leake <nolan@sigbus.net>
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
This is just enough to make reboot and poweroff work. Works for
3
family CPU, and it does not use any equivalent to the M-profile
4
linux, u-boot, and the arm trusted firmware. Not tested, but should
4
"Subsystem for Embedded" SoC-equivalent that we model in hw/arm/armsse.c.
5
work for plan9, and bare-metal/hobby OSes, since they seem to generally
5
It's therefore more convenient for us to model it as a completely
6
do what linux does for reset.
6
separate C file.
7
7
8
The watchdog timer functionality is not yet implemented.
8
This commit adds the basic skeleton of the board model, and the
9
9
code to create all the RAM and ROM. We assume that we're probably
10
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/64
10
going to want to add more images in future, so use the same
11
Signed-off-by: Nolan Leake <nolan@sigbus.net>
11
base class/subclass setup that mps2-tz.c uses, even though at
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
the moment there's only a single subclass.
13
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
14
Message-id: 20210625210209.1870217-1-nolan@sigbus.net
14
Following commits will add the CPUs and the peripherals.
15
[PMM: tweaked commit title; fixed region size to 0x200;
15
16
moved header file to include/]
17
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
18
---
19
---
19
include/hw/arm/bcm2835_peripherals.h | 3 +-
20
MAINTAINERS | 3 +-
20
include/hw/misc/bcm2835_powermgt.h | 29 +++++
21
configs/devices/arm-softmmu/default.mak | 1 +
21
hw/arm/bcm2835_peripherals.c | 13 ++-
22
hw/arm/mps3r.c | 239 ++++++++++++++++++++++++
22
hw/misc/bcm2835_powermgt.c | 160 +++++++++++++++++++++++++++
23
hw/arm/Kconfig | 5 +
23
hw/misc/meson.build | 1 +
24
hw/arm/meson.build | 1 +
24
5 files changed, 204 insertions(+), 2 deletions(-)
25
5 files changed, 248 insertions(+), 1 deletion(-)
25
create mode 100644 include/hw/misc/bcm2835_powermgt.h
26
create mode 100644 hw/arm/mps3r.c
26
create mode 100644 hw/misc/bcm2835_powermgt.c
27
27
28
diff --git a/MAINTAINERS b/MAINTAINERS
28
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
29
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/arm/bcm2835_peripherals.h
30
--- a/MAINTAINERS
31
+++ b/include/hw/arm/bcm2835_peripherals.h
31
+++ b/MAINTAINERS
32
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@ F: include/hw/misc/imx7_*.h
33
#include "hw/misc/bcm2835_mphi.h"
33
F: hw/pci-host/designware.c
34
#include "hw/misc/bcm2835_thermal.h"
34
F: include/hw/pci-host/designware.h
35
#include "hw/misc/bcm2835_cprman.h"
35
36
+#include "hw/misc/bcm2835_powermgt.h"
36
-MPS2
37
#include "hw/sd/sdhci.h"
37
+MPS2 / MPS3
38
#include "hw/sd/bcm2835_sdhost.h"
38
M: Peter Maydell <peter.maydell@linaro.org>
39
#include "hw/gpio/bcm2835_gpio.h"
39
L: qemu-arm@nongnu.org
40
@@ -XXX,XX +XXX,XX @@ struct BCM2835PeripheralState {
40
S: Maintained
41
BCM2835MphiState mphi;
41
F: hw/arm/mps2.c
42
UnimplementedDeviceState txp;
42
F: hw/arm/mps2-tz.c
43
UnimplementedDeviceState armtmr;
43
+F: hw/arm/mps3r.c
44
- UnimplementedDeviceState powermgt;
44
F: hw/misc/mps2-*.c
45
+ BCM2835PowerMgtState powermgt;
45
F: include/hw/misc/mps2-*.h
46
BCM2835CprmanState cprman;
46
F: hw/arm/armsse.c
47
PL011State uart0;
47
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
48
BCM2835AuxState aux;
48
index XXXXXXX..XXXXXXX 100644
49
diff --git a/include/hw/misc/bcm2835_powermgt.h b/include/hw/misc/bcm2835_powermgt.h
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
50
new file mode 100644
60
new file mode 100644
51
index XXXXXXX..XXXXXXX
61
index XXXXXXX..XXXXXXX
52
--- /dev/null
62
--- /dev/null
53
+++ b/include/hw/misc/bcm2835_powermgt.h
63
+++ b/hw/arm/mps3r.c
54
@@ -XXX,XX +XXX,XX @@
64
@@ -XXX,XX +XXX,XX @@
55
+/*
65
+/*
56
+ * BCM2835 Power Management emulation
66
+ * Arm MPS3 board emulation for Cortex-R-based FPGA images.
67
+ * (For M-profile images see mps2.c and mps2tz.c.)
57
+ *
68
+ *
58
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
69
+ * Copyright (c) 2017 Linaro Limited
59
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
70
+ * Written by Peter Maydell
60
+ *
71
+ *
61
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
72
+ * This program is free software; you can redistribute it and/or modify
62
+ * See the COPYING file in the top-level directory.
73
+ * it under the terms of the GNU General Public License version 2 or
74
+ * (at your option) any later version.
63
+ */
75
+ */
64
+
76
+
65
+#ifndef BCM2835_POWERMGT_H
77
+/*
66
+#define BCM2835_POWERMGT_H
78
+ * The MPS3 is an FPGA based dev board. This file handles FPGA images
67
+
79
+ * which use the Cortex-R CPUs. We model these separately from the
68
+#include "hw/sysbus.h"
80
+ * M-profile images, because on M-profile the FPGA image is based on
69
+#include "qom/object.h"
81
+ * a "Subsystem for Embedded" which is similar to an SoC, whereas
70
+
82
+ * the R-profile FPGA images don't have that abstraction layer.
71
+#define TYPE_BCM2835_POWERMGT "bcm2835-powermgt"
83
+ *
72
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835PowerMgtState, BCM2835_POWERMGT)
84
+ * We model the following FPGA images here:
73
+
85
+ * "mps3-an536" -- dual Cortex-R52 as documented in Arm Application Note AN536
74
+struct BCM2835PowerMgtState {
86
+ *
75
+ SysBusDevice busdev;
87
+ * Application Note AN536:
76
+ MemoryRegion iomem;
88
+ * https://developer.arm.com/documentation/dai0536/latest/
77
+
89
+ */
78
+ uint32_t rstc;
90
+
79
+ uint32_t rsts;
91
+#include "qemu/osdep.h"
80
+ uint32_t wdog;
92
+#include "qemu/units.h"
93
+#include "qapi/error.h"
94
+#include "exec/address-spaces.h"
95
+#include "cpu.h"
96
+#include "hw/boards.h"
97
+#include "hw/arm/boot.h"
98
+
99
+/* Define the layout of RAM and ROM in a board */
100
+typedef struct RAMInfo {
101
+ const char *name;
102
+ hwaddr base;
103
+ hwaddr size;
104
+ int mrindex; /* index into rams[]; -1 for the system RAM block */
105
+ int flags;
106
+} RAMInfo;
107
+
108
+/*
109
+ * The MPS3 DDR is 3GiB, but on a 32-bit host QEMU doesn't permit
110
+ * emulation of that much guest RAM, so artificially make it smaller.
111
+ */
112
+#if HOST_LONG_BITS == 32
113
+#define MPS3_DDR_SIZE (1 * GiB)
114
+#else
115
+#define MPS3_DDR_SIZE (3 * GiB)
116
+#endif
117
+
118
+/*
119
+ * Flag values:
120
+ * IS_MAIN: this is the main machine RAM
121
+ * IS_ROM: this area is read-only
122
+ */
123
+#define IS_MAIN 1
124
+#define IS_ROM 2
125
+
126
+#define MPS3R_RAM_MAX 9
127
+
128
+typedef enum MPS3RFPGAType {
129
+ FPGA_AN536,
130
+} MPS3RFPGAType;
131
+
132
+struct MPS3RMachineClass {
133
+ MachineClass parent;
134
+ MPS3RFPGAType fpga_type;
135
+ const RAMInfo *raminfo;
81
+};
136
+};
82
+
137
+
83
+#endif
138
+struct MPS3RMachineState {
84
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
139
+ MachineState parent;
140
+ MemoryRegion ram[MPS3R_RAM_MAX];
141
+};
142
+
143
+#define TYPE_MPS3R_MACHINE "mps3r"
144
+#define TYPE_MPS3R_AN536_MACHINE MACHINE_TYPE_NAME("mps3-an536")
145
+
146
+OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
147
+
148
+static const RAMInfo an536_raminfo[] = {
149
+ {
150
+ .name = "ATCM",
151
+ .base = 0x00000000,
152
+ .size = 0x00008000,
153
+ .mrindex = 0,
154
+ }, {
155
+ /* We model the QSPI flash as simple ROM for now */
156
+ .name = "QSPI",
157
+ .base = 0x08000000,
158
+ .size = 0x00800000,
159
+ .flags = IS_ROM,
160
+ .mrindex = 1,
161
+ }, {
162
+ .name = "BRAM",
163
+ .base = 0x10000000,
164
+ .size = 0x00080000,
165
+ .mrindex = 2,
166
+ }, {
167
+ .name = "DDR",
168
+ .base = 0x20000000,
169
+ .size = MPS3_DDR_SIZE,
170
+ .mrindex = -1,
171
+ }, {
172
+ .name = "ATCM0",
173
+ .base = 0xee000000,
174
+ .size = 0x00008000,
175
+ .mrindex = 3,
176
+ }, {
177
+ .name = "BTCM0",
178
+ .base = 0xee100000,
179
+ .size = 0x00008000,
180
+ .mrindex = 4,
181
+ }, {
182
+ .name = "CTCM0",
183
+ .base = 0xee200000,
184
+ .size = 0x00008000,
185
+ .mrindex = 5,
186
+ }, {
187
+ .name = "ATCM1",
188
+ .base = 0xee400000,
189
+ .size = 0x00008000,
190
+ .mrindex = 6,
191
+ }, {
192
+ .name = "BTCM1",
193
+ .base = 0xee500000,
194
+ .size = 0x00008000,
195
+ .mrindex = 7,
196
+ }, {
197
+ .name = "CTCM1",
198
+ .base = 0xee600000,
199
+ .size = 0x00008000,
200
+ .mrindex = 8,
201
+ }, {
202
+ .name = NULL,
203
+ }
204
+};
205
+
206
+static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
207
+ const RAMInfo *raminfo)
208
+{
209
+ /* Return an initialized MemoryRegion for the RAMInfo. */
210
+ MemoryRegion *ram;
211
+
212
+ if (raminfo->mrindex < 0) {
213
+ /* Means this RAMInfo is for QEMU's "system memory" */
214
+ MachineState *machine = MACHINE(mms);
215
+ assert(!(raminfo->flags & IS_ROM));
216
+ return machine->ram;
217
+ }
218
+
219
+ assert(raminfo->mrindex < MPS3R_RAM_MAX);
220
+ ram = &mms->ram[raminfo->mrindex];
221
+
222
+ memory_region_init_ram(ram, NULL, raminfo->name,
223
+ raminfo->size, &error_fatal);
224
+ if (raminfo->flags & IS_ROM) {
225
+ memory_region_set_readonly(ram, true);
226
+ }
227
+ return ram;
228
+}
229
+
230
+static void mps3r_common_init(MachineState *machine)
231
+{
232
+ MPS3RMachineState *mms = MPS3R_MACHINE(machine);
233
+ MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
234
+ MemoryRegion *sysmem = get_system_memory();
235
+
236
+ for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
237
+ MemoryRegion *mr = mr_for_raminfo(mms, ri);
238
+ memory_region_add_subregion(sysmem, ri->base, mr);
239
+ }
240
+}
241
+
242
+static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
243
+{
244
+ /*
245
+ * Set mc->default_ram_size and default_ram_id from the
246
+ * information in mmc->raminfo.
247
+ */
248
+ MachineClass *mc = MACHINE_CLASS(mmc);
249
+ const RAMInfo *p;
250
+
251
+ for (p = mmc->raminfo; p->name; p++) {
252
+ if (p->mrindex < 0) {
253
+ /* Found the entry for "system memory" */
254
+ mc->default_ram_size = p->size;
255
+ mc->default_ram_id = p->name;
256
+ return;
257
+ }
258
+ }
259
+ g_assert_not_reached();
260
+}
261
+
262
+static void mps3r_class_init(ObjectClass *oc, void *data)
263
+{
264
+ MachineClass *mc = MACHINE_CLASS(oc);
265
+
266
+ mc->init = mps3r_common_init;
267
+}
268
+
269
+static void mps3r_an536_class_init(ObjectClass *oc, void *data)
270
+{
271
+ MachineClass *mc = MACHINE_CLASS(oc);
272
+ MPS3RMachineClass *mmc = MPS3R_MACHINE_CLASS(oc);
273
+ static const char * const valid_cpu_types[] = {
274
+ ARM_CPU_TYPE_NAME("cortex-r52"),
275
+ NULL
276
+ };
277
+
278
+ mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
279
+ mc->default_cpus = 2;
280
+ mc->min_cpus = mc->default_cpus;
281
+ mc->max_cpus = mc->default_cpus;
282
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
283
+ mc->valid_cpu_types = valid_cpu_types;
284
+ mmc->raminfo = an536_raminfo;
285
+ mps3r_set_default_ram_info(mmc);
286
+}
287
+
288
+static const TypeInfo mps3r_machine_types[] = {
289
+ {
290
+ .name = TYPE_MPS3R_MACHINE,
291
+ .parent = TYPE_MACHINE,
292
+ .abstract = true,
293
+ .instance_size = sizeof(MPS3RMachineState),
294
+ .class_size = sizeof(MPS3RMachineClass),
295
+ .class_init = mps3r_class_init,
296
+ }, {
297
+ .name = TYPE_MPS3R_AN536_MACHINE,
298
+ .parent = TYPE_MPS3R_MACHINE,
299
+ .class_init = mps3r_an536_class_init,
300
+ },
301
+};
302
+
303
+DEFINE_TYPES(mps3r_machine_types);
304
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
85
index XXXXXXX..XXXXXXX 100644
305
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/arm/bcm2835_peripherals.c
306
--- a/hw/arm/Kconfig
87
+++ b/hw/arm/bcm2835_peripherals.c
307
+++ b/hw/arm/Kconfig
88
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_init(Object *obj)
308
@@ -XXX,XX +XXX,XX @@ config MAINSTONE
89
309
select PFLASH_CFI01
90
object_property_add_const_link(OBJECT(&s->dwc2), "dma-mr",
310
select SMC91C111
91
OBJECT(&s->gpu_bus_mr));
311
92
+
312
+config MPS3R
93
+ /* Power Management */
313
+ bool
94
+ object_initialize_child(obj, "powermgt", &s->powermgt,
314
+ default y
95
+ TYPE_BCM2835_POWERMGT);
315
+ depends on TCG && ARM
96
}
316
+
97
317
config MUSCA
98
static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
318
bool
99
@@ -XXX,XX +XXX,XX @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp)
319
default y
100
qdev_get_gpio_in_named(DEVICE(&s->ic), BCM2835_IC_GPU_IRQ,
320
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
101
INTERRUPT_USB));
102
103
+ /* Power Management */
104
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->powermgt), errp)) {
105
+ return;
106
+ }
107
+
108
+ memory_region_add_subregion(&s->peri_mr, PM_OFFSET,
109
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->powermgt), 0));
110
+
111
create_unimp(s, &s->txp, "bcm2835-txp", TXP_OFFSET, 0x1000);
112
create_unimp(s, &s->armtmr, "bcm2835-sp804", ARMCTRL_TIMER0_1_OFFSET, 0x40);
113
- create_unimp(s, &s->powermgt, "bcm2835-powermgt", PM_OFFSET, 0x114);
114
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
115
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
116
create_unimp(s, &s->spi[0], "bcm2835-spi0", SPI0_OFFSET, 0x20);
117
diff --git a/hw/misc/bcm2835_powermgt.c b/hw/misc/bcm2835_powermgt.c
118
new file mode 100644
119
index XXXXXXX..XXXXXXX
120
--- /dev/null
121
+++ b/hw/misc/bcm2835_powermgt.c
122
@@ -XXX,XX +XXX,XX @@
123
+/*
124
+ * BCM2835 Power Management emulation
125
+ *
126
+ * Copyright (C) 2017 Marcin Chojnacki <marcinch7@gmail.com>
127
+ * Copyright (C) 2021 Nolan Leake <nolan@sigbus.net>
128
+ *
129
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
130
+ * See the COPYING file in the top-level directory.
131
+ */
132
+
133
+#include "qemu/osdep.h"
134
+#include "qemu/log.h"
135
+#include "qemu/module.h"
136
+#include "hw/misc/bcm2835_powermgt.h"
137
+#include "migration/vmstate.h"
138
+#include "sysemu/runstate.h"
139
+
140
+#define PASSWORD 0x5a000000
141
+#define PASSWORD_MASK 0xff000000
142
+
143
+#define R_RSTC 0x1c
144
+#define V_RSTC_RESET 0x20
145
+#define R_RSTS 0x20
146
+#define V_RSTS_POWEROFF 0x555 /* Linux uses partition 63 to indicate halt. */
147
+#define R_WDOG 0x24
148
+
149
+static uint64_t bcm2835_powermgt_read(void *opaque, hwaddr offset,
150
+ unsigned size)
151
+{
152
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
153
+ uint32_t res = 0;
154
+
155
+ switch (offset) {
156
+ case R_RSTC:
157
+ res = s->rstc;
158
+ break;
159
+ case R_RSTS:
160
+ res = s->rsts;
161
+ break;
162
+ case R_WDOG:
163
+ res = s->wdog;
164
+ break;
165
+
166
+ default:
167
+ qemu_log_mask(LOG_UNIMP,
168
+ "bcm2835_powermgt_read: Unknown offset 0x%08"HWADDR_PRIx
169
+ "\n", offset);
170
+ res = 0;
171
+ break;
172
+ }
173
+
174
+ return res;
175
+}
176
+
177
+static void bcm2835_powermgt_write(void *opaque, hwaddr offset,
178
+ uint64_t value, unsigned size)
179
+{
180
+ BCM2835PowerMgtState *s = (BCM2835PowerMgtState *)opaque;
181
+
182
+ if ((value & PASSWORD_MASK) != PASSWORD) {
183
+ qemu_log_mask(LOG_GUEST_ERROR,
184
+ "bcm2835_powermgt_write: Bad password 0x%"PRIx64
185
+ " at offset 0x%08"HWADDR_PRIx"\n",
186
+ value, offset);
187
+ return;
188
+ }
189
+
190
+ value = value & ~PASSWORD_MASK;
191
+
192
+ switch (offset) {
193
+ case R_RSTC:
194
+ s->rstc = value;
195
+ if (value & V_RSTC_RESET) {
196
+ if ((s->rsts & 0xfff) == V_RSTS_POWEROFF) {
197
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
198
+ } else {
199
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
200
+ }
201
+ }
202
+ break;
203
+ case R_RSTS:
204
+ qemu_log_mask(LOG_UNIMP,
205
+ "bcm2835_powermgt_write: RSTS\n");
206
+ s->rsts = value;
207
+ break;
208
+ case R_WDOG:
209
+ qemu_log_mask(LOG_UNIMP,
210
+ "bcm2835_powermgt_write: WDOG\n");
211
+ s->wdog = value;
212
+ break;
213
+
214
+ default:
215
+ qemu_log_mask(LOG_UNIMP,
216
+ "bcm2835_powermgt_write: Unknown offset 0x%08"HWADDR_PRIx
217
+ "\n", offset);
218
+ break;
219
+ }
220
+}
221
+
222
+static const MemoryRegionOps bcm2835_powermgt_ops = {
223
+ .read = bcm2835_powermgt_read,
224
+ .write = bcm2835_powermgt_write,
225
+ .endianness = DEVICE_NATIVE_ENDIAN,
226
+ .impl.min_access_size = 4,
227
+ .impl.max_access_size = 4,
228
+};
229
+
230
+static const VMStateDescription vmstate_bcm2835_powermgt = {
231
+ .name = TYPE_BCM2835_POWERMGT,
232
+ .version_id = 1,
233
+ .minimum_version_id = 1,
234
+ .fields = (VMStateField[]) {
235
+ VMSTATE_UINT32(rstc, BCM2835PowerMgtState),
236
+ VMSTATE_UINT32(rsts, BCM2835PowerMgtState),
237
+ VMSTATE_UINT32(wdog, BCM2835PowerMgtState),
238
+ VMSTATE_END_OF_LIST()
239
+ }
240
+};
241
+
242
+static void bcm2835_powermgt_init(Object *obj)
243
+{
244
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(obj);
245
+
246
+ memory_region_init_io(&s->iomem, obj, &bcm2835_powermgt_ops, s,
247
+ TYPE_BCM2835_POWERMGT, 0x200);
248
+ sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
249
+}
250
+
251
+static void bcm2835_powermgt_reset(DeviceState *dev)
252
+{
253
+ BCM2835PowerMgtState *s = BCM2835_POWERMGT(dev);
254
+
255
+ /* https://elinux.org/BCM2835_registers#PM */
256
+ s->rstc = 0x00000102;
257
+ s->rsts = 0x00001000;
258
+ s->wdog = 0x00000000;
259
+}
260
+
261
+static void bcm2835_powermgt_class_init(ObjectClass *klass, void *data)
262
+{
263
+ DeviceClass *dc = DEVICE_CLASS(klass);
264
+
265
+ dc->reset = bcm2835_powermgt_reset;
266
+ dc->vmsd = &vmstate_bcm2835_powermgt;
267
+}
268
+
269
+static TypeInfo bcm2835_powermgt_info = {
270
+ .name = TYPE_BCM2835_POWERMGT,
271
+ .parent = TYPE_SYS_BUS_DEVICE,
272
+ .instance_size = sizeof(BCM2835PowerMgtState),
273
+ .class_init = bcm2835_powermgt_class_init,
274
+ .instance_init = bcm2835_powermgt_init,
275
+};
276
+
277
+static void bcm2835_powermgt_register_types(void)
278
+{
279
+ type_register_static(&bcm2835_powermgt_info);
280
+}
281
+
282
+type_init(bcm2835_powermgt_register_types)
283
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
284
index XXXXXXX..XXXXXXX 100644
321
index XXXXXXX..XXXXXXX 100644
285
--- a/hw/misc/meson.build
322
--- a/hw/arm/meson.build
286
+++ b/hw/misc/meson.build
323
+++ b/hw/arm/meson.build
287
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
324
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_HIGHBANK', if_true: files('highbank.c'))
288
'bcm2835_rng.c',
325
arm_ss.add(when: 'CONFIG_INTEGRATOR', if_true: files('integratorcp.c'))
289
'bcm2835_thermal.c',
326
arm_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mainstone.c'))
290
'bcm2835_cprman.c',
327
arm_ss.add(when: 'CONFIG_MICROBIT', if_true: files('microbit.c'))
291
+ 'bcm2835_powermgt.c',
328
+arm_ss.add(when: 'CONFIG_MPS3R', if_true: files('mps3r.c'))
292
))
329
arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
293
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
330
arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c'))
294
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 'zynq-xadc.c'))
331
arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c'))
295
--
332
--
296
2.20.1
333
2.34.1
297
334
298
335
diff view generated by jsdifflib
1
Implement the MVE saturating shift-right-and-narrow insns
1
Create the CPUs, the GIC, and the per-CPU RAM block for
2
VQSHRN, VQSHRUN, VQRSHRN and VQRSHRUN.
2
the mps3-an536 board.
3
4
do_srshr() is borrowed from sve_helper.c.
5
3
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20240206132931.38376-10-peter.maydell@linaro.org
8
Message-id: 20210628135835.6690-13-peter.maydell@linaro.org
9
---
6
---
10
target/arm/helper-mve.h | 30 +++++++++++
7
hw/arm/mps3r.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++++-
11
target/arm/mve.decode | 28 ++++++++++
8
1 file changed, 177 insertions(+), 3 deletions(-)
12
target/arm/mve_helper.c | 104 +++++++++++++++++++++++++++++++++++++
13
target/arm/translate-mve.c | 12 +++++
14
4 files changed, 174 insertions(+)
15
9
16
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
10
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
17
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-mve.h
12
--- a/hw/arm/mps3r.c
19
+++ b/target/arm/helper-mve.h
13
+++ b/hw/arm/mps3r.c
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vrshrnbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
14
@@ -XXX,XX +XXX,XX @@
21
DEF_HELPER_FLAGS_4(mve_vrshrnbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
15
#include "qemu/osdep.h"
22
DEF_HELPER_FLAGS_4(mve_vrshrntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
16
#include "qemu/units.h"
23
DEF_HELPER_FLAGS_4(mve_vrshrnth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
17
#include "qapi/error.h"
24
+
18
+#include "qapi/qmp/qlist.h"
25
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
19
#include "exec/address-spaces.h"
26
+DEF_HELPER_FLAGS_4(mve_vqshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
20
#include "cpu.h"
27
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
21
#include "hw/boards.h"
28
+DEF_HELPER_FLAGS_4(mve_vqshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
22
+#include "hw/qdev-properties.h"
29
+
23
#include "hw/arm/boot.h"
30
+DEF_HELPER_FLAGS_4(mve_vqshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
24
+#include "hw/arm/bsa.h"
31
+DEF_HELPER_FLAGS_4(mve_vqshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
25
+#include "hw/intc/arm_gicv3.h"
32
+DEF_HELPER_FLAGS_4(mve_vqshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
26
33
+DEF_HELPER_FLAGS_4(mve_vqshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
27
/* Define the layout of RAM and ROM in a board */
34
+
28
typedef struct RAMInfo {
35
+DEF_HELPER_FLAGS_4(mve_vqshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
29
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
36
+DEF_HELPER_FLAGS_4(mve_vqshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
#define IS_ROM 2
37
+DEF_HELPER_FLAGS_4(mve_vqshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
38
+DEF_HELPER_FLAGS_4(mve_vqshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
#define MPS3R_RAM_MAX 9
39
+
33
+#define MPS3R_CPU_MAX 2
40
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
34
+
41
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
35
+#define PERIPHBASE 0xf0000000
42
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
+#define NUM_SPIS 96
43
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
44
+
38
typedef enum MPS3RFPGAType {
45
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
FPGA_AN536,
46
+DEF_HELPER_FLAGS_4(mve_vqrshrnb_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineClass {
47
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
MachineClass parent;
48
+DEF_HELPER_FLAGS_4(mve_vqrshrnt_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
42
MPS3RFPGAType fpga_type;
49
+
43
const RAMInfo *raminfo;
50
+DEF_HELPER_FLAGS_4(mve_vqrshrunbb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
44
+ hwaddr loader_start;
51
+DEF_HELPER_FLAGS_4(mve_vqrshrunbh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
45
};
52
+DEF_HELPER_FLAGS_4(mve_vqrshruntb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
46
53
+DEF_HELPER_FLAGS_4(mve_vqrshrunth, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
47
struct MPS3RMachineState {
54
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
48
MachineState parent;
55
index XXXXXXX..XXXXXXX 100644
49
+ struct arm_boot_info bootinfo;
56
--- a/target/arm/mve.decode
50
MemoryRegion ram[MPS3R_RAM_MAX];
57
+++ b/target/arm/mve.decode
51
+ Object *cpu[MPS3R_CPU_MAX];
58
@@ -XXX,XX +XXX,XX @@ VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_b
52
+ MemoryRegion cpu_sysmem[MPS3R_CPU_MAX];
59
VRSHRNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 1 @2_shr_h
53
+ MemoryRegion sysmem_alias[MPS3R_CPU_MAX];
60
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_b
54
+ MemoryRegion cpu_ram[MPS3R_CPU_MAX];
61
VRSHRNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 1 @2_shr_h
55
+ GICv3State gic;
62
+
56
};
63
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
57
64
+VQSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
58
#define TYPE_MPS3R_MACHINE "mps3r"
65
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
59
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
66
+VQSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
60
return ram;
67
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_b
68
+VQSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 0 @2_shr_h
69
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_b
70
+VQSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 0 @2_shr_h
71
+
72
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
73
+VQSHRUNB 111 0 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
74
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
75
+VQSHRUNT 111 0 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
76
+
77
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
78
+VQRSHRNB_S 111 0 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
79
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
80
+VQRSHRNT_S 111 0 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
81
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_b
82
+VQRSHRNB_U 111 1 1110 1 . ... ... ... 0 1111 0 1 . 0 ... 1 @2_shr_h
83
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_b
84
+VQRSHRNT_U 111 1 1110 1 . ... ... ... 1 1111 0 1 . 0 ... 1 @2_shr_h
85
+
86
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_b
87
+VQRSHRUNB 111 1 1110 1 . ... ... ... 0 1111 1 1 . 0 ... 0 @2_shr_h
88
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_b
89
+VQRSHRUNT 111 1 1110 1 . ... ... ... 1 1111 1 1 . 0 ... 0 @2_shr_h
90
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/mve_helper.c
93
+++ b/target/arm/mve_helper.c
94
@@ -XXX,XX +XXX,XX @@ static inline uint64_t do_urshr(uint64_t x, unsigned sh)
95
}
96
}
61
}
97
62
98
+static inline int64_t do_srshr(int64_t x, unsigned sh)
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)
99
+{
78
+{
100
+ if (likely(sh < 64)) {
79
+ /*
101
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
80
+ * Power the secondary CPU off. This means we don't need to write any
102
+ } else {
81
+ * boot code into guest memory. Note that the 'cpu' argument to this
103
+ /* Rounding the sign bit always produces 0. */
82
+ * function is the primary CPU we passed to arm_load_kernel(), not
104
+ return 0;
83
+ * the secondary. Loop around all the other CPUs, as the boot.c
84
+ * code does for the "disable secondaries if PSCI is enabled" case.
85
+ */
86
+ for (CPUState *cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
87
+ if (cs != first_cpu) {
88
+ object_property_set_bool(OBJECT(cs), "start-powered-off", true,
89
+ &error_abort);
90
+ }
105
+ }
91
+ }
106
+}
92
+}
107
+
93
+
108
DO_VSHRN_ALL(vshrn, DO_SHR)
94
+static void mps3r_secondary_cpu_reset(ARMCPU *cpu,
109
DO_VSHRN_ALL(vrshrn, do_urshr)
95
+ const struct arm_boot_info *info)
110
+
111
+static inline int32_t do_sat_bhs(int64_t val, int64_t min, int64_t max,
112
+ bool *satp)
113
+{
96
+{
114
+ if (val > max) {
97
+ /* We don't need to do anything here because the CPU will be off */
115
+ *satp = true;
98
+}
116
+ return max;
99
+
117
+ } else if (val < min) {
100
+static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
118
+ *satp = true;
101
+{
119
+ return min;
102
+ MachineState *machine = MACHINE(mms);
120
+ } else {
103
+ DeviceState *gicdev;
121
+ return val;
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));
122
+ }
161
+ }
123
+}
162
+}
124
+
163
+
125
+/* Saturating narrowing right shifts */
164
static void mps3r_common_init(MachineState *machine)
126
+#define DO_VSHRN_SAT(OP, TOP, ESIZE, TYPE, LESIZE, LTYPE, FN) \
165
{
127
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
166
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
128
+ void *vm, uint32_t shift) \
167
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
129
+ { \
168
MemoryRegion *mr = mr_for_raminfo(mms, ri);
130
+ LTYPE *m = vm; \
169
memory_region_add_subregion(sysmem, ri->base, mr);
131
+ TYPE *d = vd; \
170
}
132
+ uint16_t mask = mve_element_mask(env); \
171
+
133
+ bool qc = false; \
172
+ assert(machine->smp.cpus <= MPS3R_CPU_MAX);
134
+ unsigned le; \
173
+ for (int i = 0; i < machine->smp.cpus; i++) {
135
+ for (le = 0; le < 16 / LESIZE; le++, mask >>= LESIZE) { \
174
+ g_autofree char *sysmem_name = g_strdup_printf("cpu-%d-memory", i);
136
+ bool sat = false; \
175
+ g_autofree char *ramname = g_strdup_printf("cpu-%d-memory", i);
137
+ TYPE r = FN(m[H##LESIZE(le)], shift, &sat); \
176
+ g_autofree char *alias_name = g_strdup_printf("sysmem-alias-%d", i);
138
+ mergemask(&d[H##ESIZE(le * 2 + TOP)], r, mask); \
177
+
139
+ qc |= sat && (mask & 1 << (TOP * ESIZE)); \
178
+ /*
140
+ } \
179
+ * Each CPU has some private RAM/peripherals, so create the container
141
+ if (qc) { \
180
+ * which will house those, with the whole-machine system memory being
142
+ env->vfp.qc[0] = qc; \
181
+ * used where there's no CPU-specific device. Note that we need the
143
+ } \
182
+ * sysmem_alias aliases because we can't put one MR (the original
144
+ mve_advance_vpt(env); \
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]);
145
+ }
205
+ }
146
+
206
+
147
+#define DO_VSHRN_SAT_UB(BOP, TOP, FN) \
207
+ create_gic(mms, sysmem);
148
+ DO_VSHRN_SAT(BOP, false, 1, uint8_t, 2, uint16_t, FN) \
208
+
149
+ DO_VSHRN_SAT(TOP, true, 1, uint8_t, 2, uint16_t, FN)
209
+ mms->bootinfo.ram_size = machine->ram_size;
150
+
210
+ mms->bootinfo.board_id = -1;
151
+#define DO_VSHRN_SAT_UH(BOP, TOP, FN) \
211
+ mms->bootinfo.loader_start = mmc->loader_start;
152
+ DO_VSHRN_SAT(BOP, false, 2, uint16_t, 4, uint32_t, FN) \
212
+ mms->bootinfo.write_secondary_boot = mps3r_write_secondary_boot;
153
+ DO_VSHRN_SAT(TOP, true, 2, uint16_t, 4, uint32_t, FN)
213
+ mms->bootinfo.secondary_cpu_reset_hook = mps3r_secondary_cpu_reset;
154
+
214
+ arm_load_kernel(ARM_CPU(mms->cpu[0]), machine, &mms->bootinfo);
155
+#define DO_VSHRN_SAT_SB(BOP, TOP, FN) \
215
}
156
+ DO_VSHRN_SAT(BOP, false, 1, int8_t, 2, int16_t, FN) \
216
157
+ DO_VSHRN_SAT(TOP, true, 1, int8_t, 2, int16_t, FN)
217
static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
158
+
218
@@ -XXX,XX +XXX,XX @@ static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
159
+#define DO_VSHRN_SAT_SH(BOP, TOP, FN) \
219
/* Found the entry for "system memory" */
160
+ DO_VSHRN_SAT(BOP, false, 2, int16_t, 4, int32_t, FN) \
220
mc->default_ram_size = p->size;
161
+ DO_VSHRN_SAT(TOP, true, 2, int16_t, 4, int32_t, FN)
221
mc->default_ram_id = p->name;
162
+
222
+ mmc->loader_start = p->base;
163
+#define DO_SHRN_SB(N, M, SATP) \
223
return;
164
+ do_sat_bhs((int64_t)(N) >> (M), INT8_MIN, INT8_MAX, SATP)
224
}
165
+#define DO_SHRN_UB(N, M, SATP) \
225
}
166
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT8_MAX, SATP)
226
@@ -XXX,XX +XXX,XX @@ static void mps3r_an536_class_init(ObjectClass *oc, void *data)
167
+#define DO_SHRUN_B(N, M, SATP) \
227
};
168
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT8_MAX, SATP)
228
169
+
229
mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
170
+#define DO_SHRN_SH(N, M, SATP) \
230
- mc->default_cpus = 2;
171
+ do_sat_bhs((int64_t)(N) >> (M), INT16_MIN, INT16_MAX, SATP)
231
- mc->min_cpus = mc->default_cpus;
172
+#define DO_SHRN_UH(N, M, SATP) \
232
- mc->max_cpus = mc->default_cpus;
173
+ do_sat_bhs((uint64_t)(N) >> (M), 0, UINT16_MAX, SATP)
233
+ /*
174
+#define DO_SHRUN_H(N, M, SATP) \
234
+ * In the real FPGA image there are always two cores, but the standard
175
+ do_sat_bhs((int64_t)(N) >> (M), 0, UINT16_MAX, SATP)
235
+ * initial setting for the SCC SYSCON 0x000 register is 0x21, meaning
176
+
236
+ * that the second core is held in reset and halted. Many images built for
177
+#define DO_RSHRN_SB(N, M, SATP) \
237
+ * the board do not expect the second core to run at startup (especially
178
+ do_sat_bhs(do_srshr(N, M), INT8_MIN, INT8_MAX, SATP)
238
+ * since on the real FPGA image it is not possible to use LDREX/STREX
179
+#define DO_RSHRN_UB(N, M, SATP) \
239
+ * in RAM between the two cores, so a true SMP setup isn't supported).
180
+ do_sat_bhs(do_urshr(N, M), 0, UINT8_MAX, SATP)
240
+ *
181
+#define DO_RSHRUN_B(N, M, SATP) \
241
+ * As QEMU's equivalent of this, we support both -smp 1 and -smp 2,
182
+ do_sat_bhs(do_srshr(N, M), 0, UINT8_MAX, SATP)
242
+ * with the default being -smp 1. This seems a more intuitive UI for
183
+
243
+ * QEMU users than, for instance, having a machine property to allow
184
+#define DO_RSHRN_SH(N, M, SATP) \
244
+ * the user to set the initial value of the SYSCON 0x000 register.
185
+ do_sat_bhs(do_srshr(N, M), INT16_MIN, INT16_MAX, SATP)
245
+ */
186
+#define DO_RSHRN_UH(N, M, SATP) \
246
+ mc->default_cpus = 1;
187
+ do_sat_bhs(do_urshr(N, M), 0, UINT16_MAX, SATP)
247
+ mc->min_cpus = 1;
188
+#define DO_RSHRUN_H(N, M, SATP) \
248
+ mc->max_cpus = 2;
189
+ do_sat_bhs(do_srshr(N, M), 0, UINT16_MAX, SATP)
249
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
190
+
250
mc->valid_cpu_types = valid_cpu_types;
191
+DO_VSHRN_SAT_SB(vqshrnb_sb, vqshrnt_sb, DO_SHRN_SB)
251
mmc->raminfo = an536_raminfo;
192
+DO_VSHRN_SAT_SH(vqshrnb_sh, vqshrnt_sh, DO_SHRN_SH)
193
+DO_VSHRN_SAT_UB(vqshrnb_ub, vqshrnt_ub, DO_SHRN_UB)
194
+DO_VSHRN_SAT_UH(vqshrnb_uh, vqshrnt_uh, DO_SHRN_UH)
195
+DO_VSHRN_SAT_SB(vqshrunbb, vqshruntb, DO_SHRUN_B)
196
+DO_VSHRN_SAT_SH(vqshrunbh, vqshrunth, DO_SHRUN_H)
197
+
198
+DO_VSHRN_SAT_SB(vqrshrnb_sb, vqrshrnt_sb, DO_RSHRN_SB)
199
+DO_VSHRN_SAT_SH(vqrshrnb_sh, vqrshrnt_sh, DO_RSHRN_SH)
200
+DO_VSHRN_SAT_UB(vqrshrnb_ub, vqrshrnt_ub, DO_RSHRN_UB)
201
+DO_VSHRN_SAT_UH(vqrshrnb_uh, vqrshrnt_uh, DO_RSHRN_UH)
202
+DO_VSHRN_SAT_SB(vqrshrunbb, vqrshruntb, DO_RSHRUN_B)
203
+DO_VSHRN_SAT_SH(vqrshrunbh, vqrshrunth, DO_RSHRUN_H)
204
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
205
index XXXXXXX..XXXXXXX 100644
206
--- a/target/arm/translate-mve.c
207
+++ b/target/arm/translate-mve.c
208
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_N(VSHRNB, vshrnb)
209
DO_2SHIFT_N(VSHRNT, vshrnt)
210
DO_2SHIFT_N(VRSHRNB, vrshrnb)
211
DO_2SHIFT_N(VRSHRNT, vrshrnt)
212
+DO_2SHIFT_N(VQSHRNB_S, vqshrnb_s)
213
+DO_2SHIFT_N(VQSHRNT_S, vqshrnt_s)
214
+DO_2SHIFT_N(VQSHRNB_U, vqshrnb_u)
215
+DO_2SHIFT_N(VQSHRNT_U, vqshrnt_u)
216
+DO_2SHIFT_N(VQSHRUNB, vqshrunb)
217
+DO_2SHIFT_N(VQSHRUNT, vqshrunt)
218
+DO_2SHIFT_N(VQRSHRNB_S, vqrshrnb_s)
219
+DO_2SHIFT_N(VQRSHRNT_S, vqrshrnt_s)
220
+DO_2SHIFT_N(VQRSHRNB_U, vqrshrnb_u)
221
+DO_2SHIFT_N(VQRSHRNT_U, vqrshrnt_u)
222
+DO_2SHIFT_N(VQRSHRUNB, vqrshrunb)
223
+DO_2SHIFT_N(VQRSHRUNT, vqrshrunt)
224
--
252
--
225
2.20.1
253
2.34.1
226
227
diff view generated by jsdifflib
1
In do_ldst(), the calculation of the offset needs to be based on the
1
This board has a lot of UARTs: there is one UART per CPU in the
2
size of the memory access, not the size of the elements in the
2
per-CPU peripheral part of the address map, whose interrupts are
3
vector. This meant we were getting it wrong for the widening and
3
connected as per-CPU interrupt lines. Then there are 4 UARTs in the
4
narrowing variants of the various VLDR and VSTR insns.
4
normal part of the peripheral space, whose interrupts are shared
5
peripheral interrupts.
6
7
Connect and wire them all up; this involves some OR gates where
8
multiple overflow interrupts are wired into one GIC input.
5
9
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20210628135835.6690-2-peter.maydell@linaro.org
12
Message-id: 20240206132931.38376-11-peter.maydell@linaro.org
9
---
13
---
10
target/arm/translate-mve.c | 17 +++++++++--------
14
hw/arm/mps3r.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++
11
1 file changed, 9 insertions(+), 8 deletions(-)
15
1 file changed, 94 insertions(+)
12
16
13
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
17
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-mve.c
19
--- a/hw/arm/mps3r.c
16
+++ b/target/arm/translate-mve.c
20
+++ b/hw/arm/mps3r.c
17
@@ -XXX,XX +XXX,XX @@ static bool mve_skip_first_beat(DisasContext *s)
21
@@ -XXX,XX +XXX,XX @@
22
#include "qapi/qmp/qlist.h"
23
#include "exec/address-spaces.h"
24
#include "cpu.h"
25
+#include "sysemu/sysemu.h"
26
#include "hw/boards.h"
27
+#include "hw/or-irq.h"
28
#include "hw/qdev-properties.h"
29
#include "hw/arm/boot.h"
30
#include "hw/arm/bsa.h"
31
+#include "hw/char/cmsdk-apb-uart.h"
32
#include "hw/intc/arm_gicv3.h"
33
34
/* Define the layout of RAM and ROM in a board */
35
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
36
37
#define MPS3R_RAM_MAX 9
38
#define MPS3R_CPU_MAX 2
39
+#define MPS3R_UART_MAX 4 /* shared UART count */
40
41
#define PERIPHBASE 0xf0000000
42
#define NUM_SPIS 96
43
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
44
MemoryRegion sysmem_alias[MPS3R_CPU_MAX];
45
MemoryRegion cpu_ram[MPS3R_CPU_MAX];
46
GICv3State gic;
47
+ /* per-CPU UARTs followed by the shared UARTs */
48
+ CMSDKAPBUART uart[MPS3R_CPU_MAX + MPS3R_UART_MAX];
49
+ OrIRQState cpu_uart_oflow[MPS3R_CPU_MAX];
50
+ OrIRQState uart_oflow;
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
64
+
65
static const RAMInfo an536_raminfo[] = {
66
{
67
.name = "ATCM",
68
@@ -XXX,XX +XXX,XX @@ static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
18
}
69
}
19
}
70
}
20
71
21
-static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
72
+/*
22
+static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn,
73
+ * Create UART uartno, and map it into the MemoryRegion mem at address baseaddr.
23
+ unsigned msize)
74
+ * The qemu_irq arguments are where we connect the various IRQs from the UART.
75
+ */
76
+static void create_uart(MPS3RMachineState *mms, int uartno, MemoryRegion *mem,
77
+ hwaddr baseaddr, qemu_irq txirq, qemu_irq rxirq,
78
+ qemu_irq txoverirq, qemu_irq rxoverirq,
79
+ qemu_irq combirq)
80
+{
81
+ g_autofree char *s = g_strdup_printf("uart%d", uartno);
82
+ SysBusDevice *sbd;
83
+
84
+ assert(uartno < ARRAY_SIZE(mms->uart));
85
+ object_initialize_child(OBJECT(mms), s, &mms->uart[uartno],
86
+ TYPE_CMSDK_APB_UART);
87
+ qdev_prop_set_uint32(DEVICE(&mms->uart[uartno]), "pclk-frq", CLK_FRQ);
88
+ qdev_prop_set_chr(DEVICE(&mms->uart[uartno]), "chardev", serial_hd(uartno));
89
+ sbd = SYS_BUS_DEVICE(&mms->uart[uartno]);
90
+ sysbus_realize(sbd, &error_fatal);
91
+ memory_region_add_subregion(mem, baseaddr,
92
+ sysbus_mmio_get_region(sbd, 0));
93
+ sysbus_connect_irq(sbd, 0, txirq);
94
+ sysbus_connect_irq(sbd, 1, rxirq);
95
+ sysbus_connect_irq(sbd, 2, txoverirq);
96
+ sysbus_connect_irq(sbd, 3, rxoverirq);
97
+ sysbus_connect_irq(sbd, 4, combirq);
98
+}
99
+
100
static void mps3r_common_init(MachineState *machine)
24
{
101
{
25
TCGv_i32 addr;
102
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
26
uint32_t offset;
103
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
27
@@ -XXX,XX +XXX,XX @@ static bool do_ldst(DisasContext *s, arg_VLDR_VSTR *a, MVEGenLdStFn *fn)
104
MemoryRegion *sysmem = get_system_memory();
28
return true;
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)
29
}
110
}
30
111
31
- offset = a->imm << a->size;
112
create_gic(mms, sysmem);
32
+ offset = a->imm << msize;
113
+ gicdev = DEVICE(&mms->gic);
33
if (!a->a) {
114
+
34
offset = -offset;
115
+ /*
35
}
116
+ * UARTs 0 and 1 are per-CPU; their interrupts are wired to
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR(DisasContext *s, arg_VLDR_VSTR *a)
117
+ * the relevant CPU's PPI 0..3, aka INTID 16..19
37
{ gen_helper_mve_vstrw, gen_helper_mve_vldrw },
118
+ */
38
{ NULL, NULL }
119
+ for (int i = 0; i < machine->smp.cpus; i++) {
39
};
120
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
40
- return do_ldst(s, a, ldstfns[a->size][a->l]);
121
+ g_autofree char *s = g_strdup_printf("cpu-uart-oflow-orgate%d", i);
41
+ return do_ldst(s, a, ldstfns[a->size][a->l], a->size);
122
+ DeviceState *orgate;
42
}
123
+
43
124
+ /* The two overflow IRQs from the UART are ORed together into PPI 3 */
44
-#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST) \
125
+ object_initialize_child(OBJECT(mms), s, &mms->cpu_uart_oflow[i],
45
+#define DO_VLDST_WIDE_NARROW(OP, SLD, ULD, ST, MSIZE) \
126
+ TYPE_OR_IRQ);
46
static bool trans_##OP(DisasContext *s, arg_VLDR_VSTR *a) \
127
+ orgate = DEVICE(&mms->cpu_uart_oflow[i]);
47
{ \
128
+ qdev_prop_set_uint32(orgate, "num-lines", 2);
48
static MVEGenLdStFn * const ldstfns[2][2] = { \
129
+ qdev_realize(orgate, NULL, &error_fatal);
49
{ gen_helper_mve_##ST, gen_helper_mve_##SLD }, \
130
+ qdev_connect_gpio_out(orgate, 0,
50
{ NULL, gen_helper_mve_##ULD }, \
131
+ qdev_get_gpio_in(gicdev, intidbase + 19));
51
}; \
132
+
52
- return do_ldst(s, a, ldstfns[a->u][a->l]); \
133
+ create_uart(mms, i, &mms->cpu_sysmem[i], 0xe7c00000,
53
+ return do_ldst(s, a, ldstfns[a->u][a->l], MSIZE); \
134
+ qdev_get_gpio_in(gicdev, intidbase + 17), /* tx */
54
}
135
+ qdev_get_gpio_in(gicdev, intidbase + 16), /* rx */
55
136
+ qdev_get_gpio_in(orgate, 0), /* txover */
56
-DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h)
137
+ qdev_get_gpio_in(orgate, 1), /* rxover */
57
-DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w)
138
+ qdev_get_gpio_in(gicdev, intidbase + 18) /* combined */);
58
-DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w)
139
+ }
59
+DO_VLDST_WIDE_NARROW(VLDSTB_H, vldrb_sh, vldrb_uh, vstrb_h, MO_8)
140
+ /*
60
+DO_VLDST_WIDE_NARROW(VLDSTB_W, vldrb_sw, vldrb_uw, vstrb_w, MO_8)
141
+ * UARTs 2 to 5 are whole-system; all overflow IRQs are ORed
61
+DO_VLDST_WIDE_NARROW(VLDSTH_W, vldrh_sw, vldrh_uw, vstrh_w, MO_16)
142
+ * together into IRQ 17
62
143
+ */
63
static bool trans_VDUP(DisasContext *s, arg_VDUP *a)
144
+ object_initialize_child(OBJECT(mms), "uart-oflow-orgate",
64
{
145
+ &mms->uart_oflow, TYPE_OR_IRQ);
146
+ qdev_prop_set_uint32(DEVICE(&mms->uart_oflow), "num-lines",
147
+ MPS3R_UART_MAX * 2);
148
+ qdev_realize(DEVICE(&mms->uart_oflow), NULL, &error_fatal);
149
+ qdev_connect_gpio_out(DEVICE(&mms->uart_oflow), 0,
150
+ qdev_get_gpio_in(gicdev, 17));
151
+
152
+ for (int i = 0; i < MPS3R_UART_MAX; i++) {
153
+ hwaddr baseaddr = 0xe0205000 + i * 0x1000;
154
+ int rxirq = 5 + i * 2, txirq = 6 + i * 2, combirq = 13 + i;
155
+
156
+ create_uart(mms, i + MPS3R_CPU_MAX, sysmem, baseaddr,
157
+ qdev_get_gpio_in(gicdev, txirq),
158
+ qdev_get_gpio_in(gicdev, rxirq),
159
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2),
160
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2 + 1),
161
+ qdev_get_gpio_in(gicdev, combirq));
162
+ }
163
164
mms->bootinfo.ram_size = machine->ram_size;
165
mms->bootinfo.board_id = -1;
65
--
166
--
66
2.20.1
167
2.34.1
67
168
68
169
diff view generated by jsdifflib
1
Implement the MVE shifts by register, which perform
1
Add the GPIO, watchdog, dual-timer and I2C devices to the mps3-an536
2
shifts on a single general-purpose register.
2
board. These are all simple devices that just need to be created and
3
wired up.
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20210628135835.6690-19-peter.maydell@linaro.org
7
Message-id: 20240206132931.38376-12-peter.maydell@linaro.org
7
---
8
---
8
target/arm/helper-mve.h | 2 ++
9
hw/arm/mps3r.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
9
target/arm/translate.h | 1 +
10
1 file changed, 59 insertions(+)
10
target/arm/t32.decode | 18 ++++++++++++++----
11
target/arm/mve_helper.c | 10 ++++++++++
12
target/arm/translate.c | 30 ++++++++++++++++++++++++++++++
13
5 files changed, 57 insertions(+), 4 deletions(-)
14
11
15
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-mve.h
14
--- a/hw/arm/mps3r.c
18
+++ b/target/arm/helper-mve.h
15
+++ b/hw/arm/mps3r.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_uqrshll48, TCG_CALL_NO_RWG, i64, env, i64, i32)
20
21
DEF_HELPER_FLAGS_3(mve_uqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
22
DEF_HELPER_FLAGS_3(mve_sqshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
23
+DEF_HELPER_FLAGS_3(mve_uqrshl, TCG_CALL_NO_RWG, i32, env, i32, i32)
24
+DEF_HELPER_FLAGS_3(mve_sqrshr, TCG_CALL_NO_RWG, i32, env, i32, i32)
25
diff --git a/target/arm/translate.h b/target/arm/translate.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/translate.h
28
+++ b/target/arm/translate.h
29
@@ -XXX,XX +XXX,XX @@ typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
30
typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
31
typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
32
typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
33
+typedef void ShiftFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
34
35
/**
36
* arm_tbflags_from_tb:
37
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/t32.decode
40
+++ b/target/arm/t32.decode
41
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
42
&mve_shl_ri rdalo rdahi shim
17
#include "sysemu/sysemu.h"
43
&mve_shl_rr rdalo rdahi rm
18
#include "hw/boards.h"
44
&mve_sh_ri rda shim
19
#include "hw/or-irq.h"
45
+&mve_sh_rr rda rm
20
+#include "hw/qdev-clock.h"
46
21
#include "hw/qdev-properties.h"
47
# rdahi: bits [3:1] from insn, bit 0 is 1
22
#include "hw/arm/boot.h"
48
# rdalo: bits [3:1] from insn, bit 0 is 0
23
#include "hw/arm/bsa.h"
49
@@ -XXX,XX +XXX,XX @@
24
#include "hw/char/cmsdk-apb-uart.h"
50
&mve_shl_rr rdalo=%rdalo_17 rdahi=%rdahi_9
25
+#include "hw/i2c/arm_sbcon_i2c.h"
51
@mve_sh_ri ....... .... . rda:4 . ... ... . .. .. .... \
26
#include "hw/intc/arm_gicv3.h"
52
&mve_sh_ri shim=%imm5_12_6
27
+#include "hw/misc/unimp.h"
53
+@mve_sh_rr ....... .... . rda:4 rm:4 .... .... .... &mve_sh_rr
28
+#include "hw/timer/cmsdk-apb-dualtimer.h"
54
29
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
55
{
30
56
TST_xrri 1110101 0000 1 .... 0 ... 1111 .... .... @S_xrr_shi
31
/* Define the layout of RAM and ROM in a board */
57
@@ -XXX,XX +XXX,XX @@ BIC_rrri 1110101 0001 . .... 0 ... .... .... .... @s_rrr_shi
32
typedef struct RAMInfo {
58
SQSHLL_ri 1110101 0010 1 ... 1 0 ... ... 1 .. 11 1111 @mve_shl_ri
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));
59
}
56
}
60
57
61
- LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
58
+ for (int i = 0; i < 4; i++) {
62
- ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
59
+ /* CMSDK GPIO controllers */
63
- UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
60
+ g_autofree char *s = g_strdup_printf("gpio%d", i);
64
- SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
61
+ create_unimplemented_device(s, 0xe0000000 + i * 0x1000, 0x1000);
65
+ {
66
+ UQRSHL_rr 1110101 0010 1 .... .... 1111 0000 1101 @mve_sh_rr
67
+ LSLL_rr 1110101 0010 1 ... 0 .... ... 1 0000 1101 @mve_shl_rr
68
+ UQRSHLL64_rr 1110101 0010 1 ... 1 .... ... 1 0000 1101 @mve_shl_rr
69
+ }
62
+ }
70
+
63
+
71
+ {
64
+ object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
72
+ SQRSHR_rr 1110101 0010 1 .... .... 1111 0010 1101 @mve_sh_rr
65
+ TYPE_CMSDK_APB_WATCHDOG);
73
+ ASRL_rr 1110101 0010 1 ... 0 .... ... 1 0010 1101 @mve_shl_rr
66
+ qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->clk);
74
+ SQRSHRL64_rr 1110101 0010 1 ... 1 .... ... 1 0010 1101 @mve_shl_rr
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
+ }
75
+ }
103
+ }
76
+
104
+
77
UQRSHLL48_rr 1110101 0010 1 ... 1 .... ... 1 1000 1101 @mve_shl_rr
105
mms->bootinfo.ram_size = machine->ram_size;
78
SQRSHRL48_rr 1110101 0010 1 ... 1 .... ... 1 1010 1101 @mve_shl_rr
106
mms->bootinfo.board_id = -1;
79
]
107
mms->bootinfo.loader_start = mmc->loader_start;
80
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/mve_helper.c
83
+++ b/target/arm/mve_helper.c
84
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mve_sqshl)(CPUARMState *env, uint32_t n, uint32_t shift)
85
{
86
return do_sqrshl_bhs(n, (int8_t)shift, 32, false, &env->QF);
87
}
88
+
89
+uint32_t HELPER(mve_uqrshl)(CPUARMState *env, uint32_t n, uint32_t shift)
90
+{
91
+ return do_uqrshl_bhs(n, (int8_t)shift, 32, true, &env->QF);
92
+}
93
+
94
+uint32_t HELPER(mve_sqrshr)(CPUARMState *env, uint32_t n, uint32_t shift)
95
+{
96
+ return do_sqrshl_bhs(n, -(int8_t)shift, 32, true, &env->QF);
97
+}
98
diff --git a/target/arm/translate.c b/target/arm/translate.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/translate.c
101
+++ b/target/arm/translate.c
102
@@ -XXX,XX +XXX,XX @@ static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
103
return do_mve_sh_ri(s, a, gen_mve_uqshl);
104
}
105
106
+static bool do_mve_sh_rr(DisasContext *s, arg_mve_sh_rr *a, ShiftFn *fn)
107
+{
108
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
109
+ /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
110
+ return false;
111
+ }
112
+ if (!dc_isar_feature(aa32_mve, s) ||
113
+ !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
114
+ a->rda == 13 || a->rda == 15 || a->rm == 13 || a->rm == 15 ||
115
+ a->rm == a->rda) {
116
+ /* These rda/rm cases are UNPREDICTABLE; we choose to UNDEF */
117
+ unallocated_encoding(s);
118
+ return true;
119
+ }
120
+
121
+ /* The helper takes care of the sign-extension of the low 8 bits of Rm */
122
+ fn(cpu_R[a->rda], cpu_env, cpu_R[a->rda], cpu_R[a->rm]);
123
+ return true;
124
+}
125
+
126
+static bool trans_SQRSHR_rr(DisasContext *s, arg_mve_sh_rr *a)
127
+{
128
+ return do_mve_sh_rr(s, a, gen_helper_mve_sqrshr);
129
+}
130
+
131
+static bool trans_UQRSHL_rr(DisasContext *s, arg_mve_sh_rr *a)
132
+{
133
+ return do_mve_sh_rr(s, a, gen_helper_mve_uqrshl);
134
+}
135
+
136
/*
137
* Multiply and multiply accumulate
138
*/
139
--
108
--
140
2.20.1
109
2.34.1
141
110
142
111
diff view generated by jsdifflib
1
Implement the MVE shift-vector-left-by-immediate insns VSHL, VQSHL
1
Add the remaining devices (or unimplemented-device stubs) for
2
and VQSHLU.
2
this board: SPI controllers, SCC, FPGAIO, I2S, RTC, the
3
3
QSPI write-config block, and ethernet.
4
The size-and-immediate encoding here is the same as Neon, and we
5
handle it the same way neon-dp.decode does.
6
4
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20210628135835.6690-8-peter.maydell@linaro.org
7
Message-id: 20240206132931.38376-13-peter.maydell@linaro.org
10
---
8
---
11
target/arm/helper-mve.h | 16 +++++++++++
9
hw/arm/mps3r.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++
12
target/arm/mve.decode | 23 +++++++++++++++
10
1 file changed, 74 insertions(+)
13
target/arm/mve_helper.c | 57 ++++++++++++++++++++++++++++++++++++++
14
target/arm/translate-mve.c | 51 ++++++++++++++++++++++++++++++++++
15
4 files changed, 147 insertions(+)
16
11
17
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper-mve.h
14
--- a/hw/arm/mps3r.c
20
+++ b/target/arm/helper-mve.h
15
+++ b/hw/arm/mps3r.c
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(mve_vaddvuw, TCG_CALL_NO_WG, i32, env, ptr, i32)
16
@@ -XXX,XX +XXX,XX @@
22
DEF_HELPER_FLAGS_3(mve_vmovi, TCG_CALL_NO_WG, void, env, ptr, i64)
17
#include "hw/char/cmsdk-apb-uart.h"
23
DEF_HELPER_FLAGS_3(mve_vandi, TCG_CALL_NO_WG, void, env, ptr, i64)
18
#include "hw/i2c/arm_sbcon_i2c.h"
24
DEF_HELPER_FLAGS_3(mve_vorri, TCG_CALL_NO_WG, void, env, ptr, i64)
19
#include "hw/intc/arm_gicv3.h"
20
+#include "hw/misc/mps2-scc.h"
21
+#include "hw/misc/mps2-fpgaio.h"
22
#include "hw/misc/unimp.h"
23
+#include "hw/net/lan9118.h"
24
+#include "hw/rtc/pl031.h"
25
+#include "hw/ssi/pl022.h"
26
#include "hw/timer/cmsdk-apb-dualtimer.h"
27
#include "hw/watchdog/cmsdk-apb-watchdog.h"
28
29
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
30
CMSDKAPBWatchdog watchdog;
31
CMSDKAPBDualTimer dualtimer;
32
ArmSbconI2CState i2c[5];
33
+ PL022State spi[3];
34
+ MPS2SCC scc;
35
+ MPS2FPGAIO fpgaio;
36
+ UnimplementedDeviceState i2s_audio;
37
+ PL031State rtc;
38
Clock *clk;
39
};
40
41
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an536_raminfo[] = {
42
}
43
};
44
45
+static const int an536_oscclk[] = {
46
+ 24000000, /* 24MHz reference for RTC and timers */
47
+ 50000000, /* 50MHz ACLK */
48
+ 50000000, /* 50MHz MCLK */
49
+ 50000000, /* 50MHz GPUCLK */
50
+ 24576000, /* 24.576MHz AUDCLK */
51
+ 23750000, /* 23.75MHz HDLCDCLK */
52
+ 100000000, /* 100MHz DDR4_REF_CLK */
53
+};
25
+
54
+
26
+DEF_HELPER_FLAGS_4(mve_vshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
55
static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
27
+DEF_HELPER_FLAGS_4(mve_vshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
56
const RAMInfo *raminfo)
28
+DEF_HELPER_FLAGS_4(mve_vshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
57
{
58
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
59
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
60
MemoryRegion *sysmem = get_system_memory();
61
DeviceState *gicdev;
62
+ QList *oscclk;
63
64
mms->clk = clock_new(OBJECT(machine), "CLK");
65
clock_set_hz(mms->clk, CLK_FRQ);
66
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
67
}
68
}
69
70
+ for (int i = 0; i < ARRAY_SIZE(mms->spi); i++) {
71
+ g_autofree char *s = g_strdup_printf("spi%d", i);
72
+ hwaddr baseaddr = 0xe0104000 + i * 0x1000;
29
+
73
+
30
+DEF_HELPER_FLAGS_4(mve_vqshli_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
74
+ object_initialize_child(OBJECT(mms), s, &mms->spi[i], TYPE_PL022);
31
+DEF_HELPER_FLAGS_4(mve_vqshli_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->spi[i]), &error_fatal);
32
+DEF_HELPER_FLAGS_4(mve_vqshli_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
76
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->spi[i]), 0, baseaddr);
33
+
77
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->spi[i]), 0,
34
+DEF_HELPER_FLAGS_4(mve_vqshli_ub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
78
+ qdev_get_gpio_in(gicdev, 22 + i));
35
+DEF_HELPER_FLAGS_4(mve_vqshli_uh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_4(mve_vqshli_uw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
37
+
38
+DEF_HELPER_FLAGS_4(mve_vqshlui_sb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_4(mve_vqshlui_sh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(mve_vqshlui_sw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/mve.decode
44
+++ b/target/arm/mve.decode
45
@@ -XXX,XX +XXX,XX @@
46
&2op qd qm qn size
47
&2scalar qd qn rm size
48
&1imm qd imm cmode op
49
+&2shift qd qm shift size
50
51
@vldr_vstr ....... . . . . l:1 rn:4 ... ...... imm:7 &vldr_vstr qd=%qd u=0
52
# Note that both Rn and Qd are 3 bits only (no D bit)
53
@@ -XXX,XX +XXX,XX @@
54
@2scalar .... .... .. size:2 .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
55
@2scalar_nosz .... .... .... .... .... .... .... rm:4 &2scalar qd=%qd qn=%qn
56
57
+@2_shl_b .... .... .. 001 shift:3 .... .... .... .... &2shift qd=%qd qm=%qm size=0
58
+@2_shl_h .... .... .. 01 shift:4 .... .... .... .... &2shift qd=%qd qm=%qm size=1
59
+@2_shl_w .... .... .. 1 shift:5 .... .... .... .... &2shift qd=%qd qm=%qm size=2
60
+
61
# Vector loads and stores
62
63
# Widening loads and narrowing stores:
64
@@ -XXX,XX +XXX,XX @@ VPST 1111 1110 0 . 11 000 1 ... 0 1111 0100 1101 mask=%mask_22_13
65
# So we have a single decode line and check the cmode/op in the
66
# trans function.
67
Vimm_1r 111 . 1111 1 . 00 0 ... ... 0 .... 0 1 . 1 .... @1imm
68
+
69
+# Shifts by immediate
70
+
71
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
72
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
73
+VSHLI 111 0 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
74
+
75
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
76
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
77
+VQSHLI_S 111 0 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
78
+
79
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_b
80
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_h
81
+VQSHLI_U 111 1 1111 1 . ... ... ... 0 0111 0 1 . 1 ... 0 @2_shl_w
82
+
83
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_b
84
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_h
85
+VQSHLUI 111 1 1111 1 . ... ... ... 0 0110 0 1 . 1 ... 0 @2_shl_w
86
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/arm/mve_helper.c
89
+++ b/target/arm/mve_helper.c
90
@@ -XXX,XX +XXX,XX @@ DO_2OP_SAT(vqsubsw, 4, int32_t, DO_SQSUB_W)
91
WRAP_QRSHL_HELPER(do_sqrshl_bhs, N, M, true, satp)
92
#define DO_UQRSHL_OP(N, M, satp) \
93
WRAP_QRSHL_HELPER(do_uqrshl_bhs, N, M, true, satp)
94
+#define DO_SUQSHL_OP(N, M, satp) \
95
+ WRAP_QRSHL_HELPER(do_suqrshl_bhs, N, M, false, satp)
96
97
DO_2OP_SAT_S(vqshls, DO_SQSHL_OP)
98
DO_2OP_SAT_U(vqshlu, DO_UQSHL_OP)
99
@@ -XXX,XX +XXX,XX @@ DO_VADDV(vaddvsw, 4, uint32_t)
100
DO_VADDV(vaddvub, 1, uint8_t)
101
DO_VADDV(vaddvuh, 2, uint16_t)
102
DO_VADDV(vaddvuw, 4, uint32_t)
103
+
104
+/* Shifts by immediate */
105
+#define DO_2SHIFT(OP, ESIZE, TYPE, FN) \
106
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
107
+ void *vm, uint32_t shift) \
108
+ { \
109
+ TYPE *d = vd, *m = vm; \
110
+ uint16_t mask = mve_element_mask(env); \
111
+ unsigned e; \
112
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
113
+ mergemask(&d[H##ESIZE(e)], \
114
+ FN(m[H##ESIZE(e)], shift), mask); \
115
+ } \
116
+ mve_advance_vpt(env); \
117
+ }
79
+ }
118
+
80
+
119
+#define DO_2SHIFT_SAT(OP, ESIZE, TYPE, FN) \
81
+ object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
120
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
82
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg0", 0);
121
+ void *vm, uint32_t shift) \
83
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg4", 0x2);
122
+ { \
84
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-aid", 0x00200008);
123
+ TYPE *d = vd, *m = vm; \
85
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-id", 0x41055360);
124
+ uint16_t mask = mve_element_mask(env); \
86
+ oscclk = qlist_new();
125
+ unsigned e; \
87
+ for (int i = 0; i < ARRAY_SIZE(an536_oscclk); i++) {
126
+ bool qc = false; \
88
+ qlist_append_int(oscclk, an536_oscclk[i]);
127
+ for (e = 0; e < 16 / ESIZE; e++, mask >>= ESIZE) { \
128
+ bool sat = false; \
129
+ mergemask(&d[H##ESIZE(e)], \
130
+ FN(m[H##ESIZE(e)], shift, &sat), mask); \
131
+ qc |= sat & mask & 1; \
132
+ } \
133
+ if (qc) { \
134
+ env->vfp.qc[0] = qc; \
135
+ } \
136
+ mve_advance_vpt(env); \
137
+ }
89
+ }
90
+ qdev_prop_set_array(DEVICE(&mms->scc), "oscclk", oscclk);
91
+ sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
92
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->scc), 0, 0xe0200000);
138
+
93
+
139
+/* provide unsigned 2-op shift helpers for all sizes */
94
+ create_unimplemented_device("i2s-audio", 0xe0201000, 0x1000);
140
+#define DO_2SHIFT_U(OP, FN) \
141
+ DO_2SHIFT(OP##b, 1, uint8_t, FN) \
142
+ DO_2SHIFT(OP##h, 2, uint16_t, FN) \
143
+ DO_2SHIFT(OP##w, 4, uint32_t, FN)
144
+
95
+
145
+#define DO_2SHIFT_SAT_U(OP, FN) \
96
+ object_initialize_child(OBJECT(mms), "fpgaio", &mms->fpgaio,
146
+ DO_2SHIFT_SAT(OP##b, 1, uint8_t, FN) \
97
+ TYPE_MPS2_FPGAIO);
147
+ DO_2SHIFT_SAT(OP##h, 2, uint16_t, FN) \
98
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", an536_oscclk[1]);
148
+ DO_2SHIFT_SAT(OP##w, 4, uint32_t, FN)
99
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "num-leds", 10);
149
+#define DO_2SHIFT_SAT_S(OP, FN) \
100
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-switches", true);
150
+ DO_2SHIFT_SAT(OP##b, 1, int8_t, FN) \
101
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-dbgctrl", false);
151
+ DO_2SHIFT_SAT(OP##h, 2, int16_t, FN) \
102
+ sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
152
+ DO_2SHIFT_SAT(OP##w, 4, int32_t, FN)
103
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0xe0202000);
153
+
104
+
154
+DO_2SHIFT_U(vshli_u, DO_VSHLU)
105
+ create_unimplemented_device("clcd", 0xe0209000, 0x1000);
155
+DO_2SHIFT_SAT_U(vqshli_u, DO_UQSHL_OP)
156
+DO_2SHIFT_SAT_S(vqshli_s, DO_SQSHL_OP)
157
+DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
158
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
159
index XXXXXXX..XXXXXXX 100644
160
--- a/target/arm/translate-mve.c
161
+++ b/target/arm/translate-mve.c
162
@@ -XXX,XX +XXX,XX @@ typedef void MVEGenLdStFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
163
typedef void MVEGenOneOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
164
typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
165
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
166
+typedef void MVEGenTwoOpShiftFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
167
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
168
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
169
typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
170
@@ -XXX,XX +XXX,XX @@ static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
171
}
172
return do_1imm(s, a, fn);
173
}
174
+
106
+
175
+static bool do_2shift(DisasContext *s, arg_2shift *a, MVEGenTwoOpShiftFn fn,
107
+ object_initialize_child(OBJECT(mms), "rtc", &mms->rtc, TYPE_PL031);
176
+ bool negateshift)
108
+ sysbus_realize(SYS_BUS_DEVICE(&mms->rtc), &error_fatal);
177
+{
109
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->rtc), 0, 0xe020a000);
178
+ TCGv_ptr qd, qm;
110
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->rtc), 0,
179
+ int shift = a->shift;
111
+ qdev_get_gpio_in(gicdev, 4));
180
+
181
+ if (!dc_isar_feature(aa32_mve, s) ||
182
+ !mve_check_qreg_bank(s, a->qd | a->qm) ||
183
+ !fn) {
184
+ return false;
185
+ }
186
+ if (!mve_eci_check(s) || !vfp_access_check(s)) {
187
+ return true;
188
+ }
189
+
112
+
190
+ /*
113
+ /*
191
+ * When we handle a right shift insn using a left-shift helper
114
+ * In hardware this is a LAN9220; the LAN9118 is software compatible
192
+ * which permits a negative shift count to indicate a right-shift,
115
+ * except that it doesn't support the checksum-offload feature.
193
+ * we must negate the shift count.
194
+ */
116
+ */
195
+ if (negateshift) {
117
+ lan9118_init(0xe0300000,
196
+ shift = -shift;
118
+ qdev_get_gpio_in(gicdev, 18));
197
+ }
198
+
119
+
199
+ qd = mve_qreg_ptr(a->qd);
120
+ create_unimplemented_device("usb", 0xe0301000, 0x1000);
200
+ qm = mve_qreg_ptr(a->qm);
121
+ create_unimplemented_device("qspi-write-config", 0xe0600000, 0x1000);
201
+ fn(cpu_env, qd, qm, tcg_constant_i32(shift));
202
+ tcg_temp_free_ptr(qd);
203
+ tcg_temp_free_ptr(qm);
204
+ mve_update_eci(s);
205
+ return true;
206
+}
207
+
122
+
208
+#define DO_2SHIFT(INSN, FN, NEGATESHIFT) \
123
mms->bootinfo.ram_size = machine->ram_size;
209
+ static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
124
mms->bootinfo.board_id = -1;
210
+ { \
125
mms->bootinfo.loader_start = mmc->loader_start;
211
+ static MVEGenTwoOpShiftFn * const fns[] = { \
212
+ gen_helper_mve_##FN##b, \
213
+ gen_helper_mve_##FN##h, \
214
+ gen_helper_mve_##FN##w, \
215
+ NULL, \
216
+ }; \
217
+ return do_2shift(s, a, fns[a->size], NEGATESHIFT); \
218
+ }
219
+
220
+DO_2SHIFT(VSHLI, vshli_u, false)
221
+DO_2SHIFT(VQSHLI_S, vqshli_s, false)
222
+DO_2SHIFT(VQSHLI_U, vqshli_u, false)
223
+DO_2SHIFT(VQSHLUI, vqshlui_s, false)
224
--
126
--
225
2.20.1
127
2.34.1
226
128
227
129
diff view generated by jsdifflib
1
Implement the MVE VSRI and VSLI insns, which perform a
1
Add documentation for the mps3-an536 board type.
2
shift-and-insert operation.
3
2
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20210628135835.6690-11-peter.maydell@linaro.org
5
Message-id: 20240206132931.38376-14-peter.maydell@linaro.org
7
---
6
---
8
target/arm/helper-mve.h | 8 ++++++++
7
docs/system/arm/mps2.rst | 37 ++++++++++++++++++++++++++++++++++---
9
target/arm/mve.decode | 9 ++++++++
8
1 file changed, 34 insertions(+), 3 deletions(-)
10
target/arm/mve_helper.c | 42 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-mve.c | 3 +++
12
4 files changed, 62 insertions(+)
13
9
14
diff --git a/target/arm/helper-mve.h b/target/arm/helper-mve.h
10
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-mve.h
12
--- a/docs/system/arm/mps2.rst
17
+++ b/target/arm/helper-mve.h
13
+++ b/docs/system/arm/mps2.rst
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(mve_vshlltsb, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
14
@@ -XXX,XX +XXX,XX @@
19
DEF_HELPER_FLAGS_4(mve_vshlltsh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
15
-Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
20
DEF_HELPER_FLAGS_4(mve_vshlltub, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
16
-=========================================================================================================================================================
21
DEF_HELPER_FLAGS_4(mve_vshlltuh, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
17
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an536``, ``mps3-an547``)
18
+=========================================================================================================================================================================
19
20
-These board models all use Arm M-profile CPUs.
21
+These board models use Arm M-profile or R-profile CPUs.
22
23
The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
24
bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
25
@@ -XXX,XX +XXX,XX @@ FPGA image.
26
27
QEMU models the following FPGA images:
28
29
+FPGA images using M-profile CPUs:
22
+
30
+
23
+DEF_HELPER_FLAGS_4(mve_vsrib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
31
``mps2-an385``
24
+DEF_HELPER_FLAGS_4(mve_vsrih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
32
Cortex-M3 as documented in Arm Application Note AN385
25
+DEF_HELPER_FLAGS_4(mve_vsriw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
33
``mps2-an386``
34
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
35
``mps3-an547``
36
Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
37
38
+FPGA images using R-profile CPUs:
26
+
39
+
27
+DEF_HELPER_FLAGS_4(mve_vslib, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
40
+``mps3-an536``
28
+DEF_HELPER_FLAGS_4(mve_vslih, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
41
+ Dual Cortex-R52 on an MPS3, as documented in Arm Application Note AN536
29
+DEF_HELPER_FLAGS_4(mve_vsliw, TCG_CALL_NO_WG, void, env, ptr, ptr, i32)
30
diff --git a/target/arm/mve.decode b/target/arm/mve.decode
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/mve.decode
33
+++ b/target/arm/mve.decode
34
@@ -XXX,XX +XXX,XX @@ VSHLL_TS 111 0 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
35
36
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_b
37
VSHLL_TU 111 1 1110 1 . 1 .. ... ... 1 1111 0 1 . 0 ... 0 @2_shll_h
38
+
42
+
39
+# Shift-and-insert
43
Differences between QEMU and real hardware:
40
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_b
44
41
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_h
45
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
42
+VSRI 111 1 1111 1 . ... ... ... 0 0100 0 1 . 1 ... 0 @2_shr_w
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.
43
+
64
+
44
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_b
65
+Note that for the AN536 the first UART is accessible only by
45
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_h
66
+CPU0, and the second UART is accessible only by CPU1. The
46
+VSLI 111 1 1111 1 . ... ... ... 0 0101 0 1 . 1 ... 0 @2_shl_w
67
+first UART accessible shared between both CPUs is the third
47
diff --git a/target/arm/mve_helper.c b/target/arm/mve_helper.c
68
+UART. Guest software might therefore be built to use either
48
index XXXXXXX..XXXXXXX 100644
69
+the first UART or the third UART; if you don't see any output
49
--- a/target/arm/mve_helper.c
70
+from the UART you are looking at, try one of the others.
50
+++ b/target/arm/mve_helper.c
71
+(Even if the AN536 machine is started with a single CPU and so
51
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT_SAT_S(vqshlui_s, DO_SUQSHL_OP)
72
+no "CPU1-only UART", the UART numbering remains the same,
52
DO_2SHIFT_U(vrshli_u, DO_VRSHLU)
73
+with the third UART being the first of the shared ones.)
53
DO_2SHIFT_S(vrshli_s, DO_VRSHLS)
74
54
75
Machine-specific options
55
+/* Shift-and-insert; we always work with 64 bits at a time */
76
""""""""""""""""""""""""
56
+#define DO_2SHIFT_INSERT(OP, ESIZE, SHIFTFN, MASKFN) \
57
+ void HELPER(glue(mve_, OP))(CPUARMState *env, void *vd, \
58
+ void *vm, uint32_t shift) \
59
+ { \
60
+ uint64_t *d = vd, *m = vm; \
61
+ uint16_t mask; \
62
+ uint64_t shiftmask; \
63
+ unsigned e; \
64
+ if (shift == 0 || shift == ESIZE * 8) { \
65
+ /* \
66
+ * Only VSLI can shift by 0; only VSRI can shift by <dt>. \
67
+ * The generic logic would give the right answer for 0 but \
68
+ * fails for <dt>. \
69
+ */ \
70
+ goto done; \
71
+ } \
72
+ assert(shift < ESIZE * 8); \
73
+ mask = mve_element_mask(env); \
74
+ /* ESIZE / 2 gives the MO_* value if ESIZE is in [1,2,4] */ \
75
+ shiftmask = dup_const(ESIZE / 2, MASKFN(ESIZE * 8, shift)); \
76
+ for (e = 0; e < 16 / 8; e++, mask >>= 8) { \
77
+ uint64_t r = (SHIFTFN(m[H8(e)], shift) & shiftmask) | \
78
+ (d[H8(e)] & ~shiftmask); \
79
+ mergemask(&d[H8(e)], r, mask); \
80
+ } \
81
+done: \
82
+ mve_advance_vpt(env); \
83
+ }
84
+
85
+#define DO_SHL(N, SHIFT) ((N) << (SHIFT))
86
+#define DO_SHR(N, SHIFT) ((N) >> (SHIFT))
87
+#define SHL_MASK(EBITS, SHIFT) MAKE_64BIT_MASK((SHIFT), (EBITS) - (SHIFT))
88
+#define SHR_MASK(EBITS, SHIFT) MAKE_64BIT_MASK(0, (EBITS) - (SHIFT))
89
+
90
+DO_2SHIFT_INSERT(vsrib, 1, DO_SHR, SHR_MASK)
91
+DO_2SHIFT_INSERT(vsrih, 2, DO_SHR, SHR_MASK)
92
+DO_2SHIFT_INSERT(vsriw, 4, DO_SHR, SHR_MASK)
93
+DO_2SHIFT_INSERT(vslib, 1, DO_SHL, SHL_MASK)
94
+DO_2SHIFT_INSERT(vslih, 2, DO_SHL, SHL_MASK)
95
+DO_2SHIFT_INSERT(vsliw, 4, DO_SHL, SHL_MASK)
96
+
97
/*
98
* Long shifts taking half-sized inputs from top or bottom of the input
99
* vector and producing a double-width result. ESIZE, TYPE are for
100
diff --git a/target/arm/translate-mve.c b/target/arm/translate-mve.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/translate-mve.c
103
+++ b/target/arm/translate-mve.c
104
@@ -XXX,XX +XXX,XX @@ DO_2SHIFT(VSHRI_U, vshli_u, true)
105
DO_2SHIFT(VRSHRI_S, vrshli_s, true)
106
DO_2SHIFT(VRSHRI_U, vrshli_u, true)
107
108
+DO_2SHIFT(VSRI, vsri, false)
109
+DO_2SHIFT(VSLI, vsli, false)
110
+
111
#define DO_VSHLL(INSN, FN) \
112
static bool trans_##INSN(DisasContext *s, arg_2shift *a) \
113
{ \
114
--
77
--
115
2.20.1
78
2.34.1
116
79
117
80
diff view generated by jsdifflib