1
target-arm queue: I have a lot more still in my to-review
1
I don't have anything else queued up at the moment, so this is just
2
queue, but my rule of thumb is when I get to 50 patches or
2
Richard's SME patches.
3
so to send out what I have.
4
3
5
thanks
6
-- PMM
4
-- PMM
7
5
8
The following changes since commit 9a7beaad3dbba982f7a461d676b55a5c3851d312:
6
The following changes since commit 63b38f6c85acd312c2cab68554abf33adf4ee2b3:
9
7
10
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20210304' into staging (2021-03-05 10:47:46 +0000)
8
Merge tag 'pull-target-arm-20220707' of https://git.linaro.org/people/pmaydell/qemu-arm into staging (2022-07-08 06:17:11 +0530)
11
9
12
are available in the Git repository at:
10
are available in the Git repository at:
13
11
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210305
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220711
15
13
16
for you to fetch changes up to 2c669ff88ec6733420a000103a2b8b9e93df4945:
14
for you to fetch changes up to f9982ceaf26df27d15547a3a7990a95019e9e3a8:
17
15
18
hw/arm/mps2: Update old infocenter.arm.com URLs (2021-03-05 15:17:38 +0000)
16
linux-user/aarch64: Add SME related hwcap entries (2022-07-11 13:43:52 +0100)
19
17
20
----------------------------------------------------------------
18
----------------------------------------------------------------
21
* sbsa-ref: remove cortex-a53 from list of supported cpus
19
target-arm:
22
* sbsa-ref: add 'max' to list of allowed cpus
20
* Implement SME emulation, for both system and linux-user
23
* target/arm: Add support for FEAT_SSBS, Speculative Store Bypass Safe
24
* npcm7xx: add EMC model
25
* xlnx-zynqmp: Remove obsolete 'has_rpu' property
26
* target/arm: Speed up aarch64 TBL/TBX
27
* virtio-mmio: improve virtio-mmio get_dev_path alog
28
* target/arm: Use TCF0 and TFSRE0 for unprivileged tag checks
29
* target/arm: Restrict v8M IDAU to TCG
30
* target/arm/cpu: Update coding style to make checkpatch.pl happy
31
* musicpal, tc6393xb, omap_lcdc, tcx: drop dead code for non-32-bit-RGB surfaces
32
* Add new board: mps3-an524
33
21
34
----------------------------------------------------------------
22
----------------------------------------------------------------
35
Doug Evans (3):
23
Richard Henderson (45):
36
hw/net: Add npcm7xx emc model
24
target/arm: Handle SME in aarch64_cpu_dump_state
37
hw/arm: Add npcm7xx emc model
25
target/arm: Add infrastructure for disas_sme
38
tests/qtests: Add npcm7xx emc model test
26
target/arm: Trap non-streaming usage when Streaming SVE is active
27
target/arm: Mark ADR as non-streaming
28
target/arm: Mark RDFFR, WRFFR, SETFFR as non-streaming
29
target/arm: Mark BDEP, BEXT, BGRP, COMPACT, FEXPA, FTSSEL as non-streaming
30
target/arm: Mark PMULL, FMMLA as non-streaming
31
target/arm: Mark FTSMUL, FTMAD, FADDA as non-streaming
32
target/arm: Mark SMMLA, UMMLA, USMMLA as non-streaming
33
target/arm: Mark string/histo/crypto as non-streaming
34
target/arm: Mark gather/scatter load/store as non-streaming
35
target/arm: Mark gather prefetch as non-streaming
36
target/arm: Mark LDFF1 and LDNF1 as non-streaming
37
target/arm: Mark LD1RO as non-streaming
38
target/arm: Add SME enablement checks
39
target/arm: Handle SME in sve_access_check
40
target/arm: Implement SME RDSVL, ADDSVL, ADDSPL
41
target/arm: Implement SME ZERO
42
target/arm: Implement SME MOVA
43
target/arm: Implement SME LD1, ST1
44
target/arm: Export unpredicated ld/st from translate-sve.c
45
target/arm: Implement SME LDR, STR
46
target/arm: Implement SME ADDHA, ADDVA
47
target/arm: Implement FMOPA, FMOPS (non-widening)
48
target/arm: Implement BFMOPA, BFMOPS
49
target/arm: Implement FMOPA, FMOPS (widening)
50
target/arm: Implement SME integer outer product
51
target/arm: Implement PSEL
52
target/arm: Implement REVD
53
target/arm: Implement SCLAMP, UCLAMP
54
target/arm: Reset streaming sve state on exception boundaries
55
target/arm: Enable SME for -cpu max
56
linux-user/aarch64: Clear tpidr2_el0 if CLONE_SETTLS
57
linux-user/aarch64: Reset PSTATE.SM on syscalls
58
linux-user/aarch64: Add SM bit to SVE signal context
59
linux-user/aarch64: Tidy target_restore_sigframe error return
60
linux-user/aarch64: Do not allow duplicate or short sve records
61
linux-user/aarch64: Verify extra record lock succeeded
62
linux-user/aarch64: Move sve record checks into restore
63
linux-user/aarch64: Implement SME signal handling
64
linux-user: Rename sve prctls
65
linux-user/aarch64: Implement PR_SME_GET_VL, PR_SME_SET_VL
66
target/arm: Only set ZEN in reset if SVE present
67
target/arm: Enable SME for user-only
68
linux-user/aarch64: Add SME related hwcap entries
39
69
40
Marcin Juszkiewicz (2):
70
docs/system/arm/emulation.rst | 4 +
41
sbsa-ref: remove cortex-a53 from list of supported cpus
71
linux-user/aarch64/target_cpu.h | 5 +-
42
sbsa-ref: add 'max' to list of allowed cpus
72
linux-user/aarch64/target_prctl.h | 62 +-
43
73
target/arm/cpu.h | 7 +
44
Peter Collingbourne (1):
74
target/arm/helper-sme.h | 126 ++++
45
target/arm: Use TCF0 and TFSRE0 for unprivileged tag checks
75
target/arm/helper-sve.h | 4 +
46
76
target/arm/helper.h | 18 +
47
Peter Maydell (34):
77
target/arm/translate-a64.h | 45 ++
48
hw/arm/musicpal: Remove dead code for non-32-bit-RGB surfaces
78
target/arm/translate.h | 16 +
49
hw/display/tc6393xb: Remove dead code for handling non-32bpp surfaces
79
target/arm/sme-fa64.decode | 60 ++
50
hw/display/tc6393xb: Expand out macros in template header
80
target/arm/sme.decode | 88 +++
51
hw/display/tc6393xb: Inline tc6393xb_draw_graphic32() at its callsite
81
target/arm/sve.decode | 41 +-
52
hw/display/omap_lcdc: Expand out macros in template header
82
linux-user/aarch64/cpu_loop.c | 9 +
53
hw/display/omap_lcdc: Drop broken bigendian ifdef
83
linux-user/aarch64/signal.c | 243 ++++++--
54
hw/display/omap_lcdc: Fix coding style issues in template header
84
linux-user/elfload.c | 20 +
55
hw/display/omap_lcdc: Inline template header into C file
85
linux-user/syscall.c | 28 +-
56
hw/display/omap_lcdc: Delete unnecessary macro
86
target/arm/cpu.c | 35 +-
57
hw/display/tcx: Drop unnecessary code for handling BGR format outputs
87
target/arm/cpu64.c | 11 +
58
hw/arm/mps2-tz: Make SYSCLK frequency board-specific
88
target/arm/helper.c | 56 +-
59
hw/misc/mps2-scc: Support configurable number of OSCCLK values
89
target/arm/sme_helper.c | 1140 +++++++++++++++++++++++++++++++++++++
60
hw/arm/mps2-tz: Correct the OSCCLK settings for mps2-an505 and mps2-an511
90
target/arm/sve_helper.c | 28 +
61
hw/arm/mps2-tz: Make the OSCCLK settings be configurable per-board
91
target/arm/translate-a64.c | 103 +++-
62
hw/misc/mps2-fpgaio: Make number of LEDs configurable by board
92
target/arm/translate-sme.c | 373 ++++++++++++
63
hw/misc/mps2-fpgaio: Support SWITCH register
93
target/arm/translate-sve.c | 393 ++++++++++---
64
hw/arm/mps2-tz: Make FPGAIO switch and LED config per-board
94
target/arm/translate-vfp.c | 12 +
65
hw/arm/mps2-tz: Condition IRQ splitting on number of CPUs, not board type
95
target/arm/translate.c | 2 +
66
hw/arm/mps2-tz: Make number of IRQs board-specific
96
target/arm/vec_helper.c | 24 +
67
hw/misc/mps2-scc: Implement CFG_REG5 and CFG_REG6 for MPS3 AN524
97
target/arm/meson.build | 3 +
68
hw/arm/mps2-tz: Correct wrong interrupt numbers for DMA and SPI
98
28 files changed, 2821 insertions(+), 135 deletions(-)
69
hw/arm/mps2-tz: Allow PPCPortInfo structures to specify device interrupts
99
create mode 100644 target/arm/sme-fa64.decode
70
hw/arm/mps2-tz: Move device IRQ info to data structures
100
create mode 100644 target/arm/sme.decode
71
hw/arm/mps2-tz: Size the uart-irq-orgate based on the number of UARTs
101
create mode 100644 target/arm/translate-sme.c
72
hw/arm/mps2-tz: Allow boards to have different PPCInfo data
73
hw/arm/mps2-tz: Make RAM arrangement board-specific
74
hw/arm/mps2-tz: Set MachineClass default_ram info from RAMInfo data
75
hw/arm/mps2-tz: Support ROMs as well as RAMs
76
hw/arm/mps2-tz: Get armv7m_load_kernel() size argument from RAMInfo
77
hw/arm/mps2-tz: Add new mps3-an524 board
78
hw/arm/mps2-tz: Stub out USB controller for mps3-an524
79
hw/arm/mps2-tz: Provide PL031 RTC on mps3-an524
80
docs/system/arm/mps2.rst: Document the new mps3-an524 board
81
hw/arm/mps2: Update old infocenter.arm.com URLs
82
83
Philippe Mathieu-Daudé (4):
84
hw/arm/xlnx-zynqmp: Remove obsolete 'has_rpu' property
85
hw/i2c/npcm7xx_smbus: Simplify npcm7xx_smbus_init()
86
target/arm: Restrict v8M IDAU to TCG
87
target/arm/cpu: Update coding style to make checkpatch.pl happy
88
89
Rebecca Cran (3):
90
target/arm: Add support for FEAT_SSBS, Speculative Store Bypass Safe
91
target/arm: Enable FEAT_SSBS for "max" AARCH64 CPU
92
target/arm: Set ID_PFR2.SSBS to 1 for "max" 32-bit CPU
93
94
Richard Henderson (1):
95
target/arm: Speed up aarch64 TBL/TBX
96
97
schspa (1):
98
virtio-mmio: improve virtio-mmio get_dev_path alog
99
100
docs/system/arm/mps2.rst | 24 +-
101
docs/system/arm/nuvoton.rst | 3 +-
102
hw/display/omap_lcd_template.h | 169 --------
103
hw/display/tc6393xb_template.h | 72 ----
104
include/hw/arm/armsse.h | 4 +-
105
include/hw/arm/npcm7xx.h | 2 +
106
include/hw/arm/xlnx-zynqmp.h | 2 -
107
include/hw/misc/armsse-cpuid.h | 2 +-
108
include/hw/misc/armsse-mhu.h | 2 +-
109
include/hw/misc/iotkit-secctl.h | 2 +-
110
include/hw/misc/iotkit-sysctl.h | 2 +-
111
include/hw/misc/iotkit-sysinfo.h | 2 +-
112
include/hw/misc/mps2-fpgaio.h | 8 +-
113
include/hw/misc/mps2-scc.h | 10 +-
114
include/hw/net/npcm7xx_emc.h | 286 +++++++++++++
115
include/ui/console.h | 10 -
116
target/arm/cpu.h | 15 +-
117
target/arm/helper-a64.h | 2 +-
118
target/arm/internals.h | 6 +
119
hw/arm/mps2-tz.c | 632 +++++++++++++++++++++++-----
120
hw/arm/mps2.c | 5 +
121
hw/arm/musicpal.c | 64 ++-
122
hw/arm/npcm7xx.c | 50 ++-
123
hw/arm/sbsa-ref.c | 2 +-
124
hw/arm/xlnx-zynqmp.c | 6 -
125
hw/display/omap_lcdc.c | 129 +++++-
126
hw/display/tc6393xb.c | 48 +--
127
hw/display/tcx.c | 31 +-
128
hw/i2c/npcm7xx_smbus.c | 1 -
129
hw/misc/armsse-cpuid.c | 2 +-
130
hw/misc/armsse-mhu.c | 2 +-
131
hw/misc/iotkit-sysctl.c | 2 +-
132
hw/misc/iotkit-sysinfo.c | 2 +-
133
hw/misc/mps2-fpgaio.c | 43 +-
134
hw/misc/mps2-scc.c | 93 ++++-
135
hw/net/npcm7xx_emc.c | 857 ++++++++++++++++++++++++++++++++++++++
136
hw/virtio/virtio-mmio.c | 13 +-
137
target/arm/cpu.c | 23 +-
138
target/arm/cpu64.c | 5 +
139
target/arm/cpu_tcg.c | 8 +
140
target/arm/helper-a64.c | 32 --
141
target/arm/helper.c | 39 +-
142
target/arm/mte_helper.c | 13 +-
143
target/arm/translate-a64.c | 70 +---
144
target/arm/vec_helper.c | 48 +++
145
tests/qtest/npcm7xx_emc-test.c | 862 +++++++++++++++++++++++++++++++++++++++
146
hw/net/meson.build | 1 +
147
hw/net/trace-events | 17 +
148
tests/qtest/meson.build | 3 +-
149
49 files changed, 3098 insertions(+), 628 deletions(-)
150
delete mode 100644 hw/display/omap_lcd_template.h
151
delete mode 100644 hw/display/tc6393xb_template.h
152
create mode 100644 include/hw/net/npcm7xx_emc.h
153
create mode 100644 hw/net/npcm7xx_emc.c
154
create mode 100644 tests/qtest/npcm7xx_emc-test.c
155
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We will move this code in the next commit. Clean it up
3
Dump SVCR, plus use the correct access check for Streaming Mode.
4
first to avoid checkpatch.pl errors.
5
4
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210221222617.2579610-3-f4bug@amsat.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220708151540.18136-2-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
target/arm/cpu.c | 12 ++++++++----
10
target/arm/cpu.c | 17 ++++++++++++++++-
12
1 file changed, 8 insertions(+), 4 deletions(-)
11
1 file changed, 16 insertions(+), 1 deletion(-)
13
12
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
13
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.c
15
--- a/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
16
+++ b/target/arm/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
19
}
18
int i;
20
19
int el = arm_current_el(env);
21
static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
20
const char *ns_status;
22
- /* power_control should be set to maximum latency. Again,
21
+ bool sve;
23
+ /*
22
24
+ * power_control should be set to maximum latency. Again,
23
qemu_fprintf(f, " PC=%016" PRIx64 " ", env->pc);
25
* default to 0 and set by private hook
24
for (i = 0; i < 32; i++) {
26
*/
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
27
{ .name = "A9_PWRCTL", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
26
el,
28
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
27
psr & PSTATE_SP ? 'h' : 't');
29
set_feature(&cpu->env, ARM_FEATURE_NEON);
28
30
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
29
+ if (cpu_isar_feature(aa64_sme, cpu)) {
31
set_feature(&cpu->env, ARM_FEATURE_EL3);
30
+ qemu_fprintf(f, " SVCR=%08" PRIx64 " %c%c",
32
- /* Note that A9 supports the MP extensions even for
31
+ env->svcr,
33
+ /*
32
+ (FIELD_EX64(env->svcr, SVCR, ZA) ? 'Z' : '-'),
34
+ * Note that A9 supports the MP extensions even for
33
+ (FIELD_EX64(env->svcr, SVCR, SM) ? 'S' : '-'));
35
* A9UP and single-core A9MP (which are both different
34
+ }
36
* and valid configurations; we don't model A9UP).
35
if (cpu_isar_feature(aa64_bti, cpu)) {
37
*/
36
qemu_fprintf(f, " BTYPE=%d", (psr & PSTATE_BTYPE) >> 10);
38
@@ -XXX,XX +XXX,XX @@ static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
37
}
39
{
38
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
40
MachineState *ms = MACHINE(qdev_get_machine());
39
qemu_fprintf(f, " FPCR=%08x FPSR=%08x\n",
41
40
vfp_get_fpcr(env), vfp_get_fpsr(env));
42
- /* Linux wants the number of processors from here.
41
43
+ /*
42
- if (cpu_isar_feature(aa64_sve, cpu) && sve_exception_el(env, el) == 0) {
44
+ * Linux wants the number of processors from here.
43
+ if (cpu_isar_feature(aa64_sme, cpu) && FIELD_EX64(env->svcr, SVCR, SM)) {
45
* Might as well set the interrupt-controller bit too.
44
+ sve = sme_exception_el(env, el) == 0;
46
*/
45
+ } else if (cpu_isar_feature(aa64_sve, cpu)) {
47
return ((ms->smp.cpus - 1) << 24) | (1 << 23);
46
+ sve = sve_exception_el(env, el) == 0;
48
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
47
+ } else {
49
cpu->isar.id_mmfr1 = 0x40000000;
48
+ sve = false;
50
cpu->isar.id_mmfr2 = 0x01240000;
49
+ }
51
cpu->isar.id_mmfr3 = 0x02102211;
50
+
52
- /* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
51
+ if (sve) {
53
+ /*
52
int j, zcr_len = sve_vqm1_for_el(env, el);
54
+ * a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
53
55
* table 4-41 gives 0x02101110, which includes the arm div insns.
54
for (i = 0; i <= FFR_PRED_NUM; i++) {
56
*/
57
cpu->isar.id_isar0 = 0x02101110;
58
--
55
--
59
2.20.1
56
2.25.1
60
61
diff view generated by jsdifflib
1
From: Doug Evans <dje@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is a 10/100 ethernet device that has several features.
3
This includes the build rules for the decoder, and the
4
Only the ones needed by the Linux driver have been implemented.
4
new file for translation, but excludes any instructions.
5
See npcm7xx_emc.c for a list of unimplemented features.
6
5
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Doug Evans <dje@google.com>
8
Message-id: 20220708151540.18136-3-richard.henderson@linaro.org
10
Message-id: 20210218212453.831406-2-dje@google.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
include/hw/net/npcm7xx_emc.h | 286 ++++++++++++
11
target/arm/translate-a64.h | 1 +
14
hw/net/npcm7xx_emc.c | 857 +++++++++++++++++++++++++++++++++++
12
target/arm/sme.decode | 20 ++++++++++++++++++++
15
hw/net/meson.build | 1 +
13
target/arm/translate-a64.c | 7 ++++++-
16
hw/net/trace-events | 17 +
14
target/arm/translate-sme.c | 35 +++++++++++++++++++++++++++++++++++
17
4 files changed, 1161 insertions(+)
15
target/arm/meson.build | 2 ++
18
create mode 100644 include/hw/net/npcm7xx_emc.h
16
5 files changed, 64 insertions(+), 1 deletion(-)
19
create mode 100644 hw/net/npcm7xx_emc.c
17
create mode 100644 target/arm/sme.decode
18
create mode 100644 target/arm/translate-sme.c
20
19
21
diff --git a/include/hw/net/npcm7xx_emc.h b/include/hw/net/npcm7xx_emc.h
20
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/translate-a64.h
23
+++ b/target/arm/translate-a64.h
24
@@ -XXX,XX +XXX,XX @@ static inline int pred_gvec_reg_size(DisasContext *s)
25
}
26
27
bool disas_sve(DisasContext *, uint32_t);
28
+bool disas_sme(DisasContext *, uint32_t);
29
30
void gen_gvec_rax1(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
31
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
32
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
22
new file mode 100644
33
new file mode 100644
23
index XXXXXXX..XXXXXXX
34
index XXXXXXX..XXXXXXX
24
--- /dev/null
35
--- /dev/null
25
+++ b/include/hw/net/npcm7xx_emc.h
36
+++ b/target/arm/sme.decode
26
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
27
+/*
38
+# AArch64 SME instruction descriptions
28
+ * Nuvoton NPCM7xx EMC Module
39
+#
29
+ *
40
+# Copyright (c) 2022 Linaro, Ltd
30
+ * Copyright 2020 Google LLC
41
+#
31
+ *
42
+# This library is free software; you can redistribute it and/or
32
+ * This program is free software; you can redistribute it and/or modify it
43
+# modify it under the terms of the GNU Lesser General Public
33
+ * under the terms of the GNU General Public License as published by the
44
+# License as published by the Free Software Foundation; either
34
+ * Free Software Foundation; either version 2 of the License, or
45
+# version 2.1 of the License, or (at your option) any later version.
35
+ * (at your option) any later version.
46
+#
36
+ *
47
+# This library is distributed in the hope that it will be useful,
37
+ * This program is distributed in the hope that it will be useful, but WITHOUT
48
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
38
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
49
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
39
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
50
+# Lesser General Public License for more details.
40
+ * for more details.
51
+#
41
+ */
52
+# You should have received a copy of the GNU Lesser General Public
53
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
42
+
54
+
43
+#ifndef NPCM7XX_EMC_H
55
+#
44
+#define NPCM7XX_EMC_H
56
+# This file is processed by scripts/decodetree.py
45
+
57
+#
46
+#include "hw/irq.h"
58
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
47
+#include "hw/sysbus.h"
59
index XXXXXXX..XXXXXXX 100644
48
+#include "net/net.h"
60
--- a/target/arm/translate-a64.c
49
+
61
+++ b/target/arm/translate-a64.c
50
+/* 32-bit register indices. */
62
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
51
+enum NPCM7xxPWMRegister {
63
}
52
+ /* Control registers. */
64
53
+ REG_CAMCMR,
65
switch (extract32(insn, 25, 4)) {
54
+ REG_CAMEN,
66
- case 0x0: case 0x1: case 0x3: /* UNALLOCATED */
55
+
67
+ case 0x0:
56
+ /* There are 16 CAMn[ML] registers. */
68
+ if (!extract32(insn, 31, 1) || !disas_sme(s, insn)) {
57
+ REG_CAMM_BASE,
69
+ unallocated_encoding(s);
58
+ REG_CAML_BASE,
70
+ }
59
+ REG_CAMML_LAST = 0x21,
71
+ break;
60
+
72
+ case 0x1: case 0x3: /* UNALLOCATED */
61
+ REG_TXDLSA = 0x22,
73
unallocated_encoding(s);
62
+ REG_RXDLSA,
74
break;
63
+ REG_MCMDR,
75
case 0x2:
64
+ REG_MIID,
76
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
65
+ REG_MIIDA,
66
+ REG_FFTCR,
67
+ REG_TSDR,
68
+ REG_RSDR,
69
+ REG_DMARFC,
70
+ REG_MIEN,
71
+
72
+ /* Status registers. */
73
+ REG_MISTA,
74
+ REG_MGSTA,
75
+ REG_MPCNT,
76
+ REG_MRPC,
77
+ REG_MRPCC,
78
+ REG_MREPC,
79
+ REG_DMARFS,
80
+ REG_CTXDSA,
81
+ REG_CTXBSA,
82
+ REG_CRXDSA,
83
+ REG_CRXBSA,
84
+
85
+ NPCM7XX_NUM_EMC_REGS,
86
+};
87
+
88
+/* REG_CAMCMR fields */
89
+/* Enable CAM Compare */
90
+#define REG_CAMCMR_ECMP (1 << 4)
91
+/* Complement CAM Compare */
92
+#define REG_CAMCMR_CCAM (1 << 3)
93
+/* Accept Broadcast Packet */
94
+#define REG_CAMCMR_ABP (1 << 2)
95
+/* Accept Multicast Packet */
96
+#define REG_CAMCMR_AMP (1 << 1)
97
+/* Accept Unicast Packet */
98
+#define REG_CAMCMR_AUP (1 << 0)
99
+
100
+/* REG_MCMDR fields */
101
+/* Software Reset */
102
+#define REG_MCMDR_SWR (1 << 24)
103
+/* Internal Loopback Select */
104
+#define REG_MCMDR_LBK (1 << 21)
105
+/* Operation Mode Select */
106
+#define REG_MCMDR_OPMOD (1 << 20)
107
+/* Enable MDC Clock Generation */
108
+#define REG_MCMDR_ENMDC (1 << 19)
109
+/* Full-Duplex Mode Select */
110
+#define REG_MCMDR_FDUP (1 << 18)
111
+/* Enable SQE Checking */
112
+#define REG_MCMDR_ENSEQ (1 << 17)
113
+/* Send PAUSE Frame */
114
+#define REG_MCMDR_SDPZ (1 << 16)
115
+/* No Defer */
116
+#define REG_MCMDR_NDEF (1 << 9)
117
+/* Frame Transmission On */
118
+#define REG_MCMDR_TXON (1 << 8)
119
+/* Strip CRC Checksum */
120
+#define REG_MCMDR_SPCRC (1 << 5)
121
+/* Accept CRC Error Packet */
122
+#define REG_MCMDR_AEP (1 << 4)
123
+/* Accept Control Packet */
124
+#define REG_MCMDR_ACP (1 << 3)
125
+/* Accept Runt Packet */
126
+#define REG_MCMDR_ARP (1 << 2)
127
+/* Accept Long Packet */
128
+#define REG_MCMDR_ALP (1 << 1)
129
+/* Frame Reception On */
130
+#define REG_MCMDR_RXON (1 << 0)
131
+
132
+/* REG_MIEN fields */
133
+/* Enable Transmit Descriptor Unavailable Interrupt */
134
+#define REG_MIEN_ENTDU (1 << 23)
135
+/* Enable Transmit Completion Interrupt */
136
+#define REG_MIEN_ENTXCP (1 << 18)
137
+/* Enable Transmit Interrupt */
138
+#define REG_MIEN_ENTXINTR (1 << 16)
139
+/* Enable Receive Descriptor Unavailable Interrupt */
140
+#define REG_MIEN_ENRDU (1 << 10)
141
+/* Enable Receive Good Interrupt */
142
+#define REG_MIEN_ENRXGD (1 << 4)
143
+/* Enable Receive Interrupt */
144
+#define REG_MIEN_ENRXINTR (1 << 0)
145
+
146
+/* REG_MISTA fields */
147
+/* TODO: Add error fields and support simulated errors? */
148
+/* Transmit Bus Error Interrupt */
149
+#define REG_MISTA_TXBERR (1 << 24)
150
+/* Transmit Descriptor Unavailable Interrupt */
151
+#define REG_MISTA_TDU (1 << 23)
152
+/* Transmit Completion Interrupt */
153
+#define REG_MISTA_TXCP (1 << 18)
154
+/* Transmit Interrupt */
155
+#define REG_MISTA_TXINTR (1 << 16)
156
+/* Receive Bus Error Interrupt */
157
+#define REG_MISTA_RXBERR (1 << 11)
158
+/* Receive Descriptor Unavailable Interrupt */
159
+#define REG_MISTA_RDU (1 << 10)
160
+/* DMA Early Notification Interrupt */
161
+#define REG_MISTA_DENI (1 << 9)
162
+/* Maximum Frame Length Interrupt */
163
+#define REG_MISTA_DFOI (1 << 8)
164
+/* Receive Good Interrupt */
165
+#define REG_MISTA_RXGD (1 << 4)
166
+/* Packet Too Long Interrupt */
167
+#define REG_MISTA_PTLE (1 << 3)
168
+/* Receive Interrupt */
169
+#define REG_MISTA_RXINTR (1 << 0)
170
+
171
+/* REG_MGSTA fields */
172
+/* Transmission Halted */
173
+#define REG_MGSTA_TXHA (1 << 11)
174
+/* Receive Halted */
175
+#define REG_MGSTA_RXHA (1 << 11)
176
+
177
+/* REG_DMARFC fields */
178
+/* Maximum Receive Frame Length */
179
+#define REG_DMARFC_RXMS(word) extract32((word), 0, 16)
180
+
181
+/* REG MIIDA fields */
182
+/* Busy Bit */
183
+#define REG_MIIDA_BUSY (1 << 17)
184
+
185
+/* Transmit and receive descriptors */
186
+typedef struct NPCM7xxEMCTxDesc NPCM7xxEMCTxDesc;
187
+typedef struct NPCM7xxEMCRxDesc NPCM7xxEMCRxDesc;
188
+
189
+struct NPCM7xxEMCTxDesc {
190
+ uint32_t flags;
191
+ uint32_t txbsa;
192
+ uint32_t status_and_length;
193
+ uint32_t ntxdsa;
194
+};
195
+
196
+struct NPCM7xxEMCRxDesc {
197
+ uint32_t status_and_length;
198
+ uint32_t rxbsa;
199
+ uint32_t reserved;
200
+ uint32_t nrxdsa;
201
+};
202
+
203
+/* NPCM7xxEMCTxDesc.flags values */
204
+/* Owner: 0 = cpu, 1 = emc */
205
+#define TX_DESC_FLAG_OWNER_MASK (1 << 31)
206
+/* Transmit interrupt enable */
207
+#define TX_DESC_FLAG_INTEN (1 << 2)
208
+/* CRC append */
209
+#define TX_DESC_FLAG_CRCAPP (1 << 1)
210
+/* Padding enable */
211
+#define TX_DESC_FLAG_PADEN (1 << 0)
212
+
213
+/* NPCM7xxEMCTxDesc.status_and_length values */
214
+/* Collision count */
215
+#define TX_DESC_STATUS_CCNT_SHIFT 28
216
+#define TX_DESC_STATUS_CCNT_BITSIZE 4
217
+/* SQE error */
218
+#define TX_DESC_STATUS_SQE (1 << 26)
219
+/* Transmission paused */
220
+#define TX_DESC_STATUS_PAU (1 << 25)
221
+/* P transmission halted */
222
+#define TX_DESC_STATUS_TXHA (1 << 24)
223
+/* Late collision */
224
+#define TX_DESC_STATUS_LC (1 << 23)
225
+/* Transmission abort */
226
+#define TX_DESC_STATUS_TXABT (1 << 22)
227
+/* No carrier sense */
228
+#define TX_DESC_STATUS_NCS (1 << 21)
229
+/* Defer exceed */
230
+#define TX_DESC_STATUS_EXDEF (1 << 20)
231
+/* Transmission complete */
232
+#define TX_DESC_STATUS_TXCP (1 << 19)
233
+/* Transmission deferred */
234
+#define TX_DESC_STATUS_DEF (1 << 17)
235
+/* Transmit interrupt */
236
+#define TX_DESC_STATUS_TXINTR (1 << 16)
237
+
238
+#define TX_DESC_PKT_LEN(word) extract32((word), 0, 16)
239
+
240
+/* Transmit buffer start address */
241
+#define TX_DESC_TXBSA(word) ((uint32_t) (word) & ~3u)
242
+
243
+/* Next transmit descriptor start address */
244
+#define TX_DESC_NTXDSA(word) ((uint32_t) (word) & ~3u)
245
+
246
+/* NPCM7xxEMCRxDesc.status_and_length values */
247
+/* Owner: 0b00 = cpu, 0b01 = undefined, 0b10 = emc, 0b11 = undefined */
248
+#define RX_DESC_STATUS_OWNER_SHIFT 30
249
+#define RX_DESC_STATUS_OWNER_BITSIZE 2
250
+#define RX_DESC_STATUS_OWNER_MASK (3 << RX_DESC_STATUS_OWNER_SHIFT)
251
+/* Runt packet */
252
+#define RX_DESC_STATUS_RP (1 << 22)
253
+/* Alignment error */
254
+#define RX_DESC_STATUS_ALIE (1 << 21)
255
+/* Frame reception complete */
256
+#define RX_DESC_STATUS_RXGD (1 << 20)
257
+/* Packet too long */
258
+#define RX_DESC_STATUS_PTLE (1 << 19)
259
+/* CRC error */
260
+#define RX_DESC_STATUS_CRCE (1 << 17)
261
+/* Receive interrupt */
262
+#define RX_DESC_STATUS_RXINTR (1 << 16)
263
+
264
+#define RX_DESC_PKT_LEN(word) extract32((word), 0, 16)
265
+
266
+/* Receive buffer start address */
267
+#define RX_DESC_RXBSA(word) ((uint32_t) (word) & ~3u)
268
+
269
+/* Next receive descriptor start address */
270
+#define RX_DESC_NRXDSA(word) ((uint32_t) (word) & ~3u)
271
+
272
+/* Minimum packet length, when TX_DESC_FLAG_PADEN is set. */
273
+#define MIN_PACKET_LENGTH 64
274
+
275
+struct NPCM7xxEMCState {
276
+ /*< private >*/
277
+ SysBusDevice parent;
278
+ /*< public >*/
279
+
280
+ MemoryRegion iomem;
281
+
282
+ qemu_irq tx_irq;
283
+ qemu_irq rx_irq;
284
+
285
+ NICState *nic;
286
+ NICConf conf;
287
+
288
+ /* 0 or 1, for log messages */
289
+ uint8_t emc_num;
290
+
291
+ uint32_t regs[NPCM7XX_NUM_EMC_REGS];
292
+
293
+ /*
294
+ * tx is active. Set to true by TSDR and then switches off when out of
295
+ * descriptors. If the TXON bit in REG_MCMDR is off then this is off.
296
+ */
297
+ bool tx_active;
298
+
299
+ /*
300
+ * rx is active. Set to true by RSDR and then switches off when out of
301
+ * descriptors. If the RXON bit in REG_MCMDR is off then this is off.
302
+ */
303
+ bool rx_active;
304
+};
305
+
306
+typedef struct NPCM7xxEMCState NPCM7xxEMCState;
307
+
308
+#define TYPE_NPCM7XX_EMC "npcm7xx-emc"
309
+#define NPCM7XX_EMC(obj) \
310
+ OBJECT_CHECK(NPCM7xxEMCState, (obj), TYPE_NPCM7XX_EMC)
311
+
312
+#endif /* NPCM7XX_EMC_H */
313
diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c
314
new file mode 100644
77
new file mode 100644
315
index XXXXXXX..XXXXXXX
78
index XXXXXXX..XXXXXXX
316
--- /dev/null
79
--- /dev/null
317
+++ b/hw/net/npcm7xx_emc.c
80
+++ b/target/arm/translate-sme.c
318
@@ -XXX,XX +XXX,XX @@
81
@@ -XXX,XX +XXX,XX @@
319
+/*
82
+/*
320
+ * Nuvoton NPCM7xx EMC Module
83
+ * AArch64 SME translation
321
+ *
84
+ *
322
+ * Copyright 2020 Google LLC
85
+ * Copyright (c) 2022 Linaro, Ltd
323
+ *
86
+ *
324
+ * This program is free software; you can redistribute it and/or modify it
87
+ * This library is free software; you can redistribute it and/or
325
+ * under the terms of the GNU General Public License as published by the
88
+ * modify it under the terms of the GNU Lesser General Public
326
+ * Free Software Foundation; either version 2 of the License, or
89
+ * License as published by the Free Software Foundation; either
327
+ * (at your option) any later version.
90
+ * version 2.1 of the License, or (at your option) any later version.
328
+ *
91
+ *
329
+ * This program is distributed in the hope that it will be useful, but WITHOUT
92
+ * This library is distributed in the hope that it will be useful,
330
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
93
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
331
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
94
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
332
+ * for more details.
95
+ * Lesser General Public License for more details.
333
+ *
96
+ *
334
+ * Unsupported/unimplemented features:
97
+ * You should have received a copy of the GNU Lesser General Public
335
+ * - MCMDR.FDUP (full duplex) is ignored, half duplex is not supported
98
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
336
+ * - Only CAM0 is supported, CAM[1-15] are not
337
+ * - writes to CAMEN.[1-15] are ignored, these bits always read as zeroes
338
+ * - MII is not implemented, MIIDA.BUSY and MIID always return zero
339
+ * - MCMDR.LBK is not implemented
340
+ * - MCMDR.{OPMOD,ENSQE,AEP,ARP} are not supported
341
+ * - H/W FIFOs are not supported, MCMDR.FFTCR is ignored
342
+ * - MGSTA.SQE is not supported
343
+ * - pause and control frames are not implemented
344
+ * - MGSTA.CCNT is not supported
345
+ * - MPCNT, DMARFS are not implemented
346
+ */
99
+ */
347
+
100
+
348
+#include "qemu/osdep.h"
101
+#include "qemu/osdep.h"
102
+#include "cpu.h"
103
+#include "tcg/tcg-op.h"
104
+#include "tcg/tcg-op-gvec.h"
105
+#include "tcg/tcg-gvec-desc.h"
106
+#include "translate.h"
107
+#include "exec/helper-gen.h"
108
+#include "translate-a64.h"
109
+#include "fpu/softfloat.h"
349
+
110
+
350
+/* For crc32 */
351
+#include <zlib.h>
352
+
353
+#include "qemu-common.h"
354
+#include "hw/irq.h"
355
+#include "hw/qdev-clock.h"
356
+#include "hw/qdev-properties.h"
357
+#include "hw/net/npcm7xx_emc.h"
358
+#include "net/eth.h"
359
+#include "migration/vmstate.h"
360
+#include "qemu/bitops.h"
361
+#include "qemu/error-report.h"
362
+#include "qemu/log.h"
363
+#include "qemu/module.h"
364
+#include "qemu/units.h"
365
+#include "sysemu/dma.h"
366
+#include "trace.h"
367
+
368
+#define CRC_LENGTH 4
369
+
111
+
370
+/*
112
+/*
371
+ * The maximum size of a (layer 2) ethernet frame as defined by 802.3.
113
+ * Include the generated decoder.
372
+ * 1518 = 6(dest macaddr) + 6(src macaddr) + 2(proto) + 4(crc) + 1500(payload)
373
+ * This does not include an additional 4 for the vlan field (802.1q).
374
+ */
114
+ */
375
+#define MAX_ETH_FRAME_SIZE 1518
376
+
115
+
377
+static const char *emc_reg_name(int regno)
116
+#include "decode-sme.c.inc"
378
+{
117
diff --git a/target/arm/meson.build b/target/arm/meson.build
379
+#define REG(name) case REG_ ## name: return #name;
380
+ switch (regno) {
381
+ REG(CAMCMR)
382
+ REG(CAMEN)
383
+ REG(TXDLSA)
384
+ REG(RXDLSA)
385
+ REG(MCMDR)
386
+ REG(MIID)
387
+ REG(MIIDA)
388
+ REG(FFTCR)
389
+ REG(TSDR)
390
+ REG(RSDR)
391
+ REG(DMARFC)
392
+ REG(MIEN)
393
+ REG(MISTA)
394
+ REG(MGSTA)
395
+ REG(MPCNT)
396
+ REG(MRPC)
397
+ REG(MRPCC)
398
+ REG(MREPC)
399
+ REG(DMARFS)
400
+ REG(CTXDSA)
401
+ REG(CTXBSA)
402
+ REG(CRXDSA)
403
+ REG(CRXBSA)
404
+ case REG_CAMM_BASE + 0: return "CAM0M";
405
+ case REG_CAML_BASE + 0: return "CAM0L";
406
+ case REG_CAMM_BASE + 2 ... REG_CAMML_LAST:
407
+ /* Only CAM0 is supported, fold the others into something simple. */
408
+ if (regno & 1) {
409
+ return "CAM<n>L";
410
+ } else {
411
+ return "CAM<n>M";
412
+ }
413
+ default: return "UNKNOWN";
414
+ }
415
+#undef REG
416
+}
417
+
418
+static void emc_reset(NPCM7xxEMCState *emc)
419
+{
420
+ trace_npcm7xx_emc_reset(emc->emc_num);
421
+
422
+ memset(&emc->regs[0], 0, sizeof(emc->regs));
423
+
424
+ /* These regs have non-zero reset values. */
425
+ emc->regs[REG_TXDLSA] = 0xfffffffc;
426
+ emc->regs[REG_RXDLSA] = 0xfffffffc;
427
+ emc->regs[REG_MIIDA] = 0x00900000;
428
+ emc->regs[REG_FFTCR] = 0x0101;
429
+ emc->regs[REG_DMARFC] = 0x0800;
430
+ emc->regs[REG_MPCNT] = 0x7fff;
431
+
432
+ emc->tx_active = false;
433
+ emc->rx_active = false;
434
+}
435
+
436
+static void npcm7xx_emc_reset(DeviceState *dev)
437
+{
438
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(dev);
439
+ emc_reset(emc);
440
+}
441
+
442
+static void emc_soft_reset(NPCM7xxEMCState *emc)
443
+{
444
+ /*
445
+ * The docs say at least MCMDR.{LBK,OPMOD} bits are not changed during a
446
+ * soft reset, but does not go into further detail. For now, KISS.
447
+ */
448
+ uint32_t mcmdr = emc->regs[REG_MCMDR];
449
+ emc_reset(emc);
450
+ emc->regs[REG_MCMDR] = mcmdr & (REG_MCMDR_LBK | REG_MCMDR_OPMOD);
451
+
452
+ qemu_set_irq(emc->tx_irq, 0);
453
+ qemu_set_irq(emc->rx_irq, 0);
454
+}
455
+
456
+static void emc_set_link(NetClientState *nc)
457
+{
458
+ /* Nothing to do yet. */
459
+}
460
+
461
+/* MISTA.TXINTR is the union of the individual bits with their enables. */
462
+static void emc_update_mista_txintr(NPCM7xxEMCState *emc)
463
+{
464
+ /* Only look at the bits we support. */
465
+ uint32_t mask = (REG_MISTA_TXBERR |
466
+ REG_MISTA_TDU |
467
+ REG_MISTA_TXCP);
468
+ if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & mask) {
469
+ emc->regs[REG_MISTA] |= REG_MISTA_TXINTR;
470
+ } else {
471
+ emc->regs[REG_MISTA] &= ~REG_MISTA_TXINTR;
472
+ }
473
+}
474
+
475
+/* MISTA.RXINTR is the union of the individual bits with their enables. */
476
+static void emc_update_mista_rxintr(NPCM7xxEMCState *emc)
477
+{
478
+ /* Only look at the bits we support. */
479
+ uint32_t mask = (REG_MISTA_RXBERR |
480
+ REG_MISTA_RDU |
481
+ REG_MISTA_RXGD);
482
+ if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & mask) {
483
+ emc->regs[REG_MISTA] |= REG_MISTA_RXINTR;
484
+ } else {
485
+ emc->regs[REG_MISTA] &= ~REG_MISTA_RXINTR;
486
+ }
487
+}
488
+
489
+/* N.B. emc_update_mista_txintr must have already been called. */
490
+static void emc_update_tx_irq(NPCM7xxEMCState *emc)
491
+{
492
+ int level = !!(emc->regs[REG_MISTA] &
493
+ emc->regs[REG_MIEN] &
494
+ REG_MISTA_TXINTR);
495
+ trace_npcm7xx_emc_update_tx_irq(level);
496
+ qemu_set_irq(emc->tx_irq, level);
497
+}
498
+
499
+/* N.B. emc_update_mista_rxintr must have already been called. */
500
+static void emc_update_rx_irq(NPCM7xxEMCState *emc)
501
+{
502
+ int level = !!(emc->regs[REG_MISTA] &
503
+ emc->regs[REG_MIEN] &
504
+ REG_MISTA_RXINTR);
505
+ trace_npcm7xx_emc_update_rx_irq(level);
506
+ qemu_set_irq(emc->rx_irq, level);
507
+}
508
+
509
+/* Update IRQ states due to changes in MIEN,MISTA. */
510
+static void emc_update_irq_from_reg_change(NPCM7xxEMCState *emc)
511
+{
512
+ emc_update_mista_txintr(emc);
513
+ emc_update_tx_irq(emc);
514
+
515
+ emc_update_mista_rxintr(emc);
516
+ emc_update_rx_irq(emc);
517
+}
518
+
519
+static int emc_read_tx_desc(dma_addr_t addr, NPCM7xxEMCTxDesc *desc)
520
+{
521
+ if (dma_memory_read(&address_space_memory, addr, desc, sizeof(*desc))) {
522
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read descriptor @ 0x%"
523
+ HWADDR_PRIx "\n", __func__, addr);
524
+ return -1;
525
+ }
526
+ desc->flags = le32_to_cpu(desc->flags);
527
+ desc->txbsa = le32_to_cpu(desc->txbsa);
528
+ desc->status_and_length = le32_to_cpu(desc->status_and_length);
529
+ desc->ntxdsa = le32_to_cpu(desc->ntxdsa);
530
+ return 0;
531
+}
532
+
533
+static int emc_write_tx_desc(const NPCM7xxEMCTxDesc *desc, dma_addr_t addr)
534
+{
535
+ NPCM7xxEMCTxDesc le_desc;
536
+
537
+ le_desc.flags = cpu_to_le32(desc->flags);
538
+ le_desc.txbsa = cpu_to_le32(desc->txbsa);
539
+ le_desc.status_and_length = cpu_to_le32(desc->status_and_length);
540
+ le_desc.ntxdsa = cpu_to_le32(desc->ntxdsa);
541
+ if (dma_memory_write(&address_space_memory, addr, &le_desc,
542
+ sizeof(le_desc))) {
543
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to write descriptor @ 0x%"
544
+ HWADDR_PRIx "\n", __func__, addr);
545
+ return -1;
546
+ }
547
+ return 0;
548
+}
549
+
550
+static int emc_read_rx_desc(dma_addr_t addr, NPCM7xxEMCRxDesc *desc)
551
+{
552
+ if (dma_memory_read(&address_space_memory, addr, desc, sizeof(*desc))) {
553
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read descriptor @ 0x%"
554
+ HWADDR_PRIx "\n", __func__, addr);
555
+ return -1;
556
+ }
557
+ desc->status_and_length = le32_to_cpu(desc->status_and_length);
558
+ desc->rxbsa = le32_to_cpu(desc->rxbsa);
559
+ desc->reserved = le32_to_cpu(desc->reserved);
560
+ desc->nrxdsa = le32_to_cpu(desc->nrxdsa);
561
+ return 0;
562
+}
563
+
564
+static int emc_write_rx_desc(const NPCM7xxEMCRxDesc *desc, dma_addr_t addr)
565
+{
566
+ NPCM7xxEMCRxDesc le_desc;
567
+
568
+ le_desc.status_and_length = cpu_to_le32(desc->status_and_length);
569
+ le_desc.rxbsa = cpu_to_le32(desc->rxbsa);
570
+ le_desc.reserved = cpu_to_le32(desc->reserved);
571
+ le_desc.nrxdsa = cpu_to_le32(desc->nrxdsa);
572
+ if (dma_memory_write(&address_space_memory, addr, &le_desc,
573
+ sizeof(le_desc))) {
574
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to write descriptor @ 0x%"
575
+ HWADDR_PRIx "\n", __func__, addr);
576
+ return -1;
577
+ }
578
+ return 0;
579
+}
580
+
581
+static void emc_set_mista(NPCM7xxEMCState *emc, uint32_t flags)
582
+{
583
+ trace_npcm7xx_emc_set_mista(flags);
584
+ emc->regs[REG_MISTA] |= flags;
585
+ if (extract32(flags, 16, 16)) {
586
+ emc_update_mista_txintr(emc);
587
+ }
588
+ if (extract32(flags, 0, 16)) {
589
+ emc_update_mista_rxintr(emc);
590
+ }
591
+}
592
+
593
+static void emc_halt_tx(NPCM7xxEMCState *emc, uint32_t mista_flag)
594
+{
595
+ emc->tx_active = false;
596
+ emc_set_mista(emc, mista_flag);
597
+}
598
+
599
+static void emc_halt_rx(NPCM7xxEMCState *emc, uint32_t mista_flag)
600
+{
601
+ emc->rx_active = false;
602
+ emc_set_mista(emc, mista_flag);
603
+}
604
+
605
+static void emc_set_next_tx_descriptor(NPCM7xxEMCState *emc,
606
+ const NPCM7xxEMCTxDesc *tx_desc,
607
+ uint32_t desc_addr)
608
+{
609
+ /* Update the current descriptor, if only to reset the owner flag. */
610
+ if (emc_write_tx_desc(tx_desc, desc_addr)) {
611
+ /*
612
+ * We just read it so this shouldn't generally happen.
613
+ * Error already reported.
614
+ */
615
+ emc_set_mista(emc, REG_MISTA_TXBERR);
616
+ }
617
+ emc->regs[REG_CTXDSA] = TX_DESC_NTXDSA(tx_desc->ntxdsa);
618
+}
619
+
620
+static void emc_set_next_rx_descriptor(NPCM7xxEMCState *emc,
621
+ const NPCM7xxEMCRxDesc *rx_desc,
622
+ uint32_t desc_addr)
623
+{
624
+ /* Update the current descriptor, if only to reset the owner flag. */
625
+ if (emc_write_rx_desc(rx_desc, desc_addr)) {
626
+ /*
627
+ * We just read it so this shouldn't generally happen.
628
+ * Error already reported.
629
+ */
630
+ emc_set_mista(emc, REG_MISTA_RXBERR);
631
+ }
632
+ emc->regs[REG_CRXDSA] = RX_DESC_NRXDSA(rx_desc->nrxdsa);
633
+}
634
+
635
+static void emc_try_send_next_packet(NPCM7xxEMCState *emc)
636
+{
637
+ /* Working buffer for sending out packets. Most packets fit in this. */
638
+#define TX_BUFFER_SIZE 2048
639
+ uint8_t tx_send_buffer[TX_BUFFER_SIZE];
640
+ uint32_t desc_addr = TX_DESC_NTXDSA(emc->regs[REG_CTXDSA]);
641
+ NPCM7xxEMCTxDesc tx_desc;
642
+ uint32_t next_buf_addr, length;
643
+ uint8_t *buf;
644
+ g_autofree uint8_t *malloced_buf = NULL;
645
+
646
+ if (emc_read_tx_desc(desc_addr, &tx_desc)) {
647
+ /* Error reading descriptor, already reported. */
648
+ emc_halt_tx(emc, REG_MISTA_TXBERR);
649
+ emc_update_tx_irq(emc);
650
+ return;
651
+ }
652
+
653
+ /* Nothing we can do if we don't own the descriptor. */
654
+ if (!(tx_desc.flags & TX_DESC_FLAG_OWNER_MASK)) {
655
+ trace_npcm7xx_emc_cpu_owned_desc(desc_addr);
656
+ emc_halt_tx(emc, REG_MISTA_TDU);
657
+ emc_update_tx_irq(emc);
658
+ return;
659
+ }
660
+
661
+ /* Give the descriptor back regardless of what happens. */
662
+ tx_desc.flags &= ~TX_DESC_FLAG_OWNER_MASK;
663
+ tx_desc.status_and_length &= 0xffff;
664
+
665
+ /*
666
+ * Despite the h/w documentation saying the tx buffer is word aligned,
667
+ * the linux driver does not word align the buffer. There is value in not
668
+ * aligning the buffer: See the description of NET_IP_ALIGN in linux
669
+ * kernel sources.
670
+ */
671
+ next_buf_addr = tx_desc.txbsa;
672
+ emc->regs[REG_CTXBSA] = next_buf_addr;
673
+ length = TX_DESC_PKT_LEN(tx_desc.status_and_length);
674
+ buf = &tx_send_buffer[0];
675
+
676
+ if (length > sizeof(tx_send_buffer)) {
677
+ malloced_buf = g_malloc(length);
678
+ buf = malloced_buf;
679
+ }
680
+
681
+ if (dma_memory_read(&address_space_memory, next_buf_addr, buf, length)) {
682
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read packet @ 0x%x\n",
683
+ __func__, next_buf_addr);
684
+ emc_set_mista(emc, REG_MISTA_TXBERR);
685
+ emc_set_next_tx_descriptor(emc, &tx_desc, desc_addr);
686
+ emc_update_tx_irq(emc);
687
+ trace_npcm7xx_emc_tx_done(emc->regs[REG_CTXDSA]);
688
+ return;
689
+ }
690
+
691
+ if ((tx_desc.flags & TX_DESC_FLAG_PADEN) && (length < MIN_PACKET_LENGTH)) {
692
+ memset(buf + length, 0, MIN_PACKET_LENGTH - length);
693
+ length = MIN_PACKET_LENGTH;
694
+ }
695
+
696
+ /* N.B. emc_receive can get called here. */
697
+ qemu_send_packet(qemu_get_queue(emc->nic), buf, length);
698
+ trace_npcm7xx_emc_sent_packet(length);
699
+
700
+ tx_desc.status_and_length |= TX_DESC_STATUS_TXCP;
701
+ if (tx_desc.flags & TX_DESC_FLAG_INTEN) {
702
+ emc_set_mista(emc, REG_MISTA_TXCP);
703
+ }
704
+ if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & REG_MISTA_TXINTR) {
705
+ tx_desc.status_and_length |= TX_DESC_STATUS_TXINTR;
706
+ }
707
+
708
+ emc_set_next_tx_descriptor(emc, &tx_desc, desc_addr);
709
+ emc_update_tx_irq(emc);
710
+ trace_npcm7xx_emc_tx_done(emc->regs[REG_CTXDSA]);
711
+}
712
+
713
+static bool emc_can_receive(NetClientState *nc)
714
+{
715
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(qemu_get_nic_opaque(nc));
716
+
717
+ bool can_receive = emc->rx_active;
718
+ trace_npcm7xx_emc_can_receive(can_receive);
719
+ return can_receive;
720
+}
721
+
722
+/* If result is false then *fail_reason contains the reason. */
723
+static bool emc_receive_filter1(NPCM7xxEMCState *emc, const uint8_t *buf,
724
+ size_t len, const char **fail_reason)
725
+{
726
+ eth_pkt_types_e pkt_type = get_eth_packet_type(PKT_GET_ETH_HDR(buf));
727
+
728
+ switch (pkt_type) {
729
+ case ETH_PKT_BCAST:
730
+ if (emc->regs[REG_CAMCMR] & REG_CAMCMR_CCAM) {
731
+ return true;
732
+ } else {
733
+ *fail_reason = "Broadcast packet disabled";
734
+ return !!(emc->regs[REG_CAMCMR] & REG_CAMCMR_ABP);
735
+ }
736
+ case ETH_PKT_MCAST:
737
+ if (emc->regs[REG_CAMCMR] & REG_CAMCMR_CCAM) {
738
+ return true;
739
+ } else {
740
+ *fail_reason = "Multicast packet disabled";
741
+ return !!(emc->regs[REG_CAMCMR] & REG_CAMCMR_AMP);
742
+ }
743
+ case ETH_PKT_UCAST: {
744
+ bool matches;
745
+ if (emc->regs[REG_CAMCMR] & REG_CAMCMR_AUP) {
746
+ return true;
747
+ }
748
+ matches = ((emc->regs[REG_CAMCMR] & REG_CAMCMR_ECMP) &&
749
+ /* We only support one CAM register, CAM0. */
750
+ (emc->regs[REG_CAMEN] & (1 << 0)) &&
751
+ memcmp(buf, emc->conf.macaddr.a, ETH_ALEN) == 0);
752
+ if (emc->regs[REG_CAMCMR] & REG_CAMCMR_CCAM) {
753
+ *fail_reason = "MACADDR matched, comparison complemented";
754
+ return !matches;
755
+ } else {
756
+ *fail_reason = "MACADDR didn't match";
757
+ return matches;
758
+ }
759
+ }
760
+ default:
761
+ g_assert_not_reached();
762
+ }
763
+}
764
+
765
+static bool emc_receive_filter(NPCM7xxEMCState *emc, const uint8_t *buf,
766
+ size_t len)
767
+{
768
+ const char *fail_reason = NULL;
769
+ bool ok = emc_receive_filter1(emc, buf, len, &fail_reason);
770
+ if (!ok) {
771
+ trace_npcm7xx_emc_packet_filtered_out(fail_reason);
772
+ }
773
+ return ok;
774
+}
775
+
776
+static ssize_t emc_receive(NetClientState *nc, const uint8_t *buf, size_t len1)
777
+{
778
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(qemu_get_nic_opaque(nc));
779
+ const uint32_t len = len1;
780
+ size_t max_frame_len;
781
+ bool long_frame;
782
+ uint32_t desc_addr;
783
+ NPCM7xxEMCRxDesc rx_desc;
784
+ uint32_t crc;
785
+ uint8_t *crc_ptr;
786
+ uint32_t buf_addr;
787
+
788
+ trace_npcm7xx_emc_receiving_packet(len);
789
+
790
+ if (!emc_can_receive(nc)) {
791
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Unexpected packet\n", __func__);
792
+ return -1;
793
+ }
794
+
795
+ if (len < ETH_HLEN ||
796
+ /* Defensive programming: drop unsupportable large packets. */
797
+ len > 0xffff - CRC_LENGTH) {
798
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Dropped frame of %u bytes\n",
799
+ __func__, len);
800
+ return len;
801
+ }
802
+
803
+ /*
804
+ * DENI is set if EMC received the Length/Type field of the incoming
805
+ * packet, so it will be set regardless of what happens next.
806
+ */
807
+ emc_set_mista(emc, REG_MISTA_DENI);
808
+
809
+ if (!emc_receive_filter(emc, buf, len)) {
810
+ emc_update_rx_irq(emc);
811
+ return len;
812
+ }
813
+
814
+ /* Huge frames (> DMARFC) are dropped. */
815
+ max_frame_len = REG_DMARFC_RXMS(emc->regs[REG_DMARFC]);
816
+ if (len + CRC_LENGTH > max_frame_len) {
817
+ trace_npcm7xx_emc_packet_dropped(len);
818
+ emc_set_mista(emc, REG_MISTA_DFOI);
819
+ emc_update_rx_irq(emc);
820
+ return len;
821
+ }
822
+
823
+ /*
824
+ * Long Frames (> MAX_ETH_FRAME_SIZE) are also dropped, unless MCMDR.ALP
825
+ * is set.
826
+ */
827
+ long_frame = false;
828
+ if (len + CRC_LENGTH > MAX_ETH_FRAME_SIZE) {
829
+ if (emc->regs[REG_MCMDR] & REG_MCMDR_ALP) {
830
+ long_frame = true;
831
+ } else {
832
+ trace_npcm7xx_emc_packet_dropped(len);
833
+ emc_set_mista(emc, REG_MISTA_PTLE);
834
+ emc_update_rx_irq(emc);
835
+ return len;
836
+ }
837
+ }
838
+
839
+ desc_addr = RX_DESC_NRXDSA(emc->regs[REG_CRXDSA]);
840
+ if (emc_read_rx_desc(desc_addr, &rx_desc)) {
841
+ /* Error reading descriptor, already reported. */
842
+ emc_halt_rx(emc, REG_MISTA_RXBERR);
843
+ emc_update_rx_irq(emc);
844
+ return len;
845
+ }
846
+
847
+ /* Nothing we can do if we don't own the descriptor. */
848
+ if (!(rx_desc.status_and_length & RX_DESC_STATUS_OWNER_MASK)) {
849
+ trace_npcm7xx_emc_cpu_owned_desc(desc_addr);
850
+ emc_halt_rx(emc, REG_MISTA_RDU);
851
+ emc_update_rx_irq(emc);
852
+ return len;
853
+ }
854
+
855
+ crc = 0;
856
+ crc_ptr = (uint8_t *) &crc;
857
+ if (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC)) {
858
+ crc = cpu_to_be32(crc32(~0, buf, len));
859
+ }
860
+
861
+ /* Give the descriptor back regardless of what happens. */
862
+ rx_desc.status_and_length &= ~RX_DESC_STATUS_OWNER_MASK;
863
+
864
+ buf_addr = rx_desc.rxbsa;
865
+ emc->regs[REG_CRXBSA] = buf_addr;
866
+ if (dma_memory_write(&address_space_memory, buf_addr, buf, len) ||
867
+ (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC) &&
868
+ dma_memory_write(&address_space_memory, buf_addr + len, crc_ptr,
869
+ 4))) {
870
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bus error writing packet\n",
871
+ __func__);
872
+ emc_set_mista(emc, REG_MISTA_RXBERR);
873
+ emc_set_next_rx_descriptor(emc, &rx_desc, desc_addr);
874
+ emc_update_rx_irq(emc);
875
+ trace_npcm7xx_emc_rx_done(emc->regs[REG_CRXDSA]);
876
+ return len;
877
+ }
878
+
879
+ trace_npcm7xx_emc_received_packet(len);
880
+
881
+ /* Note: We've already verified len+4 <= 0xffff. */
882
+ rx_desc.status_and_length = len;
883
+ if (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC)) {
884
+ rx_desc.status_and_length += 4;
885
+ }
886
+ rx_desc.status_and_length |= RX_DESC_STATUS_RXGD;
887
+ emc_set_mista(emc, REG_MISTA_RXGD);
888
+
889
+ if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & REG_MISTA_RXINTR) {
890
+ rx_desc.status_and_length |= RX_DESC_STATUS_RXINTR;
891
+ }
892
+ if (long_frame) {
893
+ rx_desc.status_and_length |= RX_DESC_STATUS_PTLE;
894
+ }
895
+
896
+ emc_set_next_rx_descriptor(emc, &rx_desc, desc_addr);
897
+ emc_update_rx_irq(emc);
898
+ trace_npcm7xx_emc_rx_done(emc->regs[REG_CRXDSA]);
899
+ return len;
900
+}
901
+
902
+static void emc_try_receive_next_packet(NPCM7xxEMCState *emc)
903
+{
904
+ if (emc_can_receive(qemu_get_queue(emc->nic))) {
905
+ qemu_flush_queued_packets(qemu_get_queue(emc->nic));
906
+ }
907
+}
908
+
909
+static uint64_t npcm7xx_emc_read(void *opaque, hwaddr offset, unsigned size)
910
+{
911
+ NPCM7xxEMCState *emc = opaque;
912
+ uint32_t reg = offset / sizeof(uint32_t);
913
+ uint32_t result;
914
+
915
+ if (reg >= NPCM7XX_NUM_EMC_REGS) {
916
+ qemu_log_mask(LOG_GUEST_ERROR,
917
+ "%s: Invalid offset 0x%04" HWADDR_PRIx "\n",
918
+ __func__, offset);
919
+ return 0;
920
+ }
921
+
922
+ switch (reg) {
923
+ case REG_MIID:
924
+ /*
925
+ * We don't implement MII. For determinism, always return zero as
926
+ * writes record the last value written for debugging purposes.
927
+ */
928
+ qemu_log_mask(LOG_UNIMP, "%s: Read of MIID, returning 0\n", __func__);
929
+ result = 0;
930
+ break;
931
+ case REG_TSDR:
932
+ case REG_RSDR:
933
+ qemu_log_mask(LOG_GUEST_ERROR,
934
+ "%s: Read of write-only reg, %s/%d\n",
935
+ __func__, emc_reg_name(reg), reg);
936
+ return 0;
937
+ default:
938
+ result = emc->regs[reg];
939
+ break;
940
+ }
941
+
942
+ trace_npcm7xx_emc_reg_read(emc->emc_num, result, emc_reg_name(reg), reg);
943
+ return result;
944
+}
945
+
946
+static void npcm7xx_emc_write(void *opaque, hwaddr offset,
947
+ uint64_t v, unsigned size)
948
+{
949
+ NPCM7xxEMCState *emc = opaque;
950
+ uint32_t reg = offset / sizeof(uint32_t);
951
+ uint32_t value = v;
952
+
953
+ g_assert(size == sizeof(uint32_t));
954
+
955
+ if (reg >= NPCM7XX_NUM_EMC_REGS) {
956
+ qemu_log_mask(LOG_GUEST_ERROR,
957
+ "%s: Invalid offset 0x%04" HWADDR_PRIx "\n",
958
+ __func__, offset);
959
+ return;
960
+ }
961
+
962
+ trace_npcm7xx_emc_reg_write(emc->emc_num, emc_reg_name(reg), reg, value);
963
+
964
+ switch (reg) {
965
+ case REG_CAMCMR:
966
+ emc->regs[reg] = value;
967
+ break;
968
+ case REG_CAMEN:
969
+ /* Only CAM0 is supported, don't pretend otherwise. */
970
+ if (value & ~1) {
971
+ qemu_log_mask(LOG_GUEST_ERROR,
972
+ "%s: Only CAM0 is supported, cannot enable others"
973
+ ": 0x%x\n",
974
+ __func__, value);
975
+ }
976
+ emc->regs[reg] = value & 1;
977
+ break;
978
+ case REG_CAMM_BASE + 0:
979
+ emc->regs[reg] = value;
980
+ emc->conf.macaddr.a[0] = value >> 24;
981
+ emc->conf.macaddr.a[1] = value >> 16;
982
+ emc->conf.macaddr.a[2] = value >> 8;
983
+ emc->conf.macaddr.a[3] = value >> 0;
984
+ break;
985
+ case REG_CAML_BASE + 0:
986
+ emc->regs[reg] = value;
987
+ emc->conf.macaddr.a[4] = value >> 24;
988
+ emc->conf.macaddr.a[5] = value >> 16;
989
+ break;
990
+ case REG_MCMDR: {
991
+ uint32_t prev;
992
+ if (value & REG_MCMDR_SWR) {
993
+ emc_soft_reset(emc);
994
+ /* On h/w the reset happens over multiple cycles. For now KISS. */
995
+ break;
996
+ }
997
+ prev = emc->regs[reg];
998
+ emc->regs[reg] = value;
999
+ /* Update tx state. */
1000
+ if (!(prev & REG_MCMDR_TXON) &&
1001
+ (value & REG_MCMDR_TXON)) {
1002
+ emc->regs[REG_CTXDSA] = emc->regs[REG_TXDLSA];
1003
+ /*
1004
+ * Linux kernel turns TX on with CPU still holding descriptor,
1005
+ * which suggests we should wait for a write to TSDR before trying
1006
+ * to send a packet: so we don't send one here.
1007
+ */
1008
+ } else if ((prev & REG_MCMDR_TXON) &&
1009
+ !(value & REG_MCMDR_TXON)) {
1010
+ emc->regs[REG_MGSTA] |= REG_MGSTA_TXHA;
1011
+ }
1012
+ if (!(value & REG_MCMDR_TXON)) {
1013
+ emc_halt_tx(emc, 0);
1014
+ }
1015
+ /* Update rx state. */
1016
+ if (!(prev & REG_MCMDR_RXON) &&
1017
+ (value & REG_MCMDR_RXON)) {
1018
+ emc->regs[REG_CRXDSA] = emc->regs[REG_RXDLSA];
1019
+ } else if ((prev & REG_MCMDR_RXON) &&
1020
+ !(value & REG_MCMDR_RXON)) {
1021
+ emc->regs[REG_MGSTA] |= REG_MGSTA_RXHA;
1022
+ }
1023
+ if (!(value & REG_MCMDR_RXON)) {
1024
+ emc_halt_rx(emc, 0);
1025
+ }
1026
+ break;
1027
+ }
1028
+ case REG_TXDLSA:
1029
+ case REG_RXDLSA:
1030
+ case REG_DMARFC:
1031
+ case REG_MIID:
1032
+ emc->regs[reg] = value;
1033
+ break;
1034
+ case REG_MIEN:
1035
+ emc->regs[reg] = value;
1036
+ emc_update_irq_from_reg_change(emc);
1037
+ break;
1038
+ case REG_MISTA:
1039
+ /* Clear the bits that have 1 in "value". */
1040
+ emc->regs[reg] &= ~value;
1041
+ emc_update_irq_from_reg_change(emc);
1042
+ break;
1043
+ case REG_MGSTA:
1044
+ /* Clear the bits that have 1 in "value". */
1045
+ emc->regs[reg] &= ~value;
1046
+ break;
1047
+ case REG_TSDR:
1048
+ if (emc->regs[REG_MCMDR] & REG_MCMDR_TXON) {
1049
+ emc->tx_active = true;
1050
+ /* Keep trying to send packets until we run out. */
1051
+ while (emc->tx_active) {
1052
+ emc_try_send_next_packet(emc);
1053
+ }
1054
+ }
1055
+ break;
1056
+ case REG_RSDR:
1057
+ if (emc->regs[REG_MCMDR] & REG_MCMDR_RXON) {
1058
+ emc->rx_active = true;
1059
+ emc_try_receive_next_packet(emc);
1060
+ }
1061
+ break;
1062
+ case REG_MIIDA:
1063
+ emc->regs[reg] = value & ~REG_MIIDA_BUSY;
1064
+ break;
1065
+ case REG_MRPC:
1066
+ case REG_MRPCC:
1067
+ case REG_MREPC:
1068
+ case REG_CTXDSA:
1069
+ case REG_CTXBSA:
1070
+ case REG_CRXDSA:
1071
+ case REG_CRXBSA:
1072
+ qemu_log_mask(LOG_GUEST_ERROR,
1073
+ "%s: Write to read-only reg %s/%d\n",
1074
+ __func__, emc_reg_name(reg), reg);
1075
+ break;
1076
+ default:
1077
+ qemu_log_mask(LOG_UNIMP, "%s: Write to unimplemented reg %s/%d\n",
1078
+ __func__, emc_reg_name(reg), reg);
1079
+ break;
1080
+ }
1081
+}
1082
+
1083
+static const struct MemoryRegionOps npcm7xx_emc_ops = {
1084
+ .read = npcm7xx_emc_read,
1085
+ .write = npcm7xx_emc_write,
1086
+ .endianness = DEVICE_LITTLE_ENDIAN,
1087
+ .valid = {
1088
+ .min_access_size = 4,
1089
+ .max_access_size = 4,
1090
+ .unaligned = false,
1091
+ },
1092
+};
1093
+
1094
+static void emc_cleanup(NetClientState *nc)
1095
+{
1096
+ /* Nothing to do yet. */
1097
+}
1098
+
1099
+static NetClientInfo net_npcm7xx_emc_info = {
1100
+ .type = NET_CLIENT_DRIVER_NIC,
1101
+ .size = sizeof(NICState),
1102
+ .can_receive = emc_can_receive,
1103
+ .receive = emc_receive,
1104
+ .cleanup = emc_cleanup,
1105
+ .link_status_changed = emc_set_link,
1106
+};
1107
+
1108
+static void npcm7xx_emc_realize(DeviceState *dev, Error **errp)
1109
+{
1110
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(dev);
1111
+ SysBusDevice *sbd = SYS_BUS_DEVICE(emc);
1112
+
1113
+ memory_region_init_io(&emc->iomem, OBJECT(emc), &npcm7xx_emc_ops, emc,
1114
+ TYPE_NPCM7XX_EMC, 4 * KiB);
1115
+ sysbus_init_mmio(sbd, &emc->iomem);
1116
+ sysbus_init_irq(sbd, &emc->tx_irq);
1117
+ sysbus_init_irq(sbd, &emc->rx_irq);
1118
+
1119
+ qemu_macaddr_default_if_unset(&emc->conf.macaddr);
1120
+ emc->nic = qemu_new_nic(&net_npcm7xx_emc_info, &emc->conf,
1121
+ object_get_typename(OBJECT(dev)), dev->id, emc);
1122
+ qemu_format_nic_info_str(qemu_get_queue(emc->nic), emc->conf.macaddr.a);
1123
+}
1124
+
1125
+static void npcm7xx_emc_unrealize(DeviceState *dev)
1126
+{
1127
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(dev);
1128
+
1129
+ qemu_del_nic(emc->nic);
1130
+}
1131
+
1132
+static const VMStateDescription vmstate_npcm7xx_emc = {
1133
+ .name = TYPE_NPCM7XX_EMC,
1134
+ .version_id = 0,
1135
+ .minimum_version_id = 0,
1136
+ .fields = (VMStateField[]) {
1137
+ VMSTATE_UINT8(emc_num, NPCM7xxEMCState),
1138
+ VMSTATE_UINT32_ARRAY(regs, NPCM7xxEMCState, NPCM7XX_NUM_EMC_REGS),
1139
+ VMSTATE_BOOL(tx_active, NPCM7xxEMCState),
1140
+ VMSTATE_BOOL(rx_active, NPCM7xxEMCState),
1141
+ VMSTATE_END_OF_LIST(),
1142
+ },
1143
+};
1144
+
1145
+static Property npcm7xx_emc_properties[] = {
1146
+ DEFINE_NIC_PROPERTIES(NPCM7xxEMCState, conf),
1147
+ DEFINE_PROP_END_OF_LIST(),
1148
+};
1149
+
1150
+static void npcm7xx_emc_class_init(ObjectClass *klass, void *data)
1151
+{
1152
+ DeviceClass *dc = DEVICE_CLASS(klass);
1153
+
1154
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
1155
+ dc->desc = "NPCM7xx EMC Controller";
1156
+ dc->realize = npcm7xx_emc_realize;
1157
+ dc->unrealize = npcm7xx_emc_unrealize;
1158
+ dc->reset = npcm7xx_emc_reset;
1159
+ dc->vmsd = &vmstate_npcm7xx_emc;
1160
+ device_class_set_props(dc, npcm7xx_emc_properties);
1161
+}
1162
+
1163
+static const TypeInfo npcm7xx_emc_info = {
1164
+ .name = TYPE_NPCM7XX_EMC,
1165
+ .parent = TYPE_SYS_BUS_DEVICE,
1166
+ .instance_size = sizeof(NPCM7xxEMCState),
1167
+ .class_init = npcm7xx_emc_class_init,
1168
+};
1169
+
1170
+static void npcm7xx_emc_register_type(void)
1171
+{
1172
+ type_register_static(&npcm7xx_emc_info);
1173
+}
1174
+
1175
+type_init(npcm7xx_emc_register_type)
1176
diff --git a/hw/net/meson.build b/hw/net/meson.build
1177
index XXXXXXX..XXXXXXX 100644
118
index XXXXXXX..XXXXXXX 100644
1178
--- a/hw/net/meson.build
119
--- a/target/arm/meson.build
1179
+++ b/hw/net/meson.build
120
+++ b/target/arm/meson.build
1180
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_I82596_COMMON', if_true: files('i82596.c'))
121
@@ -XXX,XX +XXX,XX @@
1181
softmmu_ss.add(when: 'CONFIG_SUNHME', if_true: files('sunhme.c'))
122
gen = [
1182
softmmu_ss.add(when: 'CONFIG_FTGMAC100', if_true: files('ftgmac100.c'))
123
decodetree.process('sve.decode', extra_args: '--decode=disas_sve'),
1183
softmmu_ss.add(when: 'CONFIG_SUNGEM', if_true: files('sungem.c'))
124
+ decodetree.process('sme.decode', extra_args: '--decode=disas_sme'),
1184
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c'))
125
decodetree.process('neon-shared.decode', extra_args: '--decode=disas_neon_shared'),
1185
126
decodetree.process('neon-dp.decode', extra_args: '--decode=disas_neon_dp'),
1186
softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_eth.c'))
127
decodetree.process('neon-ls.decode', extra_args: '--decode=disas_neon_ls'),
1187
softmmu_ss.add(when: 'CONFIG_COLDFIRE', if_true: files('mcf_fec.c'))
128
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
1188
diff --git a/hw/net/trace-events b/hw/net/trace-events
129
'sme_helper.c',
1189
index XXXXXXX..XXXXXXX 100644
130
'translate-a64.c',
1190
--- a/hw/net/trace-events
131
'translate-sve.c',
1191
+++ b/hw/net/trace-events
132
+ 'translate-sme.c',
1192
@@ -XXX,XX +XXX,XX @@ imx_fec_receive_last(int last) "rx frame flags 0x%04x"
133
))
1193
imx_enet_receive(size_t size) "len %zu"
134
1194
imx_enet_receive_len(uint64_t addr, int len) "rx_bd 0x%"PRIx64" length %d"
135
arm_softmmu_ss = ss.source_set()
1195
imx_enet_receive_last(int last) "rx frame flags 0x%04x"
1196
+
1197
+# npcm7xx_emc.c
1198
+npcm7xx_emc_reset(int emc_num) "Resetting emc%d"
1199
+npcm7xx_emc_update_tx_irq(int level) "Setting tx irq to %d"
1200
+npcm7xx_emc_update_rx_irq(int level) "Setting rx irq to %d"
1201
+npcm7xx_emc_set_mista(uint32_t flags) "ORing 0x%x into MISTA"
1202
+npcm7xx_emc_cpu_owned_desc(uint32_t addr) "Can't process cpu-owned descriptor @0x%x"
1203
+npcm7xx_emc_sent_packet(uint32_t len) "Sent %u byte packet"
1204
+npcm7xx_emc_tx_done(uint32_t ctxdsa) "TX done, CTXDSA=0x%x"
1205
+npcm7xx_emc_can_receive(int can_receive) "Can receive: %d"
1206
+npcm7xx_emc_packet_filtered_out(const char* fail_reason) "Packet filtered out: %s"
1207
+npcm7xx_emc_packet_dropped(uint32_t len) "%u byte packet dropped"
1208
+npcm7xx_emc_receiving_packet(uint32_t len) "Receiving %u byte packet"
1209
+npcm7xx_emc_received_packet(uint32_t len) "Received %u byte packet"
1210
+npcm7xx_emc_rx_done(uint32_t crxdsa) "RX done, CRXDSA=0x%x"
1211
+npcm7xx_emc_reg_read(int emc_num, uint32_t result, const char *name, int regno) "emc%d: 0x%x = reg[%s/%d]"
1212
+npcm7xx_emc_reg_write(int emc_num, const char *name, int regno, uint32_t value) "emc%d: reg[%s/%d] = 0x%x"
1213
--
136
--
1214
2.20.1
137
2.25.1
1215
1216
diff view generated by jsdifflib
1
From: Rebecca Cran <rebecca@nuviainc.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add support for FEAT_SSBS. SSBS (Speculative Store Bypass Safe) is an
3
This new behaviour is in the ARM pseudocode function
4
optional feature in ARMv8.0, and mandatory in ARMv8.5.
4
AArch64.CheckFPAdvSIMDEnabled, which applies to AArch32
5
5
via AArch32.CheckAdvSIMDOrFPEnabled when the EL to which
6
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
6
the trap would be delivered is in AArch64 mode.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
8
Message-id: 20210216224543.16142-2-rebecca@nuviainc.com
8
Given that ARMv9 drops support for AArch32 outside EL0, the trap EL
9
detection ought to be trivially true, but the pseudocode still contains
10
a number of conditions, and QEMU has not yet committed to dropping A32
11
support for EL[12] when v9 features are present.
12
13
Since the computation of SME_TRAP_NONSTREAMING is necessarily different
14
for the two modes, we might as well preserve bits within TBFLAG_ANY and
15
allocate separate bits within TBFLAG_A32 and TBFLAG_A64 instead.
16
17
Note that DDI0616A.a has typos for bits [22:21] of LD1RO in the table
18
of instructions illegal in streaming mode.
19
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
22
Message-id: 20220708151540.18136-4-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
24
---
11
target/arm/cpu.h | 15 ++++++++++++++-
25
target/arm/cpu.h | 7 +++
12
target/arm/internals.h | 6 ++++++
26
target/arm/translate.h | 4 ++
13
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++++++++
27
target/arm/sme-fa64.decode | 90 ++++++++++++++++++++++++++++++++++++++
14
target/arm/translate-a64.c | 12 ++++++++++++
28
target/arm/helper.c | 41 +++++++++++++++++
15
4 files changed, 69 insertions(+), 1 deletion(-)
29
target/arm/translate-a64.c | 40 ++++++++++++++++-
30
target/arm/translate-vfp.c | 12 +++++
31
target/arm/translate.c | 2 +
32
target/arm/meson.build | 1 +
33
8 files changed, 195 insertions(+), 2 deletions(-)
34
create mode 100644 target/arm/sme-fa64.decode
16
35
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
36
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
38
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
39
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
40
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, HSTR_ACTIVE, 9, 1)
22
#define SCTLR_TE (1U << 30) /* AArch32 only */
41
* the same thing as the current security state of the processor!
23
#define SCTLR_EnIB (1U << 30) /* v8.3, AArch64 only */
42
*/
24
#define SCTLR_EnIA (1U << 31) /* v8.3, AArch64 only */
43
FIELD(TBFLAG_A32, NS, 10, 1)
25
+#define SCTLR_DSSBS_32 (1U << 31) /* v8.5, AArch32 only */
44
+/*
26
#define SCTLR_BT0 (1ULL << 35) /* v8.5-BTI */
45
+ * Indicates that SME Streaming mode is active, and SMCR_ELx.FA64 is not.
27
#define SCTLR_BT1 (1ULL << 36) /* v8.5-BTI */
46
+ * This requires an SME trap from AArch32 mode when using NEON.
28
#define SCTLR_ITFSB (1ULL << 37) /* v8.5-MemTag */
47
+ */
29
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
48
+FIELD(TBFLAG_A32, SME_TRAP_NONSTREAMING, 11, 1)
30
#define SCTLR_TCF (3ULL << 40) /* v8.5-MemTag */
49
31
#define SCTLR_ATA0 (1ULL << 42) /* v8.5-MemTag */
32
#define SCTLR_ATA (1ULL << 43) /* v8.5-MemTag */
33
-#define SCTLR_DSSBS (1ULL << 44) /* v8.5 */
34
+#define SCTLR_DSSBS_64 (1ULL << 44) /* v8.5, AArch64 only */
35
36
#define CPTR_TCPAC (1U << 31)
37
#define CPTR_TTA (1U << 20)
38
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
39
#define CPSR_IL (1U << 20)
40
#define CPSR_DIT (1U << 21)
41
#define CPSR_PAN (1U << 22)
42
+#define CPSR_SSBS (1U << 23)
43
#define CPSR_J (1U << 24)
44
#define CPSR_IT_0_1 (3U << 25)
45
#define CPSR_Q (1U << 27)
46
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
47
#define PSTATE_A (1U << 8)
48
#define PSTATE_D (1U << 9)
49
#define PSTATE_BTYPE (3U << 10)
50
+#define PSTATE_SSBS (1U << 12)
51
#define PSTATE_IL (1U << 20)
52
#define PSTATE_SS (1U << 21)
53
#define PSTATE_PAN (1U << 22)
54
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_dit(const ARMISARegisters *id)
55
return FIELD_EX32(id->id_pfr0, ID_PFR0, DIT) != 0;
56
}
57
58
+static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
59
+{
60
+ return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0;
61
+}
62
+
63
/*
50
/*
64
* 64-bit feature tests via id registers.
51
* Bit usage when in AArch32 state, for M-profile only.
65
*/
52
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, SMEEXC_EL, 20, 2)
66
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
53
FIELD(TBFLAG_A64, PSTATE_SM, 22, 1)
67
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
54
FIELD(TBFLAG_A64, PSTATE_ZA, 23, 1)
68
}
55
FIELD(TBFLAG_A64, SVL, 24, 4)
69
56
+/* Indicates that SME Streaming mode is active, and SMCR_ELx.FA64 is not. */
70
+static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
57
+FIELD(TBFLAG_A64, SME_TRAP_NONSTREAMING, 28, 1)
71
+{
58
72
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
73
+}
74
+
75
/*
59
/*
76
* Feature tests for "does this exist in either 32-bit or 64-bit?"
60
* Helpers for using the above.
77
*/
61
diff --git a/target/arm/translate.h b/target/arm/translate.h
78
diff --git a/target/arm/internals.h b/target/arm/internals.h
62
index XXXXXXX..XXXXXXX 100644
79
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/translate.h
80
--- a/target/arm/internals.h
64
+++ b/target/arm/translate.h
81
+++ b/target/arm/internals.h
65
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
82
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
66
bool pstate_sm;
83
if (isar_feature_aa32_dit(id)) {
67
/* True if PSTATE.ZA is set. */
84
valid |= CPSR_DIT;
68
bool pstate_za;
85
}
69
+ /* True if non-streaming insns should raise an SME Streaming exception. */
86
+ if (isar_feature_aa32_ssbs(id)) {
70
+ bool sme_trap_nonstreaming;
87
+ valid |= CPSR_SSBS;
71
+ /* True if the current instruction is non-streaming. */
88
+ }
72
+ bool is_nonstreaming;
89
73
/* True if MVE insns are definitely not predicated by VPR or LTPSIZE */
90
return valid;
74
bool mve_no_pred;
91
}
75
/*
92
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
76
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
93
if (isar_feature_aa64_dit(id)) {
77
new file mode 100644
94
valid |= PSTATE_DIT;
78
index XXXXXXX..XXXXXXX
95
}
79
--- /dev/null
96
+ if (isar_feature_aa64_ssbs(id)) {
80
+++ b/target/arm/sme-fa64.decode
97
+ valid |= PSTATE_SSBS;
81
@@ -XXX,XX +XXX,XX @@
98
+ }
82
+# AArch64 SME allowed instruction decoding
99
if (isar_feature_aa64_mte(id)) {
83
+#
100
valid |= PSTATE_TCO;
84
+# Copyright (c) 2022 Linaro, Ltd
101
}
85
+#
86
+# This library is free software; you can redistribute it and/or
87
+# modify it under the terms of the GNU Lesser General Public
88
+# License as published by the Free Software Foundation; either
89
+# version 2.1 of the License, or (at your option) any later version.
90
+#
91
+# This library is distributed in the hope that it will be useful,
92
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
93
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
94
+# Lesser General Public License for more details.
95
+#
96
+# You should have received a copy of the GNU Lesser General Public
97
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
98
+
99
+#
100
+# This file is processed by scripts/decodetree.py
101
+#
102
+
103
+# These patterns are taken from Appendix E1.1 of DDI0616 A.a,
104
+# Arm Architecture Reference Manual Supplement,
105
+# The Scalable Matrix Extension (SME), for Armv9-A
106
+
107
+{
108
+ [
109
+ OK 0-00 1110 0000 0001 0010 11-- ---- ---- # SMOV W|Xd,Vn.B[0]
110
+ OK 0-00 1110 0000 0010 0010 11-- ---- ---- # SMOV W|Xd,Vn.H[0]
111
+ OK 0100 1110 0000 0100 0010 11-- ---- ---- # SMOV Xd,Vn.S[0]
112
+ OK 0000 1110 0000 0001 0011 11-- ---- ---- # UMOV Wd,Vn.B[0]
113
+ OK 0000 1110 0000 0010 0011 11-- ---- ---- # UMOV Wd,Vn.H[0]
114
+ OK 0000 1110 0000 0100 0011 11-- ---- ---- # UMOV Wd,Vn.S[0]
115
+ OK 0100 1110 0000 1000 0011 11-- ---- ---- # UMOV Xd,Vn.D[0]
116
+ ]
117
+ FAIL 0--0 111- ---- ---- ---- ---- ---- ---- # Advanced SIMD vector operations
118
+}
119
+
120
+{
121
+ [
122
+ OK 0101 1110 --1- ---- 11-1 11-- ---- ---- # FMULX/FRECPS/FRSQRTS (scalar)
123
+ OK 0101 1110 -10- ---- 00-1 11-- ---- ---- # FMULX/FRECPS/FRSQRTS (scalar, FP16)
124
+ OK 01-1 1110 1-10 0001 11-1 10-- ---- ---- # FRECPE/FRSQRTE/FRECPX (scalar)
125
+ OK 01-1 1110 1111 1001 11-1 10-- ---- ---- # FRECPE/FRSQRTE/FRECPX (scalar, FP16)
126
+ ]
127
+ FAIL 01-1 111- ---- ---- ---- ---- ---- ---- # Advanced SIMD single-element operations
128
+}
129
+
130
+FAIL 0-00 110- ---- ---- ---- ---- ---- ---- # Advanced SIMD structure load/store
131
+FAIL 1100 1110 ---- ---- ---- ---- ---- ---- # Advanced SIMD cryptography extensions
132
+FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
133
+
134
+# These are the "avoidance of doubt" final table of Illegal Advanced SIMD instructions
135
+# We don't actually need to include these, as the default is OK.
136
+# -001 111- ---- ---- ---- ---- ---- ---- # Scalar floating-point operations
137
+# --10 110- ---- ---- ---- ---- ---- ---- # Load/store pair of FP registers
138
+# --01 1100 ---- ---- ---- ---- ---- ---- # Load FP register (PC-relative literal)
139
+# --11 1100 --0- ---- ---- ---- ---- ---- # Load/store FP register (unscaled imm)
140
+# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
141
+# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
142
+
143
+FAIL 0000 0100 --1- ---- 1010 ---- ---- ---- # ADR
144
+FAIL 0000 0100 --1- ---- 1011 -0-- ---- ---- # FTSSEL, FEXPA
145
+FAIL 0000 0101 --10 0001 100- ---- ---- ---- # COMPACT
146
+FAIL 0010 0101 --01 100- 1111 000- ---0 ---- # RDFFR, RDFFRS
147
+FAIL 0010 0101 --10 1--- 1001 ---- ---- ---- # WRFFR, SETFFR
148
+FAIL 0100 0101 --0- ---- 1011 ---- ---- ---- # BDEP, BEXT, BGRP
149
+FAIL 0100 0101 000- ---- 0110 1--- ---- ---- # PMULLB, PMULLT (128b result)
150
+FAIL 0110 0100 --1- ---- 1110 01-- ---- ---- # FMMLA, BFMMLA
151
+FAIL 0110 0101 --0- ---- 0000 11-- ---- ---- # FTSMUL
152
+FAIL 0110 0101 --01 0--- 100- ---- ---- ---- # FTMAD
153
+FAIL 0110 0101 --01 1--- 001- ---- ---- ---- # FADDA
154
+FAIL 0100 0101 --0- ---- 1001 10-- ---- ---- # SMMLA, UMMLA, USMMLA
155
+FAIL 0100 0101 --1- ---- 1--- ---- ---- ---- # SVE2 string/histo/crypto instructions
156
+FAIL 1000 010- -00- ---- 10-- ---- ---- ---- # SVE2 32-bit gather NT load (vector+scalar)
157
+FAIL 1000 010- -00- ---- 111- ---- ---- ---- # SVE 32-bit gather prefetch (vector+imm)
158
+FAIL 1000 0100 0-1- ---- 0--- ---- ---- ---- # SVE 32-bit gather prefetch (scalar+vector)
159
+FAIL 1000 010- -01- ---- 1--- ---- ---- ---- # SVE 32-bit gather load (vector+imm)
160
+FAIL 1000 0100 0-0- ---- 0--- ---- ---- ---- # SVE 32-bit gather load byte (scalar+vector)
161
+FAIL 1000 0100 1--- ---- 0--- ---- ---- ---- # SVE 32-bit gather load half (scalar+vector)
162
+FAIL 1000 0101 0--- ---- 0--- ---- ---- ---- # SVE 32-bit gather load word (scalar+vector)
163
+FAIL 1010 010- ---- ---- 011- ---- ---- ---- # SVE contiguous FF load (scalar+scalar)
164
+FAIL 1010 010- ---1 ---- 101- ---- ---- ---- # SVE contiguous NF load (scalar+imm)
165
+FAIL 1010 010- -01- ---- 000- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+scalar)
166
+FAIL 1010 010- -010 ---- 001- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+imm)
167
+FAIL 1100 010- ---- ---- ---- ---- ---- ---- # SVE 64-bit gather load/prefetch
168
+FAIL 1110 010- -00- ---- 001- ---- ---- ---- # SVE2 64-bit scatter NT store (vector+scalar)
169
+FAIL 1110 010- -10- ---- 001- ---- ---- ---- # SVE2 32-bit scatter NT store (vector+scalar)
170
+FAIL 1110 010- ---- ---- 1-0- ---- ---- ---- # SVE scatter store (scalar+32-bit vector)
171
+FAIL 1110 010- ---- ---- 101- ---- ---- ---- # SVE scatter store (misc)
102
diff --git a/target/arm/helper.c b/target/arm/helper.c
172
diff --git a/target/arm/helper.c b/target/arm/helper.c
103
index XXXXXXX..XXXXXXX 100644
173
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/helper.c
174
--- a/target/arm/helper.c
105
+++ b/target/arm/helper.c
175
+++ b/target/arm/helper.c
106
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dit_reginfo = {
176
@@ -XXX,XX +XXX,XX @@ int sme_exception_el(CPUARMState *env, int el)
107
.readfn = aa64_dit_read, .writefn = aa64_dit_write
177
return 0;
108
};
178
}
109
179
110
+static uint64_t aa64_ssbs_read(CPUARMState *env, const ARMCPRegInfo *ri)
180
+/* This corresponds to the ARM pseudocode function IsFullA64Enabled(). */
111
+{
181
+static bool sme_fa64(CPUARMState *env, int el)
112
+ return env->pstate & PSTATE_SSBS;
182
+{
113
+}
183
+ if (!cpu_isar_feature(aa64_sme_fa64, env_archcpu(env))) {
114
+
184
+ return false;
115
+static void aa64_ssbs_write(CPUARMState *env, const ARMCPRegInfo *ri,
185
+ }
116
+ uint64_t value)
186
+
117
+{
187
+ if (el <= 1 && !el_is_in_host(env, el)) {
118
+ env->pstate = (env->pstate & ~PSTATE_SSBS) | (value & PSTATE_SSBS);
188
+ if (!FIELD_EX64(env->vfp.smcr_el[1], SMCR, FA64)) {
119
+}
189
+ return false;
120
+
121
+static const ARMCPRegInfo ssbs_reginfo = {
122
+ .name = "SSBS", .state = ARM_CP_STATE_AA64,
123
+ .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 6,
124
+ .type = ARM_CP_NO_RAW, .access = PL0_RW,
125
+ .readfn = aa64_ssbs_read, .writefn = aa64_ssbs_write
126
+};
127
+
128
static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env,
129
const ARMCPRegInfo *ri,
130
bool isread)
131
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
132
if (cpu_isar_feature(aa64_dit, cpu)) {
133
define_one_arm_cp_reg(cpu, &dit_reginfo);
134
}
135
+ if (cpu_isar_feature(aa64_ssbs, cpu)) {
136
+ define_one_arm_cp_reg(cpu, &ssbs_reginfo);
137
+ }
138
139
if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
140
define_arm_cp_regs(cpu, vhe_reginfo);
141
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
142
env->uncached_cpsr &= ~(CPSR_IL | CPSR_J);
143
env->daif |= mask;
144
145
+ if (cpu_isar_feature(aa32_ssbs, env_archcpu(env))) {
146
+ if (env->cp15.sctlr_el[new_el] & SCTLR_DSSBS_32) {
147
+ env->uncached_cpsr |= CPSR_SSBS;
148
+ } else {
149
+ env->uncached_cpsr &= ~CPSR_SSBS;
150
+ }
190
+ }
151
+ }
191
+ }
152
+
192
+ if (el <= 2 && arm_is_el2_enabled(env)) {
153
if (new_mode == ARM_CPU_MODE_HYP) {
193
+ if (!FIELD_EX64(env->vfp.smcr_el[2], SMCR, FA64)) {
154
env->thumb = (env->cp15.sctlr_el[2] & SCTLR_TE) != 0;
194
+ return false;
155
env->elr_el[2] = env->regs[15];
156
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
157
new_mode |= PSTATE_TCO;
158
}
159
160
+ if (cpu_isar_feature(aa64_ssbs, cpu)) {
161
+ if (env->cp15.sctlr_el[new_el] & SCTLR_DSSBS_64) {
162
+ new_mode |= PSTATE_SSBS;
163
+ } else {
164
+ new_mode &= ~PSTATE_SSBS;
165
+ }
195
+ }
166
+ }
196
+ }
167
+
197
+ if (arm_feature(env, ARM_FEATURE_EL3)) {
168
pstate_write(env, PSTATE_DAIF | new_mode);
198
+ if (!FIELD_EX64(env->vfp.smcr_el[3], SMCR, FA64)) {
169
env->aarch64 = 1;
199
+ return false;
170
aarch64_restore_sp(env, new_el);
200
+ }
201
+ }
202
+
203
+ return true;
204
+}
205
+
206
/*
207
* Given that SVE is enabled, return the vector length for EL.
208
*/
209
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
210
DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
211
}
212
213
+ /*
214
+ * The SME exception we are testing for is raised via
215
+ * AArch64.CheckFPAdvSIMDEnabled(), as called from
216
+ * AArch32.CheckAdvSIMDOrFPEnabled().
217
+ */
218
+ if (el == 0
219
+ && FIELD_EX64(env->svcr, SVCR, SM)
220
+ && (!arm_is_el2_enabled(env)
221
+ || (arm_el_is_aa64(env, 2) && !(env->cp15.hcr_el2 & HCR_TGE)))
222
+ && arm_el_is_aa64(env, 1)
223
+ && !sme_fa64(env, el)) {
224
+ DP_TBFLAG_A32(flags, SME_TRAP_NONSTREAMING, 1);
225
+ }
226
+
227
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
228
}
229
230
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
231
}
232
if (FIELD_EX64(env->svcr, SVCR, SM)) {
233
DP_TBFLAG_A64(flags, PSTATE_SM, 1);
234
+ DP_TBFLAG_A64(flags, SME_TRAP_NONSTREAMING, !sme_fa64(env, el));
235
}
236
DP_TBFLAG_A64(flags, PSTATE_ZA, FIELD_EX64(env->svcr, SVCR, ZA));
237
}
171
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
238
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
172
index XXXXXXX..XXXXXXX 100644
239
index XXXXXXX..XXXXXXX 100644
173
--- a/target/arm/translate-a64.c
240
--- a/target/arm/translate-a64.c
174
+++ b/target/arm/translate-a64.c
241
+++ b/target/arm/translate-a64.c
175
@@ -XXX,XX +XXX,XX @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
242
@@ -XXX,XX +XXX,XX @@ static void do_vec_ld(DisasContext *s, int destidx, int element,
176
tcg_temp_free_i32(t1);
243
* unallocated-encoding checks (otherwise the syndrome information
177
break;
244
* for the resulting exception will be incorrect).
178
245
*/
179
+ case 0x19: /* SSBS */
246
-static bool fp_access_check(DisasContext *s)
180
+ if (!dc_isar_feature(aa64_ssbs, s)) {
247
+static bool fp_access_check_only(DisasContext *s)
181
+ goto do_unallocated;
248
{
182
+ }
249
if (s->fp_excp_el) {
183
+ if (crm & 1) {
250
assert(!s->fp_access_checked);
184
+ set_pstate_bits(PSTATE_SSBS);
251
@@ -XXX,XX +XXX,XX @@ static bool fp_access_check(DisasContext *s)
185
+ } else {
252
return true;
186
+ clear_pstate_bits(PSTATE_SSBS);
253
}
187
+ }
254
188
+ /* Don't need to rebuild hflags since SSBS is a nop */
255
+static bool fp_access_check(DisasContext *s)
189
+ break;
256
+{
190
+
257
+ if (!fp_access_check_only(s)) {
191
case 0x1a: /* DIT */
258
+ return false;
192
if (!dc_isar_feature(aa64_dit, s)) {
259
+ }
193
goto do_unallocated;
260
+ if (s->sme_trap_nonstreaming && s->is_nonstreaming) {
261
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
262
+ syn_smetrap(SME_ET_Streaming, false));
263
+ return false;
264
+ }
265
+ return true;
266
+}
267
+
268
/* Check that SVE access is enabled. If it is, return true.
269
* If not, emit code to generate an appropriate exception and return false.
270
*/
271
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
272
default:
273
g_assert_not_reached();
274
}
275
- if ((ri->type & ARM_CP_FPU) && !fp_access_check(s)) {
276
+ if ((ri->type & ARM_CP_FPU) && !fp_access_check_only(s)) {
277
return;
278
} else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
279
return;
280
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn)
281
}
282
}
283
284
+/*
285
+ * Include the generated SME FA64 decoder.
286
+ */
287
+
288
+#include "decode-sme-fa64.c.inc"
289
+
290
+static bool trans_OK(DisasContext *s, arg_OK *a)
291
+{
292
+ return true;
293
+}
294
+
295
+static bool trans_FAIL(DisasContext *s, arg_OK *a)
296
+{
297
+ s->is_nonstreaming = true;
298
+ return true;
299
+}
300
+
301
/**
302
* is_guarded_page:
303
* @env: The cpu environment
304
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
305
dc->mte_active[1] = EX_TBFLAG_A64(tb_flags, MTE0_ACTIVE);
306
dc->pstate_sm = EX_TBFLAG_A64(tb_flags, PSTATE_SM);
307
dc->pstate_za = EX_TBFLAG_A64(tb_flags, PSTATE_ZA);
308
+ dc->sme_trap_nonstreaming = EX_TBFLAG_A64(tb_flags, SME_TRAP_NONSTREAMING);
309
dc->vec_len = 0;
310
dc->vec_stride = 0;
311
dc->cp_regs = arm_cpu->cp_regs;
312
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
313
}
314
}
315
316
+ s->is_nonstreaming = false;
317
+ if (s->sme_trap_nonstreaming) {
318
+ disas_sme_fa64(s, insn);
319
+ }
320
+
321
switch (extract32(insn, 25, 4)) {
322
case 0x0:
323
if (!extract32(insn, 31, 1) || !disas_sme(s, insn)) {
324
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
325
index XXXXXXX..XXXXXXX 100644
326
--- a/target/arm/translate-vfp.c
327
+++ b/target/arm/translate-vfp.c
328
@@ -XXX,XX +XXX,XX @@ static bool vfp_access_check_a(DisasContext *s, bool ignore_vfp_enabled)
329
return false;
330
}
331
332
+ /*
333
+ * Note that rebuild_hflags_a32 has already accounted for being in EL0
334
+ * and the higher EL in A64 mode, etc. Unlike A64 mode, there do not
335
+ * appear to be any insns which touch VFP which are allowed.
336
+ */
337
+ if (s->sme_trap_nonstreaming) {
338
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
339
+ syn_smetrap(SME_ET_Streaming,
340
+ s->base.pc_next - s->pc_curr == 2));
341
+ return false;
342
+ }
343
+
344
if (!s->vfp_enabled && !ignore_vfp_enabled) {
345
assert(!arm_dc_feature(s, ARM_FEATURE_M));
346
unallocated_encoding(s);
347
diff --git a/target/arm/translate.c b/target/arm/translate.c
348
index XXXXXXX..XXXXXXX 100644
349
--- a/target/arm/translate.c
350
+++ b/target/arm/translate.c
351
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
352
dc->vec_len = EX_TBFLAG_A32(tb_flags, VECLEN);
353
dc->vec_stride = EX_TBFLAG_A32(tb_flags, VECSTRIDE);
354
}
355
+ dc->sme_trap_nonstreaming =
356
+ EX_TBFLAG_A32(tb_flags, SME_TRAP_NONSTREAMING);
357
}
358
dc->cp_regs = cpu->cp_regs;
359
dc->features = env->features;
360
diff --git a/target/arm/meson.build b/target/arm/meson.build
361
index XXXXXXX..XXXXXXX 100644
362
--- a/target/arm/meson.build
363
+++ b/target/arm/meson.build
364
@@ -XXX,XX +XXX,XX @@
365
gen = [
366
decodetree.process('sve.decode', extra_args: '--decode=disas_sve'),
367
decodetree.process('sme.decode', extra_args: '--decode=disas_sme'),
368
+ decodetree.process('sme-fa64.decode', extra_args: '--static-decode=disas_sme_fa64'),
369
decodetree.process('neon-shared.decode', extra_args: '--decode=disas_neon_shared'),
370
decodetree.process('neon-dp.decode', extra_args: '--decode=disas_neon_dp'),
371
decodetree.process('neon-ls.decode', extra_args: '--decode=disas_neon_ls'),
194
--
372
--
195
2.20.1
373
2.25.1
196
197
diff view generated by jsdifflib
1
The AN505 and AN521 don't have any read-only memory, but the AN524
1
From: Richard Henderson <richard.henderson@linaro.org>
2
does; add a flag to ROMInfo to mark a region as ROM.
3
2
3
Mark ADR as a non-streaming instruction, which should trap
4
if full a64 support is not enabled in streaming mode.
5
6
Removing entries from sme-fa64.decode is an easy way to see
7
what remains to be done.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220708151540.18136-5-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210215115138.20465-19-peter.maydell@linaro.org
7
---
13
---
8
hw/arm/mps2-tz.c | 6 ++++++
14
target/arm/translate.h | 7 +++++++
9
1 file changed, 6 insertions(+)
15
target/arm/sme-fa64.decode | 1 -
16
target/arm/translate-sve.c | 8 ++++----
17
3 files changed, 11 insertions(+), 5 deletions(-)
10
18
11
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
19
diff --git a/target/arm/translate.h b/target/arm/translate.h
12
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/mps2-tz.c
21
--- a/target/arm/translate.h
14
+++ b/hw/arm/mps2-tz.c
22
+++ b/target/arm/translate.h
15
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
23
@@ -XXX,XX +XXX,XX @@ uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
16
* Flag values:
24
static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
17
* IS_ALIAS: this RAM area is an alias to the upstream end of the
25
{ return dc_isar_feature(FEAT, s) && FUNC(s, __VA_ARGS__); }
18
* MPC specified by its .mpc value
26
19
+ * IS_ROM: this RAM area is read-only
27
+#define TRANS_FEAT_NONSTREAMING(NAME, FEAT, FUNC, ...) \
20
*/
28
+ static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
21
#define IS_ALIAS 1
29
+ { \
22
+#define IS_ROM 2
30
+ s->is_nonstreaming = true; \
23
31
+ return dc_isar_feature(FEAT, s) && FUNC(s, __VA_ARGS__); \
24
struct MPS2TZMachineClass {
25
MachineClass parent;
26
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
27
if (raminfo->mrindex < 0) {
28
/* Means this RAMInfo is for QEMU's "system memory" */
29
MachineState *machine = MACHINE(mms);
30
+ assert(!(raminfo->flags & IS_ROM));
31
return machine->ram;
32
}
33
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
35
36
memory_region_init_ram(ram, NULL, raminfo->name,
37
raminfo->size, &error_fatal);
38
+ if (raminfo->flags & IS_ROM) {
39
+ memory_region_set_readonly(ram, true);
40
+ }
32
+ }
41
return ram;
33
+
34
#endif /* TARGET_ARM_TRANSLATE_H */
35
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/sme-fa64.decode
38
+++ b/target/arm/sme-fa64.decode
39
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
40
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
41
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
42
43
-FAIL 0000 0100 --1- ---- 1010 ---- ---- ---- # ADR
44
FAIL 0000 0100 --1- ---- 1011 -0-- ---- ---- # FTSSEL, FEXPA
45
FAIL 0000 0101 --10 0001 100- ---- ---- ---- # COMPACT
46
FAIL 0010 0101 --01 100- 1111 000- ---0 ---- # RDFFR, RDFFRS
47
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/translate-sve.c
50
+++ b/target/arm/translate-sve.c
51
@@ -XXX,XX +XXX,XX @@ static bool do_adr(DisasContext *s, arg_rrri *a, gen_helper_gvec_3 *fn)
52
return gen_gvec_ool_zzz(s, fn, a->rd, a->rn, a->rm, a->imm);
42
}
53
}
43
54
55
-TRANS_FEAT(ADR_p32, aa64_sve, do_adr, a, gen_helper_sve_adr_p32)
56
-TRANS_FEAT(ADR_p64, aa64_sve, do_adr, a, gen_helper_sve_adr_p64)
57
-TRANS_FEAT(ADR_s32, aa64_sve, do_adr, a, gen_helper_sve_adr_s32)
58
-TRANS_FEAT(ADR_u32, aa64_sve, do_adr, a, gen_helper_sve_adr_u32)
59
+TRANS_FEAT_NONSTREAMING(ADR_p32, aa64_sve, do_adr, a, gen_helper_sve_adr_p32)
60
+TRANS_FEAT_NONSTREAMING(ADR_p64, aa64_sve, do_adr, a, gen_helper_sve_adr_p64)
61
+TRANS_FEAT_NONSTREAMING(ADR_s32, aa64_sve, do_adr, a, gen_helper_sve_adr_s32)
62
+TRANS_FEAT_NONSTREAMING(ADR_u32, aa64_sve, do_adr, a, gen_helper_sve_adr_u32)
63
64
/*
65
*** SVE Integer Misc - Unpredicated Group
44
--
66
--
45
2.20.1
67
2.25.1
46
47
diff view generated by jsdifflib
1
Move the specification of the IRQ information for the uart, ethernet,
1
From: Richard Henderson <richard.henderson@linaro.org>
2
dma and spi devices to the data structures. (The other devices
3
handled by the PPCPortInfo structures don't have any interrupt lines
4
we need to wire up.)
5
2
3
Mark these as a non-streaming instructions, which should trap
4
if full a64 support is not enabled in streaming mode.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-6-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-14-peter.maydell@linaro.org
9
---
10
---
10
hw/arm/mps2-tz.c | 52 +++++++++++++++++++++++-------------------------
11
target/arm/sme-fa64.decode | 2 --
11
1 file changed, 25 insertions(+), 27 deletions(-)
12
target/arm/translate-sve.c | 9 ++++++---
13
2 files changed, 6 insertions(+), 5 deletions(-)
12
14
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
17
--- a/target/arm/sme-fa64.decode
16
+++ b/hw/arm/mps2-tz.c
18
+++ b/target/arm/sme-fa64.decode
17
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
18
const char *name, hwaddr size,
20
19
const int *irqs)
21
FAIL 0000 0100 --1- ---- 1011 -0-- ---- ---- # FTSSEL, FEXPA
20
{
22
FAIL 0000 0101 --10 0001 100- ---- ---- ---- # COMPACT
21
+ /* The irq[] array is tx, rx, combined, in that order */
23
-FAIL 0010 0101 --01 100- 1111 000- ---0 ---- # RDFFR, RDFFRS
22
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
24
-FAIL 0010 0101 --10 1--- 1001 ---- ---- ---- # WRFFR, SETFFR
23
CMSDKAPBUART *uart = opaque;
25
FAIL 0100 0101 --0- ---- 1011 ---- ---- ---- # BDEP, BEXT, BGRP
24
int i = uart - &mms->uart[0];
26
FAIL 0100 0101 000- ---- 0110 1--- ---- ---- # PMULLB, PMULLT (128b result)
25
- int rxirqno = i * 2 + 32;
27
FAIL 0110 0100 --1- ---- 1110 01-- ---- ---- # FMMLA, BFMMLA
26
- int txirqno = i * 2 + 33;
28
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
27
- int combirqno = i + 42;
29
index XXXXXXX..XXXXXXX 100644
28
SysBusDevice *s;
30
--- a/target/arm/translate-sve.c
29
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
31
+++ b/target/arm/translate-sve.c
30
32
@@ -XXX,XX +XXX,XX @@ static bool do_predset(DisasContext *s, int esz, int rd, int pat, bool setflag)
31
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
33
TRANS_FEAT(PTRUE, aa64_sve, do_predset, a->esz, a->rd, a->pat, a->s)
32
qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->sysclk_frq);
34
33
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
35
/* Note pat == 31 is #all, to set all elements. */
34
s = SYS_BUS_DEVICE(uart);
36
-TRANS_FEAT(SETFFR, aa64_sve, do_predset, 0, FFR_PRED_NUM, 31, false)
35
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, txirqno));
37
+TRANS_FEAT_NONSTREAMING(SETFFR, aa64_sve,
36
- sysbus_connect_irq(s, 1, get_sse_irq_in(mms, rxirqno));
38
+ do_predset, 0, FFR_PRED_NUM, 31, false)
37
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
39
38
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[1]));
40
/* Note pat == 32 is #unimp, to set no elements. */
39
sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
41
TRANS_FEAT(PFALSE, aa64_sve, do_predset, 0, a->rd, 32, false)
40
sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
42
@@ -XXX,XX +XXX,XX @@ static bool trans_RDFFR_p(DisasContext *s, arg_RDFFR_p *a)
41
- sysbus_connect_irq(s, 4, get_sse_irq_in(mms, combirqno));
43
.rd = a->rd, .pg = a->pg, .s = a->s,
42
+ sysbus_connect_irq(s, 4, get_sse_irq_in(mms, irqs[2]));
44
.rn = FFR_PRED_NUM, .rm = FFR_PRED_NUM,
43
return sysbus_mmio_get_region(SYS_BUS_DEVICE(uart), 0);
45
};
46
+
47
+ s->is_nonstreaming = true;
48
return trans_AND_pppp(s, &alt_a);
44
}
49
}
45
50
46
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
51
-TRANS_FEAT(RDFFR, aa64_sve, do_mov_p, a->rd, FFR_PRED_NUM)
47
52
-TRANS_FEAT(WRFFR, aa64_sve, do_mov_p, FFR_PRED_NUM, a->rn)
48
s = SYS_BUS_DEVICE(mms->lan9118);
53
+TRANS_FEAT_NONSTREAMING(RDFFR, aa64_sve, do_mov_p, a->rd, FFR_PRED_NUM)
49
sysbus_realize_and_unref(s, &error_fatal);
54
+TRANS_FEAT_NONSTREAMING(WRFFR, aa64_sve, do_mov_p, FFR_PRED_NUM, a->rn)
50
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 48));
55
51
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
56
static bool do_pfirst_pnext(DisasContext *s, arg_rr_esz *a,
52
return sysbus_mmio_get_region(s, 0);
57
void (*gen_fn)(TCGv_i32, TCGv_ptr,
53
}
54
55
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
56
const char *name, hwaddr size,
57
const int *irqs)
58
{
59
+ /* The irq[] array is DMACINTR, DMACINTERR, DMACINTTC, in that order */
60
PL080State *dma = opaque;
61
int i = dma - &mms->dma[0];
62
SysBusDevice *s;
63
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
64
65
s = SYS_BUS_DEVICE(dma);
66
/* Wire up DMACINTR, DMACINTERR, DMACINTTC */
67
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 58 + i * 3));
68
- sysbus_connect_irq(s, 1, get_sse_irq_in(mms, 56 + i * 3));
69
- sysbus_connect_irq(s, 2, get_sse_irq_in(mms, 57 + i * 3));
70
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
71
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[1]));
72
+ sysbus_connect_irq(s, 2, get_sse_irq_in(mms, irqs[2]));
73
74
g_free(mscname);
75
return sysbus_mmio_get_region(s, 0);
76
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
77
* lines are set via the "MISC" register in the MPS2 FPGAIO device.
78
*/
79
PL022State *spi = opaque;
80
- int i = spi - &mms->spi[0];
81
SysBusDevice *s;
82
83
object_initialize_child(OBJECT(mms), name, spi, TYPE_PL022);
84
sysbus_realize(SYS_BUS_DEVICE(spi), &error_fatal);
85
s = SYS_BUS_DEVICE(spi);
86
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 51 + i));
87
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
88
return sysbus_mmio_get_region(s, 0);
89
}
90
91
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
92
}, {
93
.name = "apb_ppcexp1",
94
.ports = {
95
- { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000 },
96
- { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000 },
97
- { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000 },
98
- { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000 },
99
- { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000 },
100
- { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000 },
101
- { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000 },
102
- { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 },
103
- { "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000 },
104
- { "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000 },
105
+ { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000, { 51 } },
106
+ { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000, { 52 } },
107
+ { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000, { 53 } },
108
+ { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000, { 54 } },
109
+ { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000, { 55 } },
110
+ { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000, { 32, 33, 42 } },
111
+ { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000, { 34, 35, 43 } },
112
+ { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000, { 36, 37, 44 } },
113
+ { "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000, { 38, 39, 45 } },
114
+ { "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000, { 40, 41, 46 } },
115
{ "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000 },
116
{ "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000 },
117
{ "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000 },
118
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
119
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x40101000, 0x1000 },
120
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x40102000, 0x1000 },
121
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x40103000, 0x1000 },
122
- { "eth", make_eth_dev, NULL, 0x42000000, 0x100000 },
123
+ { "eth", make_eth_dev, NULL, 0x42000000, 0x100000, { 48 } },
124
},
125
}, {
126
.name = "ahb_ppcexp1",
127
.ports = {
128
- { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000 },
129
- { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000 },
130
- { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000 },
131
- { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000 },
132
+ { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000, { 58, 56, 57 } },
133
+ { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000, { 61, 59, 60 } },
134
+ { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000, { 64, 62, 63 } },
135
+ { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000, { 67, 65, 66 } },
136
},
137
},
138
};
139
--
58
--
140
2.20.1
59
2.25.1
141
142
diff view generated by jsdifflib
1
For a long time now the UI layer has guaranteed that the console
1
From: Richard Henderson <richard.henderson@linaro.org>
2
surface is always 32 bits per pixel, RGB. The TCX code already
3
assumes 32bpp, but it still has some checks of is_surface_bgr()
4
in an attempt to support 32bpp BGR. is_surface_bgr() will always
5
return false for the qemu_console_surface(), unless the display
6
device itself has deliberately created an alternate-format
7
surface via a function like qemu_create_displaysurface_from().
8
2
9
Drop the never-used BGR-handling code, and assert that we have
3
Mark these as a non-streaming instructions, which should trap
10
a 32-bit surface rather than just doing nothing if it isn't.
4
if full a64 support is not enabled in streaming mode.
11
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-7-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20210215102149.20513-1-peter.maydell@linaro.org
16
---
10
---
17
hw/display/tcx.c | 31 ++++++++-----------------------
11
target/arm/sme-fa64.decode | 3 ---
18
1 file changed, 8 insertions(+), 23 deletions(-)
12
target/arm/translate-sve.c | 22 ++++++++++++----------
13
2 files changed, 12 insertions(+), 13 deletions(-)
19
14
20
diff --git a/hw/display/tcx.c b/hw/display/tcx.c
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/display/tcx.c
17
--- a/target/arm/sme-fa64.decode
23
+++ b/hw/display/tcx.c
18
+++ b/target/arm/sme-fa64.decode
24
@@ -XXX,XX +XXX,XX @@ static int tcx_check_dirty(TCXState *s, DirtyBitmapSnapshot *snap,
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
25
20
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
26
static void update_palette_entries(TCXState *s, int start, int end)
21
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
27
{
22
28
- DisplaySurface *surface = qemu_console_surface(s->con);
23
-FAIL 0000 0100 --1- ---- 1011 -0-- ---- ---- # FTSSEL, FEXPA
29
int i;
24
-FAIL 0000 0101 --10 0001 100- ---- ---- ---- # COMPACT
30
25
-FAIL 0100 0101 --0- ---- 1011 ---- ---- ---- # BDEP, BEXT, BGRP
31
for (i = start; i < end; i++) {
26
FAIL 0100 0101 000- ---- 0110 1--- ---- ---- # PMULLB, PMULLT (128b result)
32
- if (is_surface_bgr(surface)) {
27
FAIL 0110 0100 --1- ---- 1110 01-- ---- ---- # FMMLA, BFMMLA
33
- s->palette[i] = rgb_to_pixel32bgr(s->r[i], s->g[i], s->b[i]);
28
FAIL 0110 0101 --0- ---- 0000 11-- ---- ---- # FTSMUL
34
- } else {
29
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
35
- s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
30
index XXXXXXX..XXXXXXX 100644
36
- }
31
--- a/target/arm/translate-sve.c
37
+ s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
32
+++ b/target/arm/translate-sve.c
38
}
33
@@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_2 * const fexpa_fns[4] = {
39
tcx_set_dirty(s, 0, memory_region_size(&s->vram_mem));
34
NULL, gen_helper_sve_fexpa_h,
40
}
35
gen_helper_sve_fexpa_s, gen_helper_sve_fexpa_d,
41
@@ -XXX,XX +XXX,XX @@ static void tcx_draw_cursor32(TCXState *s1, uint8_t *d,
36
};
42
}
37
-TRANS_FEAT(FEXPA, aa64_sve, gen_gvec_ool_zz,
38
- fexpa_fns[a->esz], a->rd, a->rn, 0)
39
+TRANS_FEAT_NONSTREAMING(FEXPA, aa64_sve, gen_gvec_ool_zz,
40
+ fexpa_fns[a->esz], a->rd, a->rn, 0)
41
42
static gen_helper_gvec_3 * const ftssel_fns[4] = {
43
NULL, gen_helper_sve_ftssel_h,
44
gen_helper_sve_ftssel_s, gen_helper_sve_ftssel_d,
45
};
46
-TRANS_FEAT(FTSSEL, aa64_sve, gen_gvec_ool_arg_zzz, ftssel_fns[a->esz], a, 0)
47
+TRANS_FEAT_NONSTREAMING(FTSSEL, aa64_sve, gen_gvec_ool_arg_zzz,
48
+ ftssel_fns[a->esz], a, 0)
43
49
44
/*
50
/*
45
- XXX Could be much more optimal:
51
*** SVE Predicate Logical Operations Group
46
- * detect if line/page/whole screen is in 24 bit mode
52
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(TRN2_q, aa64_sve_f64mm, gen_gvec_ool_arg_zzz,
47
- * if destination is also BGR, use memcpy
53
static gen_helper_gvec_3 * const compact_fns[4] = {
48
- */
54
NULL, NULL, gen_helper_sve_compact_s, gen_helper_sve_compact_d
49
+ * XXX Could be much more optimal:
55
};
50
+ * detect if line/page/whole screen is in 24 bit mode
56
-TRANS_FEAT(COMPACT, aa64_sve, gen_gvec_ool_arg_zpz, compact_fns[a->esz], a, 0)
51
+ */
57
+TRANS_FEAT_NONSTREAMING(COMPACT, aa64_sve, gen_gvec_ool_arg_zpz,
52
static inline void tcx24_draw_line32(TCXState *s1, uint8_t *d,
58
+ compact_fns[a->esz], a, 0)
53
const uint8_t *s, int width,
59
54
const uint32_t *cplane,
60
/* Call the helper that computes the ARM LastActiveElement pseudocode
55
const uint32_t *s24)
61
* function, scaled by the element size. This includes the not found
56
{
62
@@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3 * const bext_fns[4] = {
57
- DisplaySurface *surface = qemu_console_surface(s1->con);
63
gen_helper_sve2_bext_b, gen_helper_sve2_bext_h,
58
- int x, bgr, r, g, b;
64
gen_helper_sve2_bext_s, gen_helper_sve2_bext_d,
59
+ int x, r, g, b;
65
};
60
uint8_t val, *p8;
66
-TRANS_FEAT(BEXT, aa64_sve2_bitperm, gen_gvec_ool_arg_zzz,
61
uint32_t *p = (uint32_t *)d;
67
- bext_fns[a->esz], a, 0)
62
uint32_t dval;
68
+TRANS_FEAT_NONSTREAMING(BEXT, aa64_sve2_bitperm, gen_gvec_ool_arg_zzz,
63
- bgr = is_surface_bgr(surface);
69
+ bext_fns[a->esz], a, 0)
64
for(x = 0; x < width; x++, s++, s24++) {
70
65
if (be32_to_cpu(*cplane) & 0x03000000) {
71
static gen_helper_gvec_3 * const bdep_fns[4] = {
66
/* 24-bit direct, BGR order */
72
gen_helper_sve2_bdep_b, gen_helper_sve2_bdep_h,
67
@@ -XXX,XX +XXX,XX @@ static inline void tcx24_draw_line32(TCXState *s1, uint8_t *d,
73
gen_helper_sve2_bdep_s, gen_helper_sve2_bdep_d,
68
b = *p8++;
74
};
69
g = *p8++;
75
-TRANS_FEAT(BDEP, aa64_sve2_bitperm, gen_gvec_ool_arg_zzz,
70
r = *p8;
76
- bdep_fns[a->esz], a, 0)
71
- if (bgr)
77
+TRANS_FEAT_NONSTREAMING(BDEP, aa64_sve2_bitperm, gen_gvec_ool_arg_zzz,
72
- dval = rgb_to_pixel32bgr(r, g, b);
78
+ bdep_fns[a->esz], a, 0)
73
- else
79
74
- dval = rgb_to_pixel32(r, g, b);
80
static gen_helper_gvec_3 * const bgrp_fns[4] = {
75
+ dval = rgb_to_pixel32(r, g, b);
81
gen_helper_sve2_bgrp_b, gen_helper_sve2_bgrp_h,
76
} else {
82
gen_helper_sve2_bgrp_s, gen_helper_sve2_bgrp_d,
77
/* 8-bit pseudocolor */
83
};
78
val = *s;
84
-TRANS_FEAT(BGRP, aa64_sve2_bitperm, gen_gvec_ool_arg_zzz,
79
@@ -XXX,XX +XXX,XX @@ static void tcx_update_display(void *opaque)
85
- bgrp_fns[a->esz], a, 0)
80
int y, y_start, dd, ds;
86
+TRANS_FEAT_NONSTREAMING(BGRP, aa64_sve2_bitperm, gen_gvec_ool_arg_zzz,
81
uint8_t *d, *s;
87
+ bgrp_fns[a->esz], a, 0)
82
88
83
- if (surface_bits_per_pixel(surface) != 32) {
89
static gen_helper_gvec_3 * const cadd_fns[4] = {
84
- return;
90
gen_helper_sve2_cadd_b, gen_helper_sve2_cadd_h,
85
- }
86
+ assert(surface_bits_per_pixel(surface) == 32);
87
88
page = 0;
89
y_start = -1;
90
@@ -XXX,XX +XXX,XX @@ static void tcx24_update_display(void *opaque)
91
uint8_t *d, *s;
92
uint32_t *cptr, *s24;
93
94
- if (surface_bits_per_pixel(surface) != 32) {
95
- return;
96
- }
97
+ assert(surface_bits_per_pixel(surface) == 32);
98
99
page = 0;
100
y_start = -1;
101
--
91
--
102
2.20.1
92
2.25.1
103
104
diff view generated by jsdifflib
1
Update old infocenter.arm.com URLs to the equivalent developer.arm.com
1
From: Richard Henderson <richard.henderson@linaro.org>
2
ones (the old URLs should redirect, but we might as well avoid the
3
redirection notice, and the new URLs are pleasantly shorter).
4
2
5
This commit covers the links to the MPS2 board TRM, the various
3
Mark these as a non-streaming instructions, which should trap
6
Application Notes, the IoTKit and SSE-200 documents.
4
if full a64 support is not enabled in streaming mode.
7
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-8-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210215115138.20465-25-peter.maydell@linaro.org
11
---
10
---
12
include/hw/arm/armsse.h | 4 ++--
11
target/arm/sme-fa64.decode | 2 --
13
include/hw/misc/armsse-cpuid.h | 2 +-
12
target/arm/translate-sve.c | 24 +++++++++++++++---------
14
include/hw/misc/armsse-mhu.h | 2 +-
13
2 files changed, 15 insertions(+), 11 deletions(-)
15
include/hw/misc/iotkit-secctl.h | 2 +-
16
include/hw/misc/iotkit-sysctl.h | 2 +-
17
include/hw/misc/iotkit-sysinfo.h | 2 +-
18
include/hw/misc/mps2-fpgaio.h | 2 +-
19
hw/arm/mps2-tz.c | 11 +++++------
20
hw/misc/armsse-cpuid.c | 2 +-
21
hw/misc/armsse-mhu.c | 2 +-
22
hw/misc/iotkit-sysctl.c | 2 +-
23
hw/misc/iotkit-sysinfo.c | 2 +-
24
hw/misc/mps2-fpgaio.c | 2 +-
25
hw/misc/mps2-scc.c | 2 +-
26
14 files changed, 19 insertions(+), 20 deletions(-)
27
14
28
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
29
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/arm/armsse.h
17
--- a/target/arm/sme-fa64.decode
31
+++ b/include/hw/arm/armsse.h
18
+++ b/target/arm/sme-fa64.decode
32
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
33
* hardware, which include the IoT Kit and the SSE-050, SSE-100 and
20
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
34
* SSE-200. Currently we model:
21
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
35
* - the Arm IoT Kit which is documented in
22
36
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
23
-FAIL 0100 0101 000- ---- 0110 1--- ---- ---- # PMULLB, PMULLT (128b result)
37
+ * https://developer.arm.com/documentation/ecm0601256/latest
24
-FAIL 0110 0100 --1- ---- 1110 01-- ---- ---- # FMMLA, BFMMLA
38
* - the SSE-200 which is documented in
25
FAIL 0110 0101 --0- ---- 0000 11-- ---- ---- # FTSMUL
39
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
26
FAIL 0110 0101 --01 0--- 100- ---- ---- ---- # FTMAD
40
+ * https://developer.arm.com/documentation/101104/latest/
27
FAIL 0110 0101 --01 1--- 001- ---- ---- ---- # FADDA
41
*
28
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
42
* The IoTKit contains:
43
* a Cortex-M33
44
diff --git a/include/hw/misc/armsse-cpuid.h b/include/hw/misc/armsse-cpuid.h
45
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
46
--- a/include/hw/misc/armsse-cpuid.h
30
--- a/target/arm/translate-sve.c
47
+++ b/include/hw/misc/armsse-cpuid.h
31
+++ b/target/arm/translate-sve.c
48
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@ static bool do_trans_pmull(DisasContext *s, arg_rrr_esz *a, bool sel)
49
/*
33
gen_helper_gvec_pmull_q, gen_helper_sve2_pmull_h,
50
* This is a model of the "CPU_IDENTITY" register block which is part of the
34
NULL, gen_helper_sve2_pmull_d,
51
* Arm SSE-200 and documented in
35
};
52
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
36
- if (a->esz == 0
53
+ * https://developer.arm.com/documentation/101104/latest/
37
- ? !dc_isar_feature(aa64_sve2_pmull128, s)
54
*
38
- : !dc_isar_feature(aa64_sve, s)) {
55
* QEMU interface:
39
+
56
* + QOM property "CPUID": the value to use for the CPUID register
40
+ if (a->esz == 0) {
57
diff --git a/include/hw/misc/armsse-mhu.h b/include/hw/misc/armsse-mhu.h
41
+ if (!dc_isar_feature(aa64_sve2_pmull128, s)) {
58
index XXXXXXX..XXXXXXX 100644
42
+ return false;
59
--- a/include/hw/misc/armsse-mhu.h
43
+ }
60
+++ b/include/hw/misc/armsse-mhu.h
44
+ s->is_nonstreaming = true;
61
@@ -XXX,XX +XXX,XX @@
45
+ } else if (!dc_isar_feature(aa64_sve, s)) {
62
/*
46
return false;
63
* This is a model of the Message Handling Unit (MHU) which is part of the
47
}
64
* Arm SSE-200 and documented in
48
return gen_gvec_ool_arg_zzz(s, fns[a->esz], a, sel);
65
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
49
@@ -XXX,XX +XXX,XX @@ DO_ZPZZ_FP(FMINP, aa64_sve2, sve2_fminp_zpzz)
66
+ * https://developer.arm.com/documentation/101104/latest/
50
* SVE Integer Multiply-Add (unpredicated)
67
*
68
* QEMU interface:
69
* + sysbus MMIO region 0: the system information register bank
70
diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h
71
index XXXXXXX..XXXXXXX 100644
72
--- a/include/hw/misc/iotkit-secctl.h
73
+++ b/include/hw/misc/iotkit-secctl.h
74
@@ -XXX,XX +XXX,XX @@
75
76
/* This is a model of the security controller which is part of the
77
* Arm IoT Kit and documented in
78
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
79
+ * https://developer.arm.com/documentation/ecm0601256/latest
80
*
81
* QEMU interface:
82
* + sysbus MMIO region 0 is the "secure privilege control block" registers
83
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
84
index XXXXXXX..XXXXXXX 100644
85
--- a/include/hw/misc/iotkit-sysctl.h
86
+++ b/include/hw/misc/iotkit-sysctl.h
87
@@ -XXX,XX +XXX,XX @@
88
/*
89
* This is a model of the "system control element" which is part of the
90
* Arm IoTKit and documented in
91
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
92
+ * https://developer.arm.com/documentation/ecm0601256/latest
93
* Specifically, it implements the "system information block" and
94
* "system control register" blocks.
95
*
96
diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
97
index XXXXXXX..XXXXXXX 100644
98
--- a/include/hw/misc/iotkit-sysinfo.h
99
+++ b/include/hw/misc/iotkit-sysinfo.h
100
@@ -XXX,XX +XXX,XX @@
101
/*
102
* This is a model of the "system information block" which is part of the
103
* Arm IoTKit and documented in
104
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
105
+ * https://developer.arm.com/documentation/ecm0601256/latest
106
* QEMU interface:
107
* + QOM property "SYS_VERSION": value to use for SYS_VERSION register
108
* + QOM property "SYS_CONFIG": value to use for SYS_CONFIG register
109
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
110
index XXXXXXX..XXXXXXX 100644
111
--- a/include/hw/misc/mps2-fpgaio.h
112
+++ b/include/hw/misc/mps2-fpgaio.h
113
@@ -XXX,XX +XXX,XX @@
114
/* This is a model of the FPGAIO register block in the AN505
115
* FPGA image for the MPS2 dev board; it is documented in the
116
* application note:
117
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
118
+ * https://developer.arm.com/documentation/dai0505/latest/
119
*
120
* QEMU interface:
121
* + sysbus MMIO region 0: the register bank
122
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/hw/arm/mps2-tz.c
125
+++ b/hw/arm/mps2-tz.c
126
@@ -XXX,XX +XXX,XX @@
127
* https://developer.arm.com/products/system-design/development-boards/fpga-prototyping-boards/mps2
128
*
129
* Board TRM:
130
- * http://infocenter.arm.com/help/topic/com.arm.doc.100112_0200_06_en/versatile_express_cortex_m_prototyping_systems_v2m_mps2_and_v2m_mps2plus_technical_reference_100112_0200_06_en.pdf
131
+ * https://developer.arm.com/documentation/100112/latest/
132
* Application Note AN505:
133
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
134
+ * https://developer.arm.com/documentation/dai0505/latest/
135
* Application Note AN521:
136
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0521c/index.html
137
+ * https://developer.arm.com/documentation/dai0521/latest/
138
* Application Note AN524:
139
* https://developer.arm.com/documentation/dai0524/latest/
140
*
141
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
142
* (ARM ECM0601256) for the details of some of the device layout:
143
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
144
+ * https://developer.arm.com/documentation/ecm0601256/latest
145
* Similarly, the AN521 and AN524 use the SSE-200, and the SSE-200 TRM defines
146
* most of the device layout:
147
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
148
- *
149
+ * https://developer.arm.com/documentation/101104/latest/
150
*/
51
*/
151
52
152
#include "qemu/osdep.h"
53
-TRANS_FEAT(FMMLA_s, aa64_sve_f32mm, gen_gvec_fpst_zzzz, gen_helper_fmmla_s,
153
diff --git a/hw/misc/armsse-cpuid.c b/hw/misc/armsse-cpuid.c
54
- a->rd, a->rn, a->rm, a->ra, 0, FPST_FPCR)
154
index XXXXXXX..XXXXXXX 100644
55
-TRANS_FEAT(FMMLA_d, aa64_sve_f64mm, gen_gvec_fpst_zzzz, gen_helper_fmmla_d,
155
--- a/hw/misc/armsse-cpuid.c
56
- a->rd, a->rn, a->rm, a->ra, 0, FPST_FPCR)
156
+++ b/hw/misc/armsse-cpuid.c
57
+TRANS_FEAT_NONSTREAMING(FMMLA_s, aa64_sve_f32mm, gen_gvec_fpst_zzzz,
157
@@ -XXX,XX +XXX,XX @@
58
+ gen_helper_fmmla_s, a->rd, a->rn, a->rm, a->ra,
158
/*
59
+ 0, FPST_FPCR)
159
* This is a model of the "CPU_IDENTITY" register block which is part of the
60
+TRANS_FEAT_NONSTREAMING(FMMLA_d, aa64_sve_f64mm, gen_gvec_fpst_zzzz,
160
* Arm SSE-200 and documented in
61
+ gen_helper_fmmla_d, a->rd, a->rn, a->rm, a->ra,
161
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
62
+ 0, FPST_FPCR)
162
+ * https://developer.arm.com/documentation/101104/latest/
63
163
*
64
static gen_helper_gvec_4 * const sqdmlal_zzzw_fns[] = {
164
* It consists of one read-only CPUID register (set by QOM property), plus the
65
NULL, gen_helper_sve2_sqdmlal_zzzw_h,
165
* usual ID registers.
66
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(BFDOT_zzzz, aa64_sve_bf16, gen_gvec_ool_arg_zzzz,
166
diff --git a/hw/misc/armsse-mhu.c b/hw/misc/armsse-mhu.c
67
TRANS_FEAT(BFDOT_zzxz, aa64_sve_bf16, gen_gvec_ool_arg_zzxz,
167
index XXXXXXX..XXXXXXX 100644
68
gen_helper_gvec_bfdot_idx, a)
168
--- a/hw/misc/armsse-mhu.c
69
169
+++ b/hw/misc/armsse-mhu.c
70
-TRANS_FEAT(BFMMLA, aa64_sve_bf16, gen_gvec_ool_arg_zzzz,
170
@@ -XXX,XX +XXX,XX @@
71
- gen_helper_gvec_bfmmla, a, 0)
171
/*
72
+TRANS_FEAT_NONSTREAMING(BFMMLA, aa64_sve_bf16, gen_gvec_ool_arg_zzzz,
172
* This is a model of the Message Handling Unit (MHU) which is part of the
73
+ gen_helper_gvec_bfmmla, a, 0)
173
* Arm SSE-200 and documented in
74
174
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
75
static bool do_BFMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel)
175
+ * https://developer.arm.com/documentation/101104/latest/
76
{
176
*/
177
178
#include "qemu/osdep.h"
179
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
180
index XXXXXXX..XXXXXXX 100644
181
--- a/hw/misc/iotkit-sysctl.c
182
+++ b/hw/misc/iotkit-sysctl.c
183
@@ -XXX,XX +XXX,XX @@
184
/*
185
* This is a model of the "system control element" which is part of the
186
* Arm IoTKit and documented in
187
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
188
+ * https://developer.arm.com/documentation/ecm0601256/latest
189
* Specifically, it implements the "system control register" blocks.
190
*/
191
192
diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/hw/misc/iotkit-sysinfo.c
195
+++ b/hw/misc/iotkit-sysinfo.c
196
@@ -XXX,XX +XXX,XX @@
197
/*
198
* This is a model of the "system information block" which is part of the
199
* Arm IoTKit and documented in
200
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
201
+ * https://developer.arm.com/documentation/ecm0601256/latest
202
* It consists of 2 read-only version/config registers, plus the
203
* usual ID registers.
204
*/
205
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
206
index XXXXXXX..XXXXXXX 100644
207
--- a/hw/misc/mps2-fpgaio.c
208
+++ b/hw/misc/mps2-fpgaio.c
209
@@ -XXX,XX +XXX,XX @@
210
/* This is a model of the "FPGA system control and I/O" block found
211
* in the AN505 FPGA image for the MPS2 devboard.
212
* It is documented in AN505:
213
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
214
+ * https://developer.arm.com/documentation/dai0505/latest/
215
*/
216
217
#include "qemu/osdep.h"
218
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
219
index XXXXXXX..XXXXXXX 100644
220
--- a/hw/misc/mps2-scc.c
221
+++ b/hw/misc/mps2-scc.c
222
@@ -XXX,XX +XXX,XX @@
223
* found in the FPGA images of MPS2 development boards.
224
*
225
* Documentation of it can be found in the MPS2 TRM:
226
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100112_0100_03_en/index.html
227
+ * https://developer.arm.com/documentation/100112/latest/
228
* and also in the Application Notes documenting individual FPGA images.
229
*/
230
231
--
77
--
232
2.20.1
78
2.25.1
233
234
diff view generated by jsdifflib
1
Add brief documentation of the new mps3-an524 board.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Mark these as a non-streaming instructions, which should trap
4
if full a64 support is not enabled in streaming mode.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-9-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210215115138.20465-24-peter.maydell@linaro.org
7
---
10
---
8
docs/system/arm/mps2.rst | 24 ++++++++++++++++++------
11
target/arm/sme-fa64.decode | 3 ---
9
1 file changed, 18 insertions(+), 6 deletions(-)
12
target/arm/translate-sve.c | 15 +++++++++++----
13
2 files changed, 11 insertions(+), 7 deletions(-)
10
14
11
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/docs/system/arm/mps2.rst
17
--- a/target/arm/sme-fa64.decode
14
+++ b/docs/system/arm/mps2.rst
18
+++ b/target/arm/sme-fa64.decode
15
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
16
-Arm MPS2 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``)
20
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
17
-================================================================================================================
21
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
18
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``)
22
19
+=========================================================================================================================================
23
-FAIL 0110 0101 --0- ---- 0000 11-- ---- ---- # FTSMUL
20
24
-FAIL 0110 0101 --01 0--- 100- ---- ---- ---- # FTMAD
21
These board models all use Arm M-profile CPUs.
25
-FAIL 0110 0101 --01 1--- 001- ---- ---- ---- # FADDA
22
26
FAIL 0100 0101 --0- ---- 1001 10-- ---- ---- # SMMLA, UMMLA, USMMLA
23
-The Arm MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger
27
FAIL 0100 0101 --1- ---- 1--- ---- ---- ---- # SVE2 string/histo/crypto instructions
24
-FPGA but is otherwise the same as the 2). Since the CPU itself
28
FAIL 1000 010- -00- ---- 10-- ---- ---- ---- # SVE2 32-bit gather NT load (vector+scalar)
25
-and most of the devices are in the FPGA, the details of the board
29
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
26
-as seen by the guest depend significantly on the FPGA image.
30
index XXXXXXX..XXXXXXX 100644
27
+The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
31
--- a/target/arm/translate-sve.c
28
+bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
32
+++ b/target/arm/translate-sve.c
29
+FPGA again, can handle 4GB of RAM and has a USB controller and QSPI flash).
33
@@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3_ptr * const ftmad_fns[4] = {
34
NULL, gen_helper_sve_ftmad_h,
35
gen_helper_sve_ftmad_s, gen_helper_sve_ftmad_d,
36
};
37
-TRANS_FEAT(FTMAD, aa64_sve, gen_gvec_fpst_zzz,
38
- ftmad_fns[a->esz], a->rd, a->rn, a->rm, a->imm,
39
- a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR)
40
+TRANS_FEAT_NONSTREAMING(FTMAD, aa64_sve, gen_gvec_fpst_zzz,
41
+ ftmad_fns[a->esz], a->rd, a->rn, a->rm, a->imm,
42
+ a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR)
43
44
/*
45
*** SVE Floating Point Accumulating Reduction Group
46
@@ -XXX,XX +XXX,XX @@ static bool trans_FADDA(DisasContext *s, arg_rprr_esz *a)
47
if (a->esz == 0 || !dc_isar_feature(aa64_sve, s)) {
48
return false;
49
}
50
+ s->is_nonstreaming = true;
51
if (!sve_access_check(s)) {
52
return true;
53
}
54
@@ -XXX,XX +XXX,XX @@ static bool trans_FADDA(DisasContext *s, arg_rprr_esz *a)
55
DO_FP3(FADD_zzz, fadd)
56
DO_FP3(FSUB_zzz, fsub)
57
DO_FP3(FMUL_zzz, fmul)
58
-DO_FP3(FTSMUL, ftsmul)
59
DO_FP3(FRECPS, recps)
60
DO_FP3(FRSQRTS, rsqrts)
61
62
#undef DO_FP3
63
64
+static gen_helper_gvec_3_ptr * const ftsmul_fns[4] = {
65
+ NULL, gen_helper_gvec_ftsmul_h,
66
+ gen_helper_gvec_ftsmul_s, gen_helper_gvec_ftsmul_d
67
+};
68
+TRANS_FEAT_NONSTREAMING(FTSMUL, aa64_sve, gen_gvec_fpst_arg_zzz,
69
+ ftsmul_fns[a->esz], a, 0)
30
+
70
+
31
+Since the CPU itself and most of the devices are in the FPGA, the
71
/*
32
+details of the board as seen by the guest depend significantly on the
72
*** SVE Floating Point Arithmetic - Predicated Group
33
+FPGA image.
73
*/
34
35
QEMU models the following FPGA images:
36
37
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
38
Cortex-M3 'DesignStart' as documented in Arm Application Note AN511
39
``mps2-an521``
40
Dual Cortex-M33 as documented in Arm Application Note AN521
41
+``mps3-an524``
42
+ Dual Cortex-M33 on an MPS3, as documented in Arm Application Note AN524
43
44
Differences between QEMU and real hardware:
45
46
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
47
block RAM is unimplemented (QEMU always maps this to ZBT SSRAM1, as
48
if zbt_boot_ctrl is always zero)
49
+- AN524 remapping of low memory to either BRAM or to QSPI flash is
50
+ unimplemented (QEMU always maps this to BRAM, ignoring the
51
+ SCC CFG_REG0 memory-remap bit)
52
- QEMU provides a LAN9118 ethernet rather than LAN9220; the only guest
53
visible difference is that the LAN9118 doesn't support checksum
54
offloading
55
+- QEMU does not model the QSPI flash in MPS3 boards as real QSPI
56
+ flash, but only as simple ROM, so attempting to rewrite the flash
57
+ from the guest will fail
58
+- QEMU does not model the USB controller in MPS3 boards
59
--
74
--
60
2.20.1
75
2.25.1
61
62
diff view generated by jsdifflib
1
The AN505 and AN521 have the same device layout, but the AN524 is
1
From: Richard Henderson <richard.henderson@linaro.org>
2
somewhat different. Allow for more than one PPCInfo array, which can
3
be selected based on the board type.
4
2
3
Mark these as a non-streaming instructions, which should trap
4
if full a64 support is not enabled in streaming mode.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-10-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210215115138.20465-16-peter.maydell@linaro.org
8
---
10
---
9
hw/arm/mps2-tz.c | 16 ++++++++++++++--
11
target/arm/sme-fa64.decode | 1 -
10
1 file changed, 14 insertions(+), 2 deletions(-)
12
target/arm/translate-sve.c | 12 ++++++------
13
2 files changed, 6 insertions(+), 7 deletions(-)
11
14
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/mps2-tz.c
17
--- a/target/arm/sme-fa64.decode
15
+++ b/hw/arm/mps2-tz.c
18
+++ b/target/arm/sme-fa64.decode
16
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
17
MemoryRegion *system_memory = get_system_memory();
20
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
18
DeviceState *iotkitdev;
21
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
19
DeviceState *dev_splitter;
22
20
+ const PPCInfo *ppcs;
23
-FAIL 0100 0101 --0- ---- 1001 10-- ---- ---- # SMMLA, UMMLA, USMMLA
21
+ int num_ppcs;
24
FAIL 0100 0101 --1- ---- 1--- ---- ---- ---- # SVE2 string/histo/crypto instructions
22
int i;
25
FAIL 1000 010- -00- ---- 10-- ---- ---- ---- # SVE2 32-bit gather NT load (vector+scalar)
23
26
FAIL 1000 010- -00- ---- 111- ---- ---- ---- # SVE 32-bit gather prefetch (vector+imm)
24
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
27
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
25
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
28
index XXXXXXX..XXXXXXX 100644
26
* + wire up the PPC's control lines to the IoTKit object
29
--- a/target/arm/translate-sve.c
27
*/
30
+++ b/target/arm/translate-sve.c
28
31
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(FMLALT_zzxw, aa64_sve2, do_FMLAL_zzxw, a, false, true)
29
- const PPCInfo ppcs[] = { {
32
TRANS_FEAT(FMLSLB_zzxw, aa64_sve2, do_FMLAL_zzxw, a, true, false)
30
+ const PPCInfo an505_ppcs[] = { {
33
TRANS_FEAT(FMLSLT_zzxw, aa64_sve2, do_FMLAL_zzxw, a, true, true)
31
.name = "apb_ppcexp0",
34
32
.ports = {
35
-TRANS_FEAT(SMMLA, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz,
33
{ "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
36
- gen_helper_gvec_smmla_b, a, 0)
34
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
37
-TRANS_FEAT(USMMLA, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz,
35
},
38
- gen_helper_gvec_usmmla_b, a, 0)
36
};
39
-TRANS_FEAT(UMMLA, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz,
37
40
- gen_helper_gvec_ummla_b, a, 0)
38
- for (i = 0; i < ARRAY_SIZE(ppcs); i++) {
41
+TRANS_FEAT_NONSTREAMING(SMMLA, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz,
39
+ switch (mmc->fpga_type) {
42
+ gen_helper_gvec_smmla_b, a, 0)
40
+ case FPGA_AN505:
43
+TRANS_FEAT_NONSTREAMING(USMMLA, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz,
41
+ case FPGA_AN521:
44
+ gen_helper_gvec_usmmla_b, a, 0)
42
+ ppcs = an505_ppcs;
45
+TRANS_FEAT_NONSTREAMING(UMMLA, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz,
43
+ num_ppcs = ARRAY_SIZE(an505_ppcs);
46
+ gen_helper_gvec_ummla_b, a, 0)
44
+ break;
47
45
+ default:
48
TRANS_FEAT(BFDOT_zzzz, aa64_sve_bf16, gen_gvec_ool_arg_zzzz,
46
+ g_assert_not_reached();
49
gen_helper_gvec_bfdot, a, 0)
47
+ }
48
+
49
+ for (i = 0; i < num_ppcs; i++) {
50
const PPCInfo *ppcinfo = &ppcs[i];
51
TZPPC *ppc = &mms->ppc[i];
52
DeviceState *ppcdev;
53
--
50
--
54
2.20.1
51
2.25.1
55
56
diff view generated by jsdifflib
1
We create an OR gate to wire together the overflow IRQs for all the
1
From: Richard Henderson <richard.henderson@linaro.org>
2
UARTs on the board; this has to have twice the number of inputs as
3
there are UARTs, since each UART feeds it a TX overflow and an RX
4
overflow interrupt line. Replace the hardcoded '10' with a
5
calculation based on the size of the uart[] array in the
6
MPS2TZMachineState. (We rely on OR gate inputs that are never wired
7
up or asserted being treated as always-zero.)
8
2
3
Mark these as non-streaming instructions, which should trap
4
if full a64 support is not enabled in streaming mode.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-11-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210215115138.20465-15-peter.maydell@linaro.org
12
---
10
---
13
hw/arm/mps2-tz.c | 11 ++++++++---
11
target/arm/sme-fa64.decode | 1 -
14
1 file changed, 8 insertions(+), 3 deletions(-)
12
target/arm/translate-sve.c | 35 ++++++++++++++++++-----------------
13
2 files changed, 18 insertions(+), 18 deletions(-)
15
14
16
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/mps2-tz.c
17
--- a/target/arm/sme-fa64.decode
19
+++ b/hw/arm/mps2-tz.c
18
+++ b/target/arm/sme-fa64.decode
20
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
21
*/
20
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
22
memory_region_add_subregion(system_memory, 0x80000000, machine->ram);
21
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
23
22
24
- /* The overflow IRQs for all UARTs are ORed together.
23
-FAIL 0100 0101 --1- ---- 1--- ---- ---- ---- # SVE2 string/histo/crypto instructions
25
+ /*
24
FAIL 1000 010- -00- ---- 10-- ---- ---- ---- # SVE2 32-bit gather NT load (vector+scalar)
26
+ * The overflow IRQs for all UARTs are ORed together.
25
FAIL 1000 010- -00- ---- 111- ---- ---- ---- # SVE 32-bit gather prefetch (vector+imm)
27
* Tx, Rx and "combined" IRQs are sent to the NVIC separately.
26
FAIL 1000 0100 0-1- ---- 0--- ---- ---- ---- # SVE 32-bit gather prefetch (scalar+vector)
28
- * Create the OR gate for this.
27
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
29
+ * Create the OR gate for this: it has one input for the TX overflow
28
index XXXXXXX..XXXXXXX 100644
30
+ * and one for the RX overflow for each UART we might have.
29
--- a/target/arm/translate-sve.c
31
+ * (If the board has fewer than the maximum possible number of UARTs
30
+++ b/target/arm/translate-sve.c
32
+ * those inputs are never wired up and are treated as always-zero.)
31
@@ -XXX,XX +XXX,XX @@ DO_SVE2_ZZZ_NARROW(RSUBHNT, rsubhnt)
33
*/
32
static gen_helper_gvec_flags_4 * const match_fns[4] = {
34
object_initialize_child(OBJECT(mms), "uart-irq-orgate",
33
gen_helper_sve2_match_ppzz_b, gen_helper_sve2_match_ppzz_h, NULL, NULL
35
&mms->uart_irq_orgate, TYPE_OR_IRQ);
34
};
36
- object_property_set_int(OBJECT(&mms->uart_irq_orgate), "num-lines", 10,
35
-TRANS_FEAT(MATCH, aa64_sve2, do_ppzz_flags, a, match_fns[a->esz])
37
+ object_property_set_int(OBJECT(&mms->uart_irq_orgate), "num-lines",
36
+TRANS_FEAT_NONSTREAMING(MATCH, aa64_sve2, do_ppzz_flags, a, match_fns[a->esz])
38
+ 2 * ARRAY_SIZE(mms->uart),
37
39
&error_fatal);
38
static gen_helper_gvec_flags_4 * const nmatch_fns[4] = {
40
qdev_realize(DEVICE(&mms->uart_irq_orgate), NULL, &error_fatal);
39
gen_helper_sve2_nmatch_ppzz_b, gen_helper_sve2_nmatch_ppzz_h, NULL, NULL
41
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
40
};
41
-TRANS_FEAT(NMATCH, aa64_sve2, do_ppzz_flags, a, nmatch_fns[a->esz])
42
+TRANS_FEAT_NONSTREAMING(NMATCH, aa64_sve2, do_ppzz_flags, a, nmatch_fns[a->esz])
43
44
static gen_helper_gvec_4 * const histcnt_fns[4] = {
45
NULL, NULL, gen_helper_sve2_histcnt_s, gen_helper_sve2_histcnt_d
46
};
47
-TRANS_FEAT(HISTCNT, aa64_sve2, gen_gvec_ool_arg_zpzz,
48
- histcnt_fns[a->esz], a, 0)
49
+TRANS_FEAT_NONSTREAMING(HISTCNT, aa64_sve2, gen_gvec_ool_arg_zpzz,
50
+ histcnt_fns[a->esz], a, 0)
51
52
-TRANS_FEAT(HISTSEG, aa64_sve2, gen_gvec_ool_arg_zzz,
53
- a->esz == 0 ? gen_helper_sve2_histseg : NULL, a, 0)
54
+TRANS_FEAT_NONSTREAMING(HISTSEG, aa64_sve2, gen_gvec_ool_arg_zzz,
55
+ a->esz == 0 ? gen_helper_sve2_histseg : NULL, a, 0)
56
57
DO_ZPZZ_FP(FADDP, aa64_sve2, sve2_faddp_zpzz)
58
DO_ZPZZ_FP(FMAXNMP, aa64_sve2, sve2_fmaxnmp_zpzz)
59
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(SQRDCMLAH_zzzz, aa64_sve2, gen_gvec_ool_zzzz,
60
TRANS_FEAT(USDOT_zzzz, aa64_sve_i8mm, gen_gvec_ool_arg_zzzz,
61
a->esz == 2 ? gen_helper_gvec_usdot_b : NULL, a, 0)
62
63
-TRANS_FEAT(AESMC, aa64_sve2_aes, gen_gvec_ool_zz,
64
- gen_helper_crypto_aesmc, a->rd, a->rd, a->decrypt)
65
+TRANS_FEAT_NONSTREAMING(AESMC, aa64_sve2_aes, gen_gvec_ool_zz,
66
+ gen_helper_crypto_aesmc, a->rd, a->rd, a->decrypt)
67
68
-TRANS_FEAT(AESE, aa64_sve2_aes, gen_gvec_ool_arg_zzz,
69
- gen_helper_crypto_aese, a, false)
70
-TRANS_FEAT(AESD, aa64_sve2_aes, gen_gvec_ool_arg_zzz,
71
- gen_helper_crypto_aese, a, true)
72
+TRANS_FEAT_NONSTREAMING(AESE, aa64_sve2_aes, gen_gvec_ool_arg_zzz,
73
+ gen_helper_crypto_aese, a, false)
74
+TRANS_FEAT_NONSTREAMING(AESD, aa64_sve2_aes, gen_gvec_ool_arg_zzz,
75
+ gen_helper_crypto_aese, a, true)
76
77
-TRANS_FEAT(SM4E, aa64_sve2_sm4, gen_gvec_ool_arg_zzz,
78
- gen_helper_crypto_sm4e, a, 0)
79
-TRANS_FEAT(SM4EKEY, aa64_sve2_sm4, gen_gvec_ool_arg_zzz,
80
- gen_helper_crypto_sm4ekey, a, 0)
81
+TRANS_FEAT_NONSTREAMING(SM4E, aa64_sve2_sm4, gen_gvec_ool_arg_zzz,
82
+ gen_helper_crypto_sm4e, a, 0)
83
+TRANS_FEAT_NONSTREAMING(SM4EKEY, aa64_sve2_sm4, gen_gvec_ool_arg_zzz,
84
+ gen_helper_crypto_sm4ekey, a, 0)
85
86
-TRANS_FEAT(RAX1, aa64_sve2_sha3, gen_gvec_fn_arg_zzz, gen_gvec_rax1, a)
87
+TRANS_FEAT_NONSTREAMING(RAX1, aa64_sve2_sha3, gen_gvec_fn_arg_zzz,
88
+ gen_gvec_rax1, a)
89
90
TRANS_FEAT(FCVTNT_sh, aa64_sve2, gen_gvec_fpst_arg_zpz,
91
gen_helper_sve2_fcvtnt_sh, a, 0, FPST_FPCR)
42
--
92
--
43
2.20.1
93
2.25.1
44
45
diff view generated by jsdifflib
1
The AN524 has more interrupt lines than the AN505 and AN521; make
1
From: Richard Henderson <richard.henderson@linaro.org>
2
numirq board-specific rather than a compile-time constant.
3
2
4
Since the difference is small (92 on the current boards and 95 on the
3
Mark these as a non-streaming instructions, which should trap
5
new one) we don't dynamically allocate the cpu_irq_splitter[] array
4
if full a64 support is not enabled in streaming mode.
6
but leave it as a fixed length array whose size is the maximum needed
7
for any of the boards.
8
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-12-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210215115138.20465-10-peter.maydell@linaro.org
13
---
10
---
14
hw/arm/mps2-tz.c | 15 ++++++++++-----
11
target/arm/sme-fa64.decode | 9 ---------
15
1 file changed, 10 insertions(+), 5 deletions(-)
12
target/arm/translate-sve.c | 6 ++++++
13
2 files changed, 6 insertions(+), 9 deletions(-)
16
14
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/mps2-tz.c
17
--- a/target/arm/sme-fa64.decode
20
+++ b/hw/arm/mps2-tz.c
18
+++ b/target/arm/sme-fa64.decode
21
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
22
#include "hw/qdev-clock.h"
20
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
23
#include "qom/object.h"
21
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
24
22
25
-#define MPS2TZ_NUMIRQ 92
23
-FAIL 1000 010- -00- ---- 10-- ---- ---- ---- # SVE2 32-bit gather NT load (vector+scalar)
26
+#define MPS2TZ_NUMIRQ_MAX 92
24
FAIL 1000 010- -00- ---- 111- ---- ---- ---- # SVE 32-bit gather prefetch (vector+imm)
27
25
FAIL 1000 0100 0-1- ---- 0--- ---- ---- ---- # SVE 32-bit gather prefetch (scalar+vector)
28
typedef enum MPS2TZFPGAType {
26
-FAIL 1000 010- -01- ---- 1--- ---- ---- ---- # SVE 32-bit gather load (vector+imm)
29
FPGA_AN505,
27
-FAIL 1000 0100 0-0- ---- 0--- ---- ---- ---- # SVE 32-bit gather load byte (scalar+vector)
30
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
28
-FAIL 1000 0100 1--- ---- 0--- ---- ---- ---- # SVE 32-bit gather load half (scalar+vector)
31
const uint32_t *oscclk;
29
-FAIL 1000 0101 0--- ---- 0--- ---- ---- ---- # SVE 32-bit gather load word (scalar+vector)
32
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
30
FAIL 1010 010- ---- ---- 011- ---- ---- ---- # SVE contiguous FF load (scalar+scalar)
33
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
31
FAIL 1010 010- ---1 ---- 101- ---- ---- ---- # SVE contiguous NF load (scalar+imm)
34
+ int numirq; /* Number of external interrupts */
32
FAIL 1010 010- -01- ---- 000- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+scalar)
35
const char *armsse_type;
33
FAIL 1010 010- -010 ---- 001- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+imm)
36
};
34
FAIL 1100 010- ---- ---- ---- ---- ---- ---- # SVE 64-bit gather load/prefetch
37
35
-FAIL 1110 010- -00- ---- 001- ---- ---- ---- # SVE2 64-bit scatter NT store (vector+scalar)
38
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
36
-FAIL 1110 010- -10- ---- 001- ---- ---- ---- # SVE2 32-bit scatter NT store (vector+scalar)
39
SplitIRQ sec_resp_splitter;
37
-FAIL 1110 010- ---- ---- 1-0- ---- ---- ---- # SVE scatter store (scalar+32-bit vector)
40
qemu_or_irq uart_irq_orgate;
38
-FAIL 1110 010- ---- ---- 101- ---- ---- ---- # SVE scatter store (misc)
41
DeviceState *lan9118;
39
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
42
- SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ];
40
index XXXXXXX..XXXXXXX 100644
43
+ SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ_MAX];
41
--- a/target/arm/translate-sve.c
44
Clock *sysclk;
42
+++ b/target/arm/translate-sve.c
45
Clock *s32kclk;
43
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1_zprz(DisasContext *s, arg_LD1_zprz *a)
46
};
44
if (!dc_isar_feature(aa64_sve, s)) {
47
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
45
return false;
48
{
46
}
49
/* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
47
+ s->is_nonstreaming = true;
50
MachineClass *mc = MACHINE_GET_CLASS(mms);
48
if (!sve_access_check(s)) {
51
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
49
return true;
52
50
}
53
- assert(irqno < MPS2TZ_NUMIRQ);
51
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1_zpiz(DisasContext *s, arg_LD1_zpiz *a)
54
+ assert(irqno < mmc->numirq);
52
if (!dc_isar_feature(aa64_sve, s)) {
55
53
return false;
56
if (mc->max_cpus > 1) {
54
}
57
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
55
+ s->is_nonstreaming = true;
58
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
56
if (!sve_access_check(s)) {
59
iotkitdev = DEVICE(&mms->iotkit);
57
return true;
60
object_property_set_link(OBJECT(&mms->iotkit), "memory",
58
}
61
OBJECT(system_memory), &error_abort);
59
@@ -XXX,XX +XXX,XX @@ static bool trans_LDNT1_zprz(DisasContext *s, arg_LD1_zprz *a)
62
- qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
60
if (!dc_isar_feature(aa64_sve2, s)) {
63
+ qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", mmc->numirq);
61
return false;
64
qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
62
}
65
qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
63
+ s->is_nonstreaming = true;
66
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
64
if (!sve_access_check(s)) {
67
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
65
return true;
68
* board. If there is only one CPU, we can just wire the device IRQ
66
}
69
* directly to the SSE's IRQ input.
67
@@ -XXX,XX +XXX,XX @@ static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a)
70
*/
68
if (!dc_isar_feature(aa64_sve, s)) {
71
+ assert(mmc->numirq <= MPS2TZ_NUMIRQ_MAX);
69
return false;
72
if (mc->max_cpus > 1) {
70
}
73
- for (i = 0; i < MPS2TZ_NUMIRQ; i++) {
71
+ s->is_nonstreaming = true;
74
+ for (i = 0; i < mmc->numirq; i++) {
72
if (!sve_access_check(s)) {
75
char *name = g_strdup_printf("mps2-irq-splitter%d", i);
73
return true;
76
SplitIRQ *splitter = &mms->cpu_irq_splitter[i];
74
}
77
75
@@ -XXX,XX +XXX,XX @@ static bool trans_ST1_zpiz(DisasContext *s, arg_ST1_zpiz *a)
78
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
76
if (!dc_isar_feature(aa64_sve, s)) {
79
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
77
return false;
80
mmc->fpgaio_num_leds = 2;
78
}
81
mmc->fpgaio_has_switches = false;
79
+ s->is_nonstreaming = true;
82
+ mmc->numirq = 92;
80
if (!sve_access_check(s)) {
83
mmc->armsse_type = TYPE_IOTKIT;
81
return true;
84
}
82
}
85
83
@@ -XXX,XX +XXX,XX @@ static bool trans_STNT1_zprz(DisasContext *s, arg_ST1_zprz *a)
86
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
84
if (!dc_isar_feature(aa64_sve2, s)) {
87
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
85
return false;
88
mmc->fpgaio_num_leds = 2;
86
}
89
mmc->fpgaio_has_switches = false;
87
+ s->is_nonstreaming = true;
90
+ mmc->numirq = 92;
88
if (!sve_access_check(s)) {
91
mmc->armsse_type = TYPE_SSE200;
89
return true;
92
}
90
}
93
94
--
91
--
95
2.20.1
92
2.25.1
96
97
diff view generated by jsdifflib
1
The AN524 has a PL031 RTC, which we have a model of; provide it
1
From: Richard Henderson <richard.henderson@linaro.org>
2
rather than an unimplemented-device stub.
3
2
3
Mark these as a non-streaming instructions, which should trap if full
4
a64 support is not enabled in streaming mode. In this case, introduce
5
PRF_ns (prefetch non-streaming) to handle the checks.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220708151540.18136-13-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210215115138.20465-23-peter.maydell@linaro.org
8
---
11
---
9
hw/arm/mps2-tz.c | 22 ++++++++++++++++++++--
12
target/arm/sme-fa64.decode | 3 ---
10
1 file changed, 20 insertions(+), 2 deletions(-)
13
target/arm/sve.decode | 10 +++++-----
14
target/arm/translate-sve.c | 11 +++++++++++
15
3 files changed, 16 insertions(+), 8 deletions(-)
11
16
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
17
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/mps2-tz.c
19
--- a/target/arm/sme-fa64.decode
15
+++ b/hw/arm/mps2-tz.c
20
+++ b/target/arm/sme-fa64.decode
16
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
17
#include "hw/misc/tz-msc.h"
22
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
18
#include "hw/arm/armsse.h"
23
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
19
#include "hw/dma/pl080.h"
24
20
+#include "hw/rtc/pl031.h"
25
-FAIL 1000 010- -00- ---- 111- ---- ---- ---- # SVE 32-bit gather prefetch (vector+imm)
21
#include "hw/ssi/pl022.h"
26
-FAIL 1000 0100 0-1- ---- 0--- ---- ---- ---- # SVE 32-bit gather prefetch (scalar+vector)
22
#include "hw/i2c/arm_sbcon_i2c.h"
27
FAIL 1010 010- ---- ---- 011- ---- ---- ---- # SVE contiguous FF load (scalar+scalar)
23
#include "hw/net/lan9118.h"
28
FAIL 1010 010- ---1 ---- 101- ---- ---- ---- # SVE contiguous NF load (scalar+imm)
24
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
29
FAIL 1010 010- -01- ---- 000- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+scalar)
25
UnimplementedDeviceState gpio[4];
30
FAIL 1010 010- -010 ---- 001- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+imm)
26
UnimplementedDeviceState gfx;
31
-FAIL 1100 010- ---- ---- ---- ---- ---- ---- # SVE 64-bit gather load/prefetch
27
UnimplementedDeviceState cldc;
32
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
28
- UnimplementedDeviceState rtc;
33
index XXXXXXX..XXXXXXX 100644
29
UnimplementedDeviceState usb;
34
--- a/target/arm/sve.decode
30
+ PL031State rtc;
35
+++ b/target/arm/sve.decode
31
PL080State dma[4];
36
@@ -XXX,XX +XXX,XX @@ LD1RO_zpri 1010010 .. 01 0.... 001 ... ..... ..... \
32
TZMSC msc[4];
37
@rpri_load_msz nreg=0
33
CMSDKAPBUART uart[6];
38
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
39
# SVE 32-bit gather prefetch (scalar plus 32-bit scaled offsets)
35
return sysbus_mmio_get_region(s, 0);
40
-PRF 1000010 00 -1 ----- 0-- --- ----- 0 ----
41
+PRF_ns 1000010 00 -1 ----- 0-- --- ----- 0 ----
42
43
# SVE 32-bit gather prefetch (vector plus immediate)
44
-PRF 1000010 -- 00 ----- 111 --- ----- 0 ----
45
+PRF_ns 1000010 -- 00 ----- 111 --- ----- 0 ----
46
47
# SVE contiguous prefetch (scalar plus immediate)
48
PRF 1000010 11 1- ----- 0-- --- ----- 0 ----
49
@@ -XXX,XX +XXX,XX @@ LD1_zpiz 1100010 .. 01 ..... 1.. ... ..... ..... \
50
@rpri_g_load esz=3
51
52
# SVE 64-bit gather prefetch (scalar plus 64-bit scaled offsets)
53
-PRF 1100010 00 11 ----- 1-- --- ----- 0 ----
54
+PRF_ns 1100010 00 11 ----- 1-- --- ----- 0 ----
55
56
# SVE 64-bit gather prefetch (scalar plus unpacked 32-bit scaled offsets)
57
-PRF 1100010 00 -1 ----- 0-- --- ----- 0 ----
58
+PRF_ns 1100010 00 -1 ----- 0-- --- ----- 0 ----
59
60
# SVE 64-bit gather prefetch (vector plus immediate)
61
-PRF 1100010 -- 00 ----- 111 --- ----- 0 ----
62
+PRF_ns 1100010 -- 00 ----- 111 --- ----- 0 ----
63
64
### SVE Memory Store Group
65
66
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate-sve.c
69
+++ b/target/arm/translate-sve.c
70
@@ -XXX,XX +XXX,XX @@ static bool trans_PRF_rr(DisasContext *s, arg_PRF_rr *a)
71
return true;
36
}
72
}
37
73
38
+static MemoryRegion *make_rtc(MPS2TZMachineState *mms, void *opaque,
74
+static bool trans_PRF_ns(DisasContext *s, arg_PRF_ns *a)
39
+ const char *name, hwaddr size,
40
+ const int *irqs)
41
+{
75
+{
42
+ PL031State *pl031 = opaque;
76
+ if (!dc_isar_feature(aa64_sve, s)) {
43
+ SysBusDevice *s;
77
+ return false;
44
+
78
+ }
45
+ object_initialize_child(OBJECT(mms), name, pl031, TYPE_PL031);
79
+ /* Prefetch is a nop within QEMU. */
46
+ s = SYS_BUS_DEVICE(pl031);
80
+ s->is_nonstreaming = true;
47
+ sysbus_realize(s, &error_fatal);
81
+ (void)sve_access_check(s);
48
+ /*
82
+ return true;
49
+ * The board docs don't give an IRQ number for the PL031, so
50
+ * presumably it is not connected.
51
+ */
52
+ return sysbus_mmio_get_region(s, 0);
53
+}
83
+}
54
+
84
+
55
static void create_non_mpc_ram(MPS2TZMachineState *mms)
85
/*
56
{
86
* Move Prefix
57
/*
87
*
58
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
59
60
{ /* port 9 reserved */ },
61
{ "clcd", make_unimp_dev, &mms->cldc, 0x4130a000, 0x1000 },
62
- { "rtc", make_unimp_dev, &mms->rtc, 0x4130b000, 0x1000 },
63
+ { "rtc", make_rtc, &mms->rtc, 0x4130b000, 0x1000 },
64
},
65
}, {
66
.name = "ahb_ppcexp0",
67
--
88
--
68
2.20.1
89
2.25.1
69
70
diff view generated by jsdifflib
1
MPS3 boards have an extra SWITCH register in the FPGAIO block which
1
From: Richard Henderson <richard.henderson@linaro.org>
2
reports the value of some switches. Implement this, governed by a
3
property the board code can use to specify whether whether it exists.
4
2
3
Mark these as a non-streaming instructions, which should trap
4
if full a64 support is not enabled in streaming mode.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-14-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-7-peter.maydell@linaro.org
9
---
10
---
10
include/hw/misc/mps2-fpgaio.h | 1 +
11
target/arm/sme-fa64.decode | 2 --
11
hw/misc/mps2-fpgaio.c | 10 ++++++++++
12
target/arm/translate-sve.c | 2 ++
12
2 files changed, 11 insertions(+)
13
2 files changed, 2 insertions(+), 2 deletions(-)
13
14
14
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/misc/mps2-fpgaio.h
17
--- a/target/arm/sme-fa64.decode
17
+++ b/include/hw/misc/mps2-fpgaio.h
18
+++ b/target/arm/sme-fa64.decode
18
@@ -XXX,XX +XXX,XX @@ struct MPS2FPGAIO {
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
19
MemoryRegion iomem;
20
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
20
LEDState *led[MPS2FPGAIO_MAX_LEDS];
21
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
21
uint32_t num_leds;
22
22
+ bool has_switches;
23
-FAIL 1010 010- ---- ---- 011- ---- ---- ---- # SVE contiguous FF load (scalar+scalar)
23
24
-FAIL 1010 010- ---1 ---- 101- ---- ---- ---- # SVE contiguous NF load (scalar+imm)
24
uint32_t led0;
25
FAIL 1010 010- -01- ---- 000- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+scalar)
25
uint32_t prescale;
26
FAIL 1010 010- -010 ---- 001- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+imm)
26
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
27
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
27
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/misc/mps2-fpgaio.c
29
--- a/target/arm/translate-sve.c
29
+++ b/hw/misc/mps2-fpgaio.c
30
+++ b/target/arm/translate-sve.c
30
@@ -XXX,XX +XXX,XX @@ REG32(CLK100HZ, 0x14)
31
@@ -XXX,XX +XXX,XX @@ static bool trans_LDFF1_zprr(DisasContext *s, arg_rprr_load *a)
31
REG32(COUNTER, 0x18)
32
if (!dc_isar_feature(aa64_sve, s)) {
32
REG32(PRESCALE, 0x1c)
33
return false;
33
REG32(PSCNTR, 0x20)
34
}
34
+REG32(SWITCH, 0x28)
35
+ s->is_nonstreaming = true;
35
REG32(MISC, 0x4c)
36
if (sve_access_check(s)) {
36
37
TCGv_i64 addr = new_tmp_a64(s);
37
static uint32_t counter_from_tickoff(int64_t now, int64_t tick_offset, int frq)
38
tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), dtype_msz(a->dtype));
38
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
39
@@ -XXX,XX +XXX,XX @@ static bool trans_LDNF1_zpri(DisasContext *s, arg_rpri_load *a)
39
resync_counter(s);
40
if (!dc_isar_feature(aa64_sve, s)) {
40
r = s->pscntr;
41
return false;
41
break;
42
}
42
+ case A_SWITCH:
43
+ s->is_nonstreaming = true;
43
+ if (!s->has_switches) {
44
if (sve_access_check(s)) {
44
+ goto bad_offset;
45
int vsz = vec_full_reg_size(s);
45
+ }
46
int elements = vsz >> dtype_esz[a->dtype];
46
+ /* User-togglable board switches. We don't model that, so report 0. */
47
+ r = 0;
48
+ break;
49
default:
50
+ bad_offset:
51
qemu_log_mask(LOG_GUEST_ERROR,
52
"MPS2 FPGAIO read: bad offset %x\n", (int) offset);
53
r = 0;
54
@@ -XXX,XX +XXX,XX @@ static Property mps2_fpgaio_properties[] = {
55
DEFINE_PROP_UINT32("prescale-clk", MPS2FPGAIO, prescale_clk, 20000000),
56
/* Number of LEDs controlled by LED0 register */
57
DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2),
58
+ DEFINE_PROP_BOOL("has-switches", MPS2FPGAIO, has_switches, false),
59
DEFINE_PROP_END_OF_LIST(),
60
};
61
62
--
47
--
63
2.20.1
48
2.25.1
64
65
diff view generated by jsdifflib
1
We were previously using the default OSCCLK settings, which are
1
From: Richard Henderson <richard.henderson@linaro.org>
2
correct for the older MPS2 boards (mps2-an385, mps2-an386,
3
mps2-an500, mps2-an511), but wrong for the mps2-an505 and mps2-511
4
implemented in mps2-tz.c. Now we're setting the values explicitly we
5
can fix them to be correct.
6
2
3
Mark these as a non-streaming instructions, which should trap
4
if full a64 support is not enabled in streaming mode.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-15-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210215115138.20465-4-peter.maydell@linaro.org
11
---
10
---
12
hw/arm/mps2-tz.c | 4 ++--
11
target/arm/sme-fa64.decode | 3 ---
13
1 file changed, 2 insertions(+), 2 deletions(-)
12
target/arm/translate-sve.c | 2 ++
13
2 files changed, 2 insertions(+), 3 deletions(-)
14
14
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
diff --git a/target/arm/sme-fa64.decode b/target/arm/sme-fa64.decode
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2-tz.c
17
--- a/target/arm/sme-fa64.decode
18
+++ b/hw/arm/mps2-tz.c
18
+++ b/target/arm/sme-fa64.decode
19
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
19
@@ -XXX,XX +XXX,XX @@ FAIL 0001 1110 0111 1110 0000 00-- ---- ---- # FJCVTZS
20
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
20
# --11 1100 --0- ---- ---- ---- ---- ---- # Load/store FP register (unscaled imm)
21
/* This will need to be per-FPGA image eventually */
21
# --11 1100 --1- ---- ---- ---- ---- --10 # Load/store FP register (register offset)
22
qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
22
# --11 1101 ---- ---- ---- ---- ---- ---- # Load/store FP register (scaled imm)
23
- qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
23
-
24
- qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
24
-FAIL 1010 010- -01- ---- 000- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+scalar)
25
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 40000000);
25
-FAIL 1010 010- -010 ---- 001- ---- ---- ---- # SVE load & replicate 32 bytes (scalar+imm)
26
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24580000);
26
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
27
qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
27
index XXXXXXX..XXXXXXX 100644
28
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
28
--- a/target/arm/translate-sve.c
29
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
29
+++ b/target/arm/translate-sve.c
30
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1RO_zprr(DisasContext *s, arg_rprr_load *a)
31
if (a->rm == 31) {
32
return false;
33
}
34
+ s->is_nonstreaming = true;
35
if (sve_access_check(s)) {
36
TCGv_i64 addr = new_tmp_a64(s);
37
tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), dtype_msz(a->dtype));
38
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1RO_zpri(DisasContext *s, arg_rpri_load *a)
39
if (!dc_isar_feature(aa64_sve_f64mm, s)) {
40
return false;
41
}
42
+ s->is_nonstreaming = true;
43
if (sve_access_check(s)) {
44
TCGv_i64 addr = new_tmp_a64(s);
45
tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn), a->imm * 32);
30
--
46
--
31
2.20.1
47
2.25.1
32
33
diff view generated by jsdifflib
1
The AN524 has a USB controller (an ISP1763); we don't have a model of
1
From: Richard Henderson <richard.henderson@linaro.org>
2
it but we should provide a stub "unimplemented-device" for it. This
3
is slightly complicated because the USB controller shares a PPC port
4
with the ethernet controller.
5
2
6
Implement a make_* function which provides creates a container
3
These functions will be used to verify that the cpu
7
MemoryRegion with both the ethernet controller and an
4
is in the correct state for a given instruction.
8
unimplemented-device stub for the USB controller.
9
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-16-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20210215115138.20465-22-peter.maydell@linaro.org
14
---
10
---
15
hw/arm/mps2-tz.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
11
target/arm/translate-a64.h | 21 +++++++++++++++++++++
16
1 file changed, 47 insertions(+), 1 deletion(-)
12
target/arm/translate-a64.c | 34 ++++++++++++++++++++++++++++++++++
13
2 files changed, 55 insertions(+)
17
14
18
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/mps2-tz.c
17
--- a/target/arm/translate-a64.h
21
+++ b/hw/arm/mps2-tz.c
18
+++ b/target/arm/translate-a64.h
22
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
19
@@ -XXX,XX +XXX,XX @@ void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v);
23
20
bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
24
ARMSSE iotkit;
21
unsigned int imms, unsigned int immr);
25
MemoryRegion ram[MPS2TZ_RAM_MAX];
22
bool sve_access_check(DisasContext *s);
26
+ MemoryRegion eth_usb_container;
23
+bool sme_enabled_check(DisasContext *s);
24
+bool sme_enabled_check_with_svcr(DisasContext *s, unsigned);
27
+
25
+
28
MPS2SCC scc;
26
+/* This function corresponds to CheckStreamingSVEEnabled. */
29
MPS2FPGAIO fpgaio;
27
+static inline bool sme_sm_enabled_check(DisasContext *s)
30
TZPPC ppc[5];
28
+{
31
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
29
+ return sme_enabled_check_with_svcr(s, R_SVCR_SM_MASK);
32
UnimplementedDeviceState gfx;
30
+}
33
UnimplementedDeviceState cldc;
31
+
34
UnimplementedDeviceState rtc;
32
+/* This function corresponds to CheckSMEAndZAEnabled. */
35
+ UnimplementedDeviceState usb;
33
+static inline bool sme_za_enabled_check(DisasContext *s)
36
PL080State dma[4];
34
+{
37
TZMSC msc[4];
35
+ return sme_enabled_check_with_svcr(s, R_SVCR_ZA_MASK);
38
CMSDKAPBUART uart[6];
36
+}
39
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
37
+
40
return sysbus_mmio_get_region(s, 0);
38
+/* Note that this function corresponds to CheckStreamingSVEAndZAEnabled. */
39
+static inline bool sme_smza_enabled_check(DisasContext *s)
40
+{
41
+ return sme_enabled_check_with_svcr(s, R_SVCR_SM_MASK | R_SVCR_ZA_MASK);
42
+}
43
+
44
TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr);
45
TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write,
46
bool tag_checked, int log2_size);
47
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/translate-a64.c
50
+++ b/target/arm/translate-a64.c
51
@@ -XXX,XX +XXX,XX @@ static bool sme_access_check(DisasContext *s)
52
return true;
41
}
53
}
42
54
43
+static MemoryRegion *make_eth_usb(MPS2TZMachineState *mms, void *opaque,
55
+/* This function corresponds to CheckSMEEnabled. */
44
+ const char *name, hwaddr size,
56
+bool sme_enabled_check(DisasContext *s)
45
+ const int *irqs)
46
+{
57
+{
47
+ /*
58
+ /*
48
+ * The AN524 makes the ethernet and USB share a PPC port.
59
+ * Note that unlike sve_excp_el, we have not constrained sme_excp_el
49
+ * irqs[] is the ethernet IRQ.
60
+ * to be zero when fp_excp_el has priority. This is because we need
61
+ * sme_excp_el by itself for cpregs access checks.
50
+ */
62
+ */
51
+ SysBusDevice *s;
63
+ if (!s->fp_excp_el || s->sme_excp_el < s->fp_excp_el) {
52
+ NICInfo *nd = &nd_table[0];
64
+ s->fp_access_checked = true;
53
+
65
+ return sme_access_check(s);
54
+ memory_region_init(&mms->eth_usb_container, OBJECT(mms),
66
+ }
55
+ "mps2-tz-eth-usb-container", 0x200000);
67
+ return fp_access_check_only(s);
56
+
57
+ /*
58
+ * In hardware this is a LAN9220; the LAN9118 is software compatible
59
+ * except that it doesn't support the checksum-offload feature.
60
+ */
61
+ qemu_check_nic_model(nd, "lan9118");
62
+ mms->lan9118 = qdev_new(TYPE_LAN9118);
63
+ qdev_set_nic_properties(mms->lan9118, nd);
64
+
65
+ s = SYS_BUS_DEVICE(mms->lan9118);
66
+ sysbus_realize_and_unref(s, &error_fatal);
67
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
68
+
69
+ memory_region_add_subregion(&mms->eth_usb_container,
70
+ 0, sysbus_mmio_get_region(s, 0));
71
+
72
+ /* The USB OTG controller is an ISP1763; we don't have a model of it. */
73
+ object_initialize_child(OBJECT(mms), "usb-otg",
74
+ &mms->usb, TYPE_UNIMPLEMENTED_DEVICE);
75
+ qdev_prop_set_string(DEVICE(&mms->usb), "name", "usb-otg");
76
+ qdev_prop_set_uint64(DEVICE(&mms->usb), "size", 0x100000);
77
+ s = SYS_BUS_DEVICE(&mms->usb);
78
+ sysbus_realize(s, &error_fatal);
79
+
80
+ memory_region_add_subregion(&mms->eth_usb_container,
81
+ 0x100000, sysbus_mmio_get_region(s, 0));
82
+
83
+ return &mms->eth_usb_container;
84
+}
68
+}
85
+
69
+
86
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
70
+/* Common subroutine for CheckSMEAnd*Enabled. */
87
const char *name, hwaddr size,
71
+bool sme_enabled_check_with_svcr(DisasContext *s, unsigned req)
88
const int *irqs)
72
+{
89
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
73
+ if (!sme_enabled_check(s)) {
90
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
74
+ return false;
91
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
75
+ }
92
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
76
+ if (FIELD_EX64(req, SVCR, SM) && !s->pstate_sm) {
93
- { "eth", make_eth_dev, NULL, 0x41400000, 0x100000, { 48 } },
77
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
94
+ { "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 48 } },
78
+ syn_smetrap(SME_ET_NotStreaming, false));
95
},
79
+ return false;
96
},
80
+ }
97
};
81
+ if (FIELD_EX64(req, SVCR, ZA) && !s->pstate_za) {
82
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
83
+ syn_smetrap(SME_ET_InactiveZA, false));
84
+ return false;
85
+ }
86
+ return true;
87
+}
88
+
89
/*
90
* This utility function is for doing register extension with an
91
* optional shift. You will likely want to pass a temporary for the
98
--
92
--
99
2.20.1
93
2.25.1
100
101
diff view generated by jsdifflib
1
The AN524 has a different SYSCLK frequency from the AN505 and AN521;
1
From: Richard Henderson <richard.henderson@linaro.org>
2
make the SYSCLK frequency a field in the MPS2TZMachineClass rather
3
than a compile-time constant so we can support the AN524.
4
2
3
The pseudocode for CheckSVEEnabled gains a check for Streaming
4
SVE mode, and for SME present but SVE absent.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-17-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-2-peter.maydell@linaro.org
9
---
10
---
10
hw/arm/mps2-tz.c | 10 ++++++----
11
target/arm/translate-a64.c | 22 ++++++++++++++++------
11
1 file changed, 6 insertions(+), 4 deletions(-)
12
1 file changed, 16 insertions(+), 6 deletions(-)
12
13
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
16
--- a/target/arm/translate-a64.c
16
+++ b/hw/arm/mps2-tz.c
17
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
18
@@ -XXX,XX +XXX,XX @@ static bool fp_access_check(DisasContext *s)
18
MachineClass parent;
19
return true;
19
MPS2TZFPGAType fpga_type;
20
}
20
uint32_t scc_id;
21
21
+ uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
22
-/* Check that SVE access is enabled. If it is, return true.
22
const char *armsse_type;
23
+/*
23
};
24
+ * Check that SVE access is enabled. If it is, return true.
24
25
* If not, emit code to generate an appropriate exception and return false.
25
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
26
+ * This function corresponds to CheckSVEEnabled().
26
27
*/
27
OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
28
bool sve_access_check(DisasContext *s)
28
29
-/* Main SYSCLK frequency in Hz */
30
-#define SYSCLK_FRQ 20000000
31
/* Slow 32Khz S32KCLK frequency in Hz */
32
#define S32KCLK_FRQ (32 * 1000)
33
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
35
static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
36
const char *name, hwaddr size)
37
{
29
{
38
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
30
- if (s->sve_excp_el) {
39
CMSDKAPBUART *uart = opaque;
31
- assert(!s->sve_access_checked);
40
int i = uart - &mms->uart[0];
32
- s->sve_access_checked = true;
41
int rxirqno = i * 2;
33
-
42
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
34
+ if (s->pstate_sm || !dc_isar_feature(aa64_sve, s)) {
43
35
+ assert(dc_isar_feature(aa64_sme, s));
44
object_initialize_child(OBJECT(mms), name, uart, TYPE_CMSDK_APB_UART);
36
+ if (!sme_sm_enabled_check(s)) {
45
qdev_prop_set_chr(DEVICE(uart), "chardev", serial_hd(i));
37
+ goto fail_exit;
46
- qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", SYSCLK_FRQ);
38
+ }
47
+ qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->sysclk_frq);
39
+ } else if (s->sve_excp_el) {
48
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
40
gen_exception_insn_el(s, s->pc_curr, EXCP_UDEF,
49
s = SYS_BUS_DEVICE(uart);
41
syn_sve_access_trap(), s->sve_excp_el);
50
sysbus_connect_irq(s, 0, get_sse_irq_in(mms, txirqno));
42
- return false;
51
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
43
+ goto fail_exit;
52
44
}
53
/* These clocks don't need migration because they are fixed-frequency */
45
s->sve_access_checked = true;
54
mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
46
return fp_access_check(s);
55
- clock_set_hz(mms->sysclk, SYSCLK_FRQ);
47
+
56
+ clock_set_hz(mms->sysclk, mmc->sysclk_frq);
48
+ fail_exit:
57
mms->s32kclk = clock_new(OBJECT(machine), "S32KCLK");
49
+ /* Assert that we only raise one exception per instruction. */
58
clock_set_hz(mms->s32kclk, S32KCLK_FRQ);
50
+ assert(!s->sve_access_checked);
59
51
+ s->sve_access_checked = true;
60
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
52
+ return false;
61
mmc->fpga_type = FPGA_AN505;
62
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
63
mmc->scc_id = 0x41045050;
64
+ mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
65
mmc->armsse_type = TYPE_IOTKIT;
66
}
53
}
67
54
68
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
55
/*
69
mmc->fpga_type = FPGA_AN521;
70
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
71
mmc->scc_id = 0x41045210;
72
+ mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
73
mmc->armsse_type = TYPE_SSE200;
74
}
75
76
--
56
--
77
2.20.1
57
2.25.1
78
79
diff view generated by jsdifflib
1
Add support for the mps3-an524 board; this is an SSE-200 based FPGA
1
From: Richard Henderson <richard.henderson@linaro.org>
2
image, like the existing mps2-an521. It has a usefully larger amount
3
of RAM, and a PL031 RTC, as well as some more minor differences.
4
2
5
In real hardware this image runs on a newer generation of the FPGA
3
These SME instructions are nominally within the SVE decode space,
6
board, the MPS3 rather than the older MPS2. Architecturally the two
4
so we add them to sve.decode and translate-sve.c.
7
boards are similar, so we implement the MPS3 boards in the mps2-tz.c
8
file as variations of the existing MPS2 boards.
9
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-18-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210215115138.20465-21-peter.maydell@linaro.org
13
---
10
---
14
hw/arm/mps2-tz.c | 139 +++++++++++++++++++++++++++++++++++++++++++++--
11
target/arm/translate-a64.h | 12 ++++++++++++
15
1 file changed, 135 insertions(+), 4 deletions(-)
12
target/arm/sve.decode | 5 ++++-
13
target/arm/translate-sve.c | 38 ++++++++++++++++++++++++++++++++++++++
14
3 files changed, 54 insertions(+), 1 deletion(-)
16
15
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/mps2-tz.c
18
--- a/target/arm/translate-a64.h
20
+++ b/hw/arm/mps2-tz.c
19
+++ b/target/arm/translate-a64.h
21
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static inline int vec_full_reg_size(DisasContext *s)
22
* This source file covers the following FPGA images, for TrustZone cores:
21
return s->vl;
23
* "mps2-an505" -- Cortex-M33 as documented in ARM Application Note AN505
24
* "mps2-an521" -- Dual Cortex-M33 as documented in Application Note AN521
25
+ * "mps2-an524" -- Dual Cortex-M33 as documented in Application Note AN524
26
*
27
* Links to the TRM for the board itself and to the various Application
28
* Notes which document the FPGA images can be found here:
29
@@ -XXX,XX +XXX,XX @@
30
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
31
* Application Note AN521:
32
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0521c/index.html
33
+ * Application Note AN524:
34
+ * https://developer.arm.com/documentation/dai0524/latest/
35
*
36
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
37
* (ARM ECM0601256) for the details of some of the device layout:
38
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
39
- * Similarly, the AN521 uses the SSE-200, and the SSE-200 TRM defines
40
+ * Similarly, the AN521 and AN524 use the SSE-200, and the SSE-200 TRM defines
41
* most of the device layout:
42
* http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
43
*
44
@@ -XXX,XX +XXX,XX @@
45
#include "hw/qdev-clock.h"
46
#include "qom/object.h"
47
48
-#define MPS2TZ_NUMIRQ_MAX 92
49
+#define MPS2TZ_NUMIRQ_MAX 95
50
#define MPS2TZ_RAM_MAX 4
51
52
typedef enum MPS2TZFPGAType {
53
FPGA_AN505,
54
FPGA_AN521,
55
+ FPGA_AN524,
56
} MPS2TZFPGAType;
57
58
/*
59
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
60
TZPPC ppc[5];
61
TZMPC mpc[3];
62
PL022State spi[5];
63
- ArmSbconI2CState i2c[4];
64
+ ArmSbconI2CState i2c[5];
65
UnimplementedDeviceState i2s_audio;
66
UnimplementedDeviceState gpio[4];
67
UnimplementedDeviceState gfx;
68
+ UnimplementedDeviceState cldc;
69
+ UnimplementedDeviceState rtc;
70
PL080State dma[4];
71
TZMSC msc[4];
72
- CMSDKAPBUART uart[5];
73
+ CMSDKAPBUART uart[6];
74
SplitIRQ sec_resp_splitter;
75
qemu_or_irq uart_irq_orgate;
76
DeviceState *lan9118;
77
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
78
#define TYPE_MPS2TZ_MACHINE "mps2tz"
79
#define TYPE_MPS2TZ_AN505_MACHINE MACHINE_TYPE_NAME("mps2-an505")
80
#define TYPE_MPS2TZ_AN521_MACHINE MACHINE_TYPE_NAME("mps2-an521")
81
+#define TYPE_MPS3TZ_AN524_MACHINE MACHINE_TYPE_NAME("mps3-an524")
82
83
OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
84
85
@@ -XXX,XX +XXX,XX @@ static const uint32_t an505_oscclk[] = {
86
25000000,
87
};
88
89
+static const uint32_t an524_oscclk[] = {
90
+ 24000000,
91
+ 32000000,
92
+ 50000000,
93
+ 50000000,
94
+ 24576000,
95
+ 23750000,
96
+};
97
+
98
static const RAMInfo an505_raminfo[] = { {
99
.name = "ssram-0",
100
.base = 0x00000000,
101
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an505_raminfo[] = { {
102
},
103
};
104
105
+static const RAMInfo an524_raminfo[] = { {
106
+ .name = "bram",
107
+ .base = 0x00000000,
108
+ .size = 512 * KiB,
109
+ .mpc = 0,
110
+ .mrindex = 0,
111
+ }, {
112
+ .name = "sram",
113
+ .base = 0x20000000,
114
+ .size = 32 * 4 * KiB,
115
+ .mpc = 1,
116
+ .mrindex = 1,
117
+ }, {
118
+ /* We don't model QSPI flash yet; for now expose it as simple ROM */
119
+ .name = "QSPI",
120
+ .base = 0x28000000,
121
+ .size = 8 * MiB,
122
+ .mpc = 1,
123
+ .mrindex = 2,
124
+ .flags = IS_ROM,
125
+ }, {
126
+ .name = "DDR",
127
+ .base = 0x60000000,
128
+ .size = 2 * GiB,
129
+ .mpc = 2,
130
+ .mrindex = -1,
131
+ }, {
132
+ .name = NULL,
133
+ },
134
+};
135
+
136
static const RAMInfo *find_raminfo_for_mpc(MPS2TZMachineState *mms, int mpc)
137
{
138
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
139
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
140
},
141
};
142
143
+ const PPCInfo an524_ppcs[] = { {
144
+ .name = "apb_ppcexp0",
145
+ .ports = {
146
+ { "bram-mpc", make_mpc, &mms->mpc[0], 0x58007000, 0x1000 },
147
+ { "qspi-mpc", make_mpc, &mms->mpc[1], 0x58008000, 0x1000 },
148
+ { "ddr-mpc", make_mpc, &mms->mpc[2], 0x58009000, 0x1000 },
149
+ },
150
+ }, {
151
+ .name = "apb_ppcexp1",
152
+ .ports = {
153
+ { "i2c0", make_i2c, &mms->i2c[0], 0x41200000, 0x1000 },
154
+ { "i2c1", make_i2c, &mms->i2c[1], 0x41201000, 0x1000 },
155
+ { "spi0", make_spi, &mms->spi[0], 0x41202000, 0x1000, { 52 } },
156
+ { "spi1", make_spi, &mms->spi[1], 0x41203000, 0x1000, { 53 } },
157
+ { "spi2", make_spi, &mms->spi[2], 0x41204000, 0x1000, { 54 } },
158
+ { "i2c2", make_i2c, &mms->i2c[2], 0x41205000, 0x1000 },
159
+ { "i2c3", make_i2c, &mms->i2c[3], 0x41206000, 0x1000 },
160
+ { /* port 7 reserved */ },
161
+ { "i2c4", make_i2c, &mms->i2c[4], 0x41208000, 0x1000 },
162
+ },
163
+ }, {
164
+ .name = "apb_ppcexp2",
165
+ .ports = {
166
+ { "scc", make_scc, &mms->scc, 0x41300000, 0x1000 },
167
+ { "i2s-audio", make_unimp_dev, &mms->i2s_audio,
168
+ 0x41301000, 0x1000 },
169
+ { "fpgaio", make_fpgaio, &mms->fpgaio, 0x41302000, 0x1000 },
170
+ { "uart0", make_uart, &mms->uart[0], 0x41303000, 0x1000, { 32, 33, 42 } },
171
+ { "uart1", make_uart, &mms->uart[1], 0x41304000, 0x1000, { 34, 35, 43 } },
172
+ { "uart2", make_uart, &mms->uart[2], 0x41305000, 0x1000, { 36, 37, 44 } },
173
+ { "uart3", make_uart, &mms->uart[3], 0x41306000, 0x1000, { 38, 39, 45 } },
174
+ { "uart4", make_uart, &mms->uart[4], 0x41307000, 0x1000, { 40, 41, 46 } },
175
+ { "uart5", make_uart, &mms->uart[5], 0x41308000, 0x1000, { 124, 125, 126 } },
176
+
177
+ { /* port 9 reserved */ },
178
+ { "clcd", make_unimp_dev, &mms->cldc, 0x4130a000, 0x1000 },
179
+ { "rtc", make_unimp_dev, &mms->rtc, 0x4130b000, 0x1000 },
180
+ },
181
+ }, {
182
+ .name = "ahb_ppcexp0",
183
+ .ports = {
184
+ { "gpio0", make_unimp_dev, &mms->gpio[0], 0x41100000, 0x1000 },
185
+ { "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
186
+ { "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
187
+ { "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
188
+ { "eth", make_eth_dev, NULL, 0x41400000, 0x100000, { 48 } },
189
+ },
190
+ },
191
+ };
192
+
193
switch (mmc->fpga_type) {
194
case FPGA_AN505:
195
case FPGA_AN521:
196
ppcs = an505_ppcs;
197
num_ppcs = ARRAY_SIZE(an505_ppcs);
198
break;
199
+ case FPGA_AN524:
200
+ ppcs = an524_ppcs;
201
+ num_ppcs = ARRAY_SIZE(an524_ppcs);
202
+ break;
203
default:
204
g_assert_not_reached();
205
}
206
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
207
mps2tz_set_default_ram_info(mmc);
208
}
22
}
209
23
210
+static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
24
+/* Return the byte size of the vector register, SVL / 8. */
25
+static inline int streaming_vec_reg_size(DisasContext *s)
211
+{
26
+{
212
+ MachineClass *mc = MACHINE_CLASS(oc);
27
+ return s->svl;
213
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
214
+
215
+ mc->desc = "ARM MPS3 with AN524 FPGA image for dual Cortex-M33";
216
+ mc->default_cpus = 2;
217
+ mc->min_cpus = mc->default_cpus;
218
+ mc->max_cpus = mc->default_cpus;
219
+ mmc->fpga_type = FPGA_AN524;
220
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
221
+ mmc->scc_id = 0x41045240;
222
+ mmc->sysclk_frq = 32 * 1000 * 1000; /* 32MHz */
223
+ mmc->oscclk = an524_oscclk;
224
+ mmc->len_oscclk = ARRAY_SIZE(an524_oscclk);
225
+ mmc->fpgaio_num_leds = 10;
226
+ mmc->fpgaio_has_switches = true;
227
+ mmc->numirq = 95;
228
+ mmc->raminfo = an524_raminfo;
229
+ mmc->armsse_type = TYPE_SSE200;
230
+ mps2tz_set_default_ram_info(mmc);
231
+}
28
+}
232
+
29
+
233
static const TypeInfo mps2tz_info = {
30
/*
234
.name = TYPE_MPS2TZ_MACHINE,
31
* Return the offset info CPUARMState of the predicate vector register Pn.
235
.parent = TYPE_MACHINE,
32
* Note for this purpose, FFR is P16.
236
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mps2tz_an521_info = {
33
@@ -XXX,XX +XXX,XX @@ static inline int pred_full_reg_size(DisasContext *s)
237
.class_init = mps2tz_an521_class_init,
34
return s->vl >> 3;
238
};
35
}
239
36
240
+static const TypeInfo mps3tz_an524_info = {
37
+/* Return the byte size of the predicate register, SVL / 64. */
241
+ .name = TYPE_MPS3TZ_AN524_MACHINE,
38
+static inline int streaming_pred_reg_size(DisasContext *s)
242
+ .parent = TYPE_MPS2TZ_MACHINE,
39
+{
243
+ .class_init = mps3tz_an524_class_init,
40
+ return s->svl >> 3;
244
+};
41
+}
245
+
42
+
246
static void mps2tz_machine_init(void)
43
/*
44
* Round up the size of a register to a size allowed by
45
* the tcg vector infrastructure. Any operation which uses this
46
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/sve.decode
49
+++ b/target/arm/sve.decode
50
@@ -XXX,XX +XXX,XX @@ INDEX_ri 00000100 esz:2 1 imm:s5 010001 rn:5 rd:5
51
# SVE index generation (register start, register increment)
52
INDEX_rr 00000100 .. 1 ..... 010011 ..... ..... @rd_rn_rm
53
54
-### SVE Stack Allocation Group
55
+### SVE / Streaming SVE Stack Allocation Group
56
57
# SVE stack frame adjustment
58
ADDVL 00000100 001 ..... 01010 ...... ..... @rd_rn_i6
59
+ADDSVL 00000100 001 ..... 01011 ...... ..... @rd_rn_i6
60
ADDPL 00000100 011 ..... 01010 ...... ..... @rd_rn_i6
61
+ADDSPL 00000100 011 ..... 01011 ...... ..... @rd_rn_i6
62
63
# SVE stack frame size
64
RDVL 00000100 101 11111 01010 imm:s6 rd:5
65
+RDSVL 00000100 101 11111 01011 imm:s6 rd:5
66
67
### SVE Bitwise Shift - Unpredicated Group
68
69
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/translate-sve.c
72
+++ b/target/arm/translate-sve.c
73
@@ -XXX,XX +XXX,XX @@ static bool trans_ADDVL(DisasContext *s, arg_ADDVL *a)
74
return true;
75
}
76
77
+static bool trans_ADDSVL(DisasContext *s, arg_ADDSVL *a)
78
+{
79
+ if (!dc_isar_feature(aa64_sme, s)) {
80
+ return false;
81
+ }
82
+ if (sme_enabled_check(s)) {
83
+ TCGv_i64 rd = cpu_reg_sp(s, a->rd);
84
+ TCGv_i64 rn = cpu_reg_sp(s, a->rn);
85
+ tcg_gen_addi_i64(rd, rn, a->imm * streaming_vec_reg_size(s));
86
+ }
87
+ return true;
88
+}
89
+
90
static bool trans_ADDPL(DisasContext *s, arg_ADDPL *a)
247
{
91
{
248
type_register_static(&mps2tz_info);
92
if (!dc_isar_feature(aa64_sve, s)) {
249
type_register_static(&mps2tz_an505_info);
93
@@ -XXX,XX +XXX,XX @@ static bool trans_ADDPL(DisasContext *s, arg_ADDPL *a)
250
type_register_static(&mps2tz_an521_info);
94
return true;
251
+ type_register_static(&mps3tz_an524_info);
252
}
95
}
253
96
254
type_init(mps2tz_machine_init);
97
+static bool trans_ADDSPL(DisasContext *s, arg_ADDSPL *a)
98
+{
99
+ if (!dc_isar_feature(aa64_sme, s)) {
100
+ return false;
101
+ }
102
+ if (sme_enabled_check(s)) {
103
+ TCGv_i64 rd = cpu_reg_sp(s, a->rd);
104
+ TCGv_i64 rn = cpu_reg_sp(s, a->rn);
105
+ tcg_gen_addi_i64(rd, rn, a->imm * streaming_pred_reg_size(s));
106
+ }
107
+ return true;
108
+}
109
+
110
static bool trans_RDVL(DisasContext *s, arg_RDVL *a)
111
{
112
if (!dc_isar_feature(aa64_sve, s)) {
113
@@ -XXX,XX +XXX,XX @@ static bool trans_RDVL(DisasContext *s, arg_RDVL *a)
114
return true;
115
}
116
117
+static bool trans_RDSVL(DisasContext *s, arg_RDSVL *a)
118
+{
119
+ if (!dc_isar_feature(aa64_sme, s)) {
120
+ return false;
121
+ }
122
+ if (sme_enabled_check(s)) {
123
+ TCGv_i64 reg = cpu_reg(s, a->rd);
124
+ tcg_gen_movi_i64(reg, a->imm * streaming_vec_reg_size(s));
125
+ }
126
+ return true;
127
+}
128
+
129
/*
130
*** SVE Compute Vector Address Group
131
*/
255
--
132
--
256
2.20.1
133
2.25.1
257
258
diff view generated by jsdifflib
1
The MPS2 board has 2 LEDs, but the MPS3 board has 10 LEDs. The
1
From: Richard Henderson <richard.henderson@linaro.org>
2
FPGAIO device is similar on both sets of boards, but the LED0
3
register has correspondingly more bits that have an effect. Add a
4
device property for number of LEDs.
5
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220708151540.18136-19-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210215115138.20465-6-peter.maydell@linaro.org
10
---
7
---
11
include/hw/misc/mps2-fpgaio.h | 5 ++++-
8
target/arm/helper-sme.h | 2 ++
12
hw/misc/mps2-fpgaio.c | 31 +++++++++++++++++++++++--------
9
target/arm/sme.decode | 4 ++++
13
2 files changed, 27 insertions(+), 9 deletions(-)
10
target/arm/sme_helper.c | 25 +++++++++++++++++++++++++
11
target/arm/translate-sme.c | 13 +++++++++++++
12
4 files changed, 44 insertions(+)
14
13
15
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
14
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/misc/mps2-fpgaio.h
16
--- a/target/arm/helper-sme.h
18
+++ b/include/hw/misc/mps2-fpgaio.h
17
+++ b/target/arm/helper-sme.h
19
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@
20
#define TYPE_MPS2_FPGAIO "mps2-fpgaio"
19
21
OBJECT_DECLARE_SIMPLE_TYPE(MPS2FPGAIO, MPS2_FPGAIO)
20
DEF_HELPER_FLAGS_2(set_pstate_sm, TCG_CALL_NO_RWG, void, env, i32)
22
21
DEF_HELPER_FLAGS_2(set_pstate_za, TCG_CALL_NO_RWG, void, env, i32)
23
+#define MPS2FPGAIO_MAX_LEDS 32
24
+
22
+
25
struct MPS2FPGAIO {
23
+DEF_HELPER_FLAGS_3(sme_zero, TCG_CALL_NO_RWG, void, env, i32, i32)
26
/*< private >*/
24
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
27
SysBusDevice parent_obj;
28
29
/*< public >*/
30
MemoryRegion iomem;
31
- LEDState *led[2];
32
+ LEDState *led[MPS2FPGAIO_MAX_LEDS];
33
+ uint32_t num_leds;
34
35
uint32_t led0;
36
uint32_t prescale;
37
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
38
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/misc/mps2-fpgaio.c
26
--- a/target/arm/sme.decode
40
+++ b/hw/misc/mps2-fpgaio.c
27
+++ b/target/arm/sme.decode
41
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
28
@@ -XXX,XX +XXX,XX @@
42
29
#
43
switch (offset) {
30
# This file is processed by scripts/decodetree.py
44
case A_LED0:
31
#
45
- s->led0 = value & 0x3;
46
- led_set_state(s->led[0], value & 0x01);
47
- led_set_state(s->led[1], value & 0x02);
48
+ if (s->num_leds != 0) {
49
+ uint32_t i;
50
+
32
+
51
+ s->led0 = value & MAKE_64BIT_MASK(0, s->num_leds);
33
+### SME Misc
52
+ for (i = 0; i < s->num_leds; i++) {
34
+
53
+ led_set_state(s->led[i], value & (1 << i));
35
+ZERO 11000000 00 001 00000000000 imm:8
54
+ }
36
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
55
+ }
37
index XXXXXXX..XXXXXXX 100644
56
break;
38
--- a/target/arm/sme_helper.c
57
case A_PRESCALE:
39
+++ b/target/arm/sme_helper.c
58
resync_counter(s);
40
@@ -XXX,XX +XXX,XX @@ void helper_set_pstate_za(CPUARMState *env, uint32_t i)
59
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_reset(DeviceState *dev)
41
memset(env->zarray, 0, sizeof(env->zarray));
60
s->pscntr = 0;
61
s->pscntr_sync_ticks = now;
62
63
- for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
64
+ for (size_t i = 0; i < s->num_leds; i++) {
65
device_cold_reset(DEVICE(s->led[i]));
66
}
42
}
67
}
43
}
68
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_init(Object *obj)
44
+
69
static void mps2_fpgaio_realize(DeviceState *dev, Error **errp)
45
+void helper_sme_zero(CPUARMState *env, uint32_t imm, uint32_t svl)
70
{
46
+{
71
MPS2FPGAIO *s = MPS2_FPGAIO(dev);
72
+ uint32_t i;
47
+ uint32_t i;
73
48
+
74
- s->led[0] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
49
+ /*
75
- LED_COLOR_GREEN, "USERLED0");
50
+ * Special case clearing the entire ZA space.
76
- s->led[1] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
51
+ * This falls into the CONSTRAINED UNPREDICTABLE zeroing of any
77
- LED_COLOR_GREEN, "USERLED1");
52
+ * parts of the ZA storage outside of SVL.
78
+ if (s->num_leds > MPS2FPGAIO_MAX_LEDS) {
53
+ */
79
+ error_setg(errp, "num-leds cannot be greater than %d",
54
+ if (imm == 0xff) {
80
+ MPS2FPGAIO_MAX_LEDS);
55
+ memset(env->zarray, 0, sizeof(env->zarray));
81
+ return;
56
+ return;
82
+ }
57
+ }
83
+
58
+
84
+ for (i = 0; i < s->num_leds; i++) {
59
+ /*
85
+ g_autofree char *ledname = g_strdup_printf("USERLED%d", i);
60
+ * Recall that ZAnH.D[m] is spread across ZA[n+8*m],
86
+ s->led[i] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
61
+ * so each row is discontiguous within ZA[].
87
+ LED_COLOR_GREEN, ledname);
62
+ */
63
+ for (i = 0; i < svl; i++) {
64
+ if (imm & (1 << (i % 8))) {
65
+ memset(&env->zarray[i], 0, svl);
66
+ }
88
+ }
67
+ }
89
}
68
+}
90
69
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
91
static bool mps2_fpgaio_counters_needed(void *opaque)
70
index XXXXXXX..XXXXXXX 100644
92
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_fpgaio_vmstate = {
71
--- a/target/arm/translate-sme.c
93
static Property mps2_fpgaio_properties[] = {
72
+++ b/target/arm/translate-sme.c
94
/* Frequency of the prescale counter */
73
@@ -XXX,XX +XXX,XX @@
95
DEFINE_PROP_UINT32("prescale-clk", MPS2FPGAIO, prescale_clk, 20000000),
74
*/
96
+ /* Number of LEDs controlled by LED0 register */
75
97
+ DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2),
76
#include "decode-sme.c.inc"
98
DEFINE_PROP_END_OF_LIST(),
77
+
99
};
78
+
100
79
+static bool trans_ZERO(DisasContext *s, arg_ZERO *a)
80
+{
81
+ if (!dc_isar_feature(aa64_sme, s)) {
82
+ return false;
83
+ }
84
+ if (sme_za_enabled_check(s)) {
85
+ gen_helper_sme_zero(cpu_env, tcg_constant_i32(a->imm),
86
+ tcg_constant_i32(streaming_vec_reg_size(s)));
87
+ }
88
+ return true;
89
+}
101
--
90
--
102
2.20.1
91
2.25.1
103
104
diff view generated by jsdifflib
1
On the MPS2 boards, the first 32 interrupt lines are entirely
1
From: Richard Henderson <richard.henderson@linaro.org>
2
internal to the SSE; interrupt lines for devices outside the SSE
3
start at 32. In the application notes that document each FPGA image,
4
the interrupt wiring is documented from the point of view of the CPU,
5
so '0' is the first of the SSE's interrupts and the devices in the
6
FPGA image itself are '32' and up: so the UART 0 Receive interrupt is
7
32, the SPI #0 interrupt is 51, and so on.
8
2
9
Within our implementation, because the external interrupts must be
3
We can reuse the SVE functions for implementing moves to/from
10
connected to the EXP_IRQ[0...n] lines of the SSE object, we made the
4
horizontal tile slices, but we need new ones for moves to/from
11
get_sse_irq_in() function take an irqno whose values start at 0 for
5
vertical tile slices.
12
the first FPGA device interrupt. In this numbering scheme the UART 0
13
Receive interrupt is 0, the SPI #0 interrupt is 19, and so on.
14
6
15
The result of these two different numbering schemes has been that
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
half of the devices were wired up to the wrong IRQs: the UART IRQs
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
are wired up correctly, but the DMA and SPI devices were passing
9
Message-id: 20220708151540.18136-20-richard.henderson@linaro.org
18
start-at-32 values to get_sse_irq_in() and so being mis-connected.
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/helper-sme.h | 12 +++
13
target/arm/helper-sve.h | 2 +
14
target/arm/translate-a64.h | 8 ++
15
target/arm/translate.h | 5 ++
16
target/arm/sme.decode | 15 ++++
17
target/arm/sme_helper.c | 151 ++++++++++++++++++++++++++++++++++++-
18
target/arm/sve_helper.c | 12 +++
19
target/arm/translate-sme.c | 127 +++++++++++++++++++++++++++++++
20
8 files changed, 331 insertions(+), 1 deletion(-)
19
21
20
Fix the bug by making get_sse_irq_in() take values specified with the
22
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
21
same scheme that the hardware manuals use, to avoid confusion.
23
index XXXXXXX..XXXXXXX 100644
22
24
--- a/target/arm/helper-sme.h
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
+++ b/target/arm/helper-sme.h
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(set_pstate_sm, TCG_CALL_NO_RWG, void, env, i32)
25
Message-id: 20210215115138.20465-12-peter.maydell@linaro.org
27
DEF_HELPER_FLAGS_2(set_pstate_za, TCG_CALL_NO_RWG, void, env, i32)
26
---
28
27
hw/arm/mps2-tz.c | 24 +++++++++++++++++-------
29
DEF_HELPER_FLAGS_3(sme_zero, TCG_CALL_NO_RWG, void, env, i32, i32)
28
1 file changed, 17 insertions(+), 7 deletions(-)
30
+
29
31
+/* Move to/from vertical array slices, i.e. columns, so 'c'. */
30
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
32
+DEF_HELPER_FLAGS_4(sme_mova_cz_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
index XXXXXXX..XXXXXXX 100644
33
+DEF_HELPER_FLAGS_4(sme_mova_zc_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
--- a/hw/arm/mps2-tz.c
34
+DEF_HELPER_FLAGS_4(sme_mova_cz_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
+++ b/hw/arm/mps2-tz.c
35
+DEF_HELPER_FLAGS_4(sme_mova_zc_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
36
+DEF_HELPER_FLAGS_4(sme_mova_cz_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
35
37
+DEF_HELPER_FLAGS_4(sme_mova_zc_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
38
+DEF_HELPER_FLAGS_4(sme_mova_cz_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_4(sme_mova_zc_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(sme_mova_cz_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_4(sme_mova_zc_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
42
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/helper-sve.h
45
+++ b/target/arm/helper-sve.h
46
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_sel_zpzz_s, TCG_CALL_NO_RWG,
47
void, ptr, ptr, ptr, ptr, i32)
48
DEF_HELPER_FLAGS_5(sve_sel_zpzz_d, TCG_CALL_NO_RWG,
49
void, ptr, ptr, ptr, ptr, i32)
50
+DEF_HELPER_FLAGS_5(sve_sel_zpzz_q, TCG_CALL_NO_RWG,
51
+ void, ptr, ptr, ptr, ptr, i32)
52
53
DEF_HELPER_FLAGS_5(sve2_addp_zpzz_b, TCG_CALL_NO_RWG,
54
void, ptr, ptr, ptr, ptr, i32)
55
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/translate-a64.h
58
+++ b/target/arm/translate-a64.h
59
@@ -XXX,XX +XXX,XX @@ static inline int pred_gvec_reg_size(DisasContext *s)
60
return size_for_gvec(pred_full_reg_size(s));
61
}
62
63
+/* Return a newly allocated pointer to the predicate register. */
64
+static inline TCGv_ptr pred_full_reg_ptr(DisasContext *s, int regno)
65
+{
66
+ TCGv_ptr ret = tcg_temp_new_ptr();
67
+ tcg_gen_addi_ptr(ret, cpu_env, pred_full_reg_offset(s, regno));
68
+ return ret;
69
+}
70
+
71
bool disas_sve(DisasContext *, uint32_t);
72
bool disas_sme(DisasContext *, uint32_t);
73
74
diff --git a/target/arm/translate.h b/target/arm/translate.h
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/translate.h
77
+++ b/target/arm/translate.h
78
@@ -XXX,XX +XXX,XX @@ static inline int plus_2(DisasContext *s, int x)
79
return x + 2;
80
}
81
82
+static inline int plus_12(DisasContext *s, int x)
83
+{
84
+ return x + 12;
85
+}
86
+
87
static inline int times_2(DisasContext *s, int x)
37
{
88
{
38
- /* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
89
return x * 2;
90
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/sme.decode
93
+++ b/target/arm/sme.decode
94
@@ -XXX,XX +XXX,XX @@
95
### SME Misc
96
97
ZERO 11000000 00 001 00000000000 imm:8
98
+
99
+### SME Move into/from Array
100
+
101
+%mova_rs 13:2 !function=plus_12
102
+&mova esz rs pg zr za_imm v:bool to_vec:bool
103
+
104
+MOVA 11000000 esz:2 00000 0 v:1 .. pg:3 zr:5 0 za_imm:4 \
105
+ &mova to_vec=0 rs=%mova_rs
106
+MOVA 11000000 11 00000 1 v:1 .. pg:3 zr:5 0 za_imm:4 \
107
+ &mova to_vec=0 rs=%mova_rs esz=4
108
+
109
+MOVA 11000000 esz:2 00001 0 v:1 .. pg:3 0 za_imm:4 zr:5 \
110
+ &mova to_vec=1 rs=%mova_rs
111
+MOVA 11000000 11 00001 1 v:1 .. pg:3 0 za_imm:4 zr:5 \
112
+ &mova to_vec=1 rs=%mova_rs esz=4
113
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/arm/sme_helper.c
116
+++ b/target/arm/sme_helper.c
117
@@ -XXX,XX +XXX,XX @@
118
119
#include "qemu/osdep.h"
120
#include "cpu.h"
121
-#include "internals.h"
122
+#include "tcg/tcg-gvec-desc.h"
123
#include "exec/helper-proto.h"
124
+#include "qemu/int128.h"
125
+#include "vec_internal.h"
126
127
/* ResetSVEState */
128
void arm_reset_sve_state(CPUARMState *env)
129
@@ -XXX,XX +XXX,XX @@ void helper_sme_zero(CPUARMState *env, uint32_t imm, uint32_t svl)
130
}
131
}
132
}
133
+
134
+
135
+/*
136
+ * When considering the ZA storage as an array of elements of
137
+ * type T, the index within that array of the Nth element of
138
+ * a vertical slice of a tile can be calculated like this,
139
+ * regardless of the size of type T. This is because the tiles
140
+ * are interleaved, so if type T is size N bytes then row 1 of
141
+ * the tile is N rows away from row 0. The division by N to
142
+ * convert a byte offset into an array index and the multiplication
143
+ * by N to convert from vslice-index-within-the-tile to
144
+ * the index within the ZA storage cancel out.
145
+ */
146
+#define tile_vslice_index(i) ((i) * sizeof(ARMVectorReg))
147
+
148
+/*
149
+ * When doing byte arithmetic on the ZA storage, the element
150
+ * byteoff bytes away in a tile vertical slice is always this
151
+ * many bytes away in the ZA storage, regardless of the
152
+ * size of the tile element, assuming that byteoff is a multiple
153
+ * of the element size. Again this is because of the interleaving
154
+ * of the tiles. For instance if we have 1 byte per element then
155
+ * each row of the ZA storage has one byte of the vslice data,
156
+ * and (counting from 0) byte 8 goes in row 8 of the storage
157
+ * at offset (8 * row-size-in-bytes).
158
+ * If we have 8 bytes per element then each row of the ZA storage
159
+ * has 8 bytes of the data, but there are 8 interleaved tiles and
160
+ * so byte 8 of the data goes into row 1 of the tile,
161
+ * which is again row 8 of the storage, so the offset is still
162
+ * (8 * row-size-in-bytes). Similarly for other element sizes.
163
+ */
164
+#define tile_vslice_offset(byteoff) ((byteoff) * sizeof(ARMVectorReg))
165
+
166
+
167
+/*
168
+ * Move Zreg vector to ZArray column.
169
+ */
170
+#define DO_MOVA_C(NAME, TYPE, H) \
171
+void HELPER(NAME)(void *za, void *vn, void *vg, uint32_t desc) \
172
+{ \
173
+ int i, oprsz = simd_oprsz(desc); \
174
+ for (i = 0; i < oprsz; ) { \
175
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
176
+ do { \
177
+ if (pg & 1) { \
178
+ *(TYPE *)(za + tile_vslice_offset(i)) = *(TYPE *)(vn + H(i)); \
179
+ } \
180
+ i += sizeof(TYPE); \
181
+ pg >>= sizeof(TYPE); \
182
+ } while (i & 15); \
183
+ } \
184
+}
185
+
186
+DO_MOVA_C(sme_mova_cz_b, uint8_t, H1)
187
+DO_MOVA_C(sme_mova_cz_h, uint16_t, H1_2)
188
+DO_MOVA_C(sme_mova_cz_s, uint32_t, H1_4)
189
+
190
+void HELPER(sme_mova_cz_d)(void *za, void *vn, void *vg, uint32_t desc)
191
+{
192
+ int i, oprsz = simd_oprsz(desc) / 8;
193
+ uint8_t *pg = vg;
194
+ uint64_t *n = vn;
195
+ uint64_t *a = za;
196
+
197
+ for (i = 0; i < oprsz; i++) {
198
+ if (pg[H1(i)] & 1) {
199
+ a[tile_vslice_index(i)] = n[i];
200
+ }
201
+ }
202
+}
203
+
204
+void HELPER(sme_mova_cz_q)(void *za, void *vn, void *vg, uint32_t desc)
205
+{
206
+ int i, oprsz = simd_oprsz(desc) / 16;
207
+ uint16_t *pg = vg;
208
+ Int128 *n = vn;
209
+ Int128 *a = za;
210
+
39
+ /*
211
+ /*
40
+ * Return a qemu_irq which will signal IRQ n to all CPUs in the
212
+ * Int128 is used here simply to copy 16 bytes, and to simplify
41
+ * SSE. The irqno should be as the CPU sees it, so the first
213
+ * the address arithmetic.
42
+ * external-to-the-SSE interrupt is 32.
43
+ */
214
+ */
44
MachineClass *mc = MACHINE_GET_CLASS(mms);
215
+ for (i = 0; i < oprsz; i++) {
45
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
216
+ if (pg[H2(i)] & 1) {
46
217
+ a[tile_vslice_index(i)] = n[i];
47
- assert(irqno < mmc->numirq);
218
+ }
48
+ assert(irqno >= 32 && irqno < (mmc->numirq + 32));
219
+ }
220
+}
221
+
222
+#undef DO_MOVA_C
223
+
224
+/*
225
+ * Move ZArray column to Zreg vector.
226
+ */
227
+#define DO_MOVA_Z(NAME, TYPE, H) \
228
+void HELPER(NAME)(void *vd, void *za, void *vg, uint32_t desc) \
229
+{ \
230
+ int i, oprsz = simd_oprsz(desc); \
231
+ for (i = 0; i < oprsz; ) { \
232
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
233
+ do { \
234
+ if (pg & 1) { \
235
+ *(TYPE *)(vd + H(i)) = *(TYPE *)(za + tile_vslice_offset(i)); \
236
+ } \
237
+ i += sizeof(TYPE); \
238
+ pg >>= sizeof(TYPE); \
239
+ } while (i & 15); \
240
+ } \
241
+}
242
+
243
+DO_MOVA_Z(sme_mova_zc_b, uint8_t, H1)
244
+DO_MOVA_Z(sme_mova_zc_h, uint16_t, H1_2)
245
+DO_MOVA_Z(sme_mova_zc_s, uint32_t, H1_4)
246
+
247
+void HELPER(sme_mova_zc_d)(void *vd, void *za, void *vg, uint32_t desc)
248
+{
249
+ int i, oprsz = simd_oprsz(desc) / 8;
250
+ uint8_t *pg = vg;
251
+ uint64_t *d = vd;
252
+ uint64_t *a = za;
253
+
254
+ for (i = 0; i < oprsz; i++) {
255
+ if (pg[H1(i)] & 1) {
256
+ d[i] = a[tile_vslice_index(i)];
257
+ }
258
+ }
259
+}
260
+
261
+void HELPER(sme_mova_zc_q)(void *vd, void *za, void *vg, uint32_t desc)
262
+{
263
+ int i, oprsz = simd_oprsz(desc) / 16;
264
+ uint16_t *pg = vg;
265
+ Int128 *d = vd;
266
+ Int128 *a = za;
49
+
267
+
50
+ /*
268
+ /*
51
+ * Convert from "CPU irq number" (as listed in the FPGA image
269
+ * Int128 is used here simply to copy 16 bytes, and to simplify
52
+ * documentation) to the SSE external-interrupt number.
270
+ * the address arithmetic.
53
+ */
271
+ */
54
+ irqno -= 32;
272
+ for (i = 0; i < oprsz; i++, za += sizeof(ARMVectorReg)) {
55
273
+ if (pg[H2(i)] & 1) {
56
if (mc->max_cpus > 1) {
274
+ d[i] = a[tile_vslice_index(i)];
57
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
275
+ }
58
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
276
+ }
59
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
277
+}
60
CMSDKAPBUART *uart = opaque;
278
+
61
int i = uart - &mms->uart[0];
279
+#undef DO_MOVA_Z
62
- int rxirqno = i * 2;
280
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
63
- int txirqno = i * 2 + 1;
281
index XXXXXXX..XXXXXXX 100644
64
- int combirqno = i + 10;
282
--- a/target/arm/sve_helper.c
65
+ int rxirqno = i * 2 + 32;
283
+++ b/target/arm/sve_helper.c
66
+ int txirqno = i * 2 + 33;
284
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_sel_zpzz_d)(void *vd, void *vn, void *vm,
67
+ int combirqno = i + 42;
285
}
68
SysBusDevice *s;
69
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
70
71
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
72
73
s = SYS_BUS_DEVICE(mms->lan9118);
74
sysbus_realize_and_unref(s, &error_fatal);
75
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 16));
76
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 48));
77
return sysbus_mmio_get_region(s, 0);
78
}
286
}
79
287
80
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
288
+void HELPER(sve_sel_zpzz_q)(void *vd, void *vn, void *vm,
81
&error_fatal);
289
+ void *vg, uint32_t desc)
82
qdev_realize(DEVICE(&mms->uart_irq_orgate), NULL, &error_fatal);
290
+{
83
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
291
+ intptr_t i, opr_sz = simd_oprsz(desc) / 16;
84
- get_sse_irq_in(mms, 15));
292
+ Int128 *d = vd, *n = vn, *m = vm;
85
+ get_sse_irq_in(mms, 47));
293
+ uint16_t *pg = vg;
86
294
+
87
/* Most of the devices in the FPGA are behind Peripheral Protection
295
+ for (i = 0; i < opr_sz; i += 1) {
88
* Controllers. The required order for initializing things is:
296
+ d[i] = (pg[H2(i)] & 1 ? n : m)[i];
297
+ }
298
+}
299
+
300
/* Two operand comparison controlled by a predicate.
301
* ??? It is very tempting to want to be able to expand this inline
302
* with x86 instructions, e.g.
303
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
304
index XXXXXXX..XXXXXXX 100644
305
--- a/target/arm/translate-sme.c
306
+++ b/target/arm/translate-sme.c
307
@@ -XXX,XX +XXX,XX @@
308
#include "decode-sme.c.inc"
309
310
311
+/*
312
+ * Resolve tile.size[index] to a host pointer, where tile and index
313
+ * are always decoded together, dependent on the element size.
314
+ */
315
+static TCGv_ptr get_tile_rowcol(DisasContext *s, int esz, int rs,
316
+ int tile_index, bool vertical)
317
+{
318
+ int tile = tile_index >> (4 - esz);
319
+ int index = esz == MO_128 ? 0 : extract32(tile_index, 0, 4 - esz);
320
+ int pos, len, offset;
321
+ TCGv_i32 tmp;
322
+ TCGv_ptr addr;
323
+
324
+ /* Compute the final index, which is Rs+imm. */
325
+ tmp = tcg_temp_new_i32();
326
+ tcg_gen_trunc_tl_i32(tmp, cpu_reg(s, rs));
327
+ tcg_gen_addi_i32(tmp, tmp, index);
328
+
329
+ /* Prepare a power-of-two modulo via extraction of @len bits. */
330
+ len = ctz32(streaming_vec_reg_size(s)) - esz;
331
+
332
+ if (vertical) {
333
+ /*
334
+ * Compute the byte offset of the index within the tile:
335
+ * (index % (svl / size)) * size
336
+ * = (index % (svl >> esz)) << esz
337
+ * Perform the power-of-two modulo via extraction of the low @len bits.
338
+ * Perform the multiply by shifting left by @pos bits.
339
+ * Perform these operations simultaneously via deposit into zero.
340
+ */
341
+ pos = esz;
342
+ tcg_gen_deposit_z_i32(tmp, tmp, pos, len);
343
+
344
+ /*
345
+ * For big-endian, adjust the indexed column byte offset within
346
+ * the uint64_t host words that make up env->zarray[].
347
+ */
348
+ if (HOST_BIG_ENDIAN && esz < MO_64) {
349
+ tcg_gen_xori_i32(tmp, tmp, 8 - (1 << esz));
350
+ }
351
+ } else {
352
+ /*
353
+ * Compute the byte offset of the index within the tile:
354
+ * (index % (svl / size)) * (size * sizeof(row))
355
+ * = (index % (svl >> esz)) << (esz + log2(sizeof(row)))
356
+ */
357
+ pos = esz + ctz32(sizeof(ARMVectorReg));
358
+ tcg_gen_deposit_z_i32(tmp, tmp, pos, len);
359
+
360
+ /* Row slices are always aligned and need no endian adjustment. */
361
+ }
362
+
363
+ /* The tile byte offset within env->zarray is the row. */
364
+ offset = tile * sizeof(ARMVectorReg);
365
+
366
+ /* Include the byte offset of zarray to make this relative to env. */
367
+ offset += offsetof(CPUARMState, zarray);
368
+ tcg_gen_addi_i32(tmp, tmp, offset);
369
+
370
+ /* Add the byte offset to env to produce the final pointer. */
371
+ addr = tcg_temp_new_ptr();
372
+ tcg_gen_ext_i32_ptr(addr, tmp);
373
+ tcg_temp_free_i32(tmp);
374
+ tcg_gen_add_ptr(addr, addr, cpu_env);
375
+
376
+ return addr;
377
+}
378
+
379
static bool trans_ZERO(DisasContext *s, arg_ZERO *a)
380
{
381
if (!dc_isar_feature(aa64_sme, s)) {
382
@@ -XXX,XX +XXX,XX @@ static bool trans_ZERO(DisasContext *s, arg_ZERO *a)
383
}
384
return true;
385
}
386
+
387
+static bool trans_MOVA(DisasContext *s, arg_MOVA *a)
388
+{
389
+ static gen_helper_gvec_4 * const h_fns[5] = {
390
+ gen_helper_sve_sel_zpzz_b, gen_helper_sve_sel_zpzz_h,
391
+ gen_helper_sve_sel_zpzz_s, gen_helper_sve_sel_zpzz_d,
392
+ gen_helper_sve_sel_zpzz_q
393
+ };
394
+ static gen_helper_gvec_3 * const cz_fns[5] = {
395
+ gen_helper_sme_mova_cz_b, gen_helper_sme_mova_cz_h,
396
+ gen_helper_sme_mova_cz_s, gen_helper_sme_mova_cz_d,
397
+ gen_helper_sme_mova_cz_q,
398
+ };
399
+ static gen_helper_gvec_3 * const zc_fns[5] = {
400
+ gen_helper_sme_mova_zc_b, gen_helper_sme_mova_zc_h,
401
+ gen_helper_sme_mova_zc_s, gen_helper_sme_mova_zc_d,
402
+ gen_helper_sme_mova_zc_q,
403
+ };
404
+
405
+ TCGv_ptr t_za, t_zr, t_pg;
406
+ TCGv_i32 t_desc;
407
+ int svl;
408
+
409
+ if (!dc_isar_feature(aa64_sme, s)) {
410
+ return false;
411
+ }
412
+ if (!sme_smza_enabled_check(s)) {
413
+ return true;
414
+ }
415
+
416
+ t_za = get_tile_rowcol(s, a->esz, a->rs, a->za_imm, a->v);
417
+ t_zr = vec_full_reg_ptr(s, a->zr);
418
+ t_pg = pred_full_reg_ptr(s, a->pg);
419
+
420
+ svl = streaming_vec_reg_size(s);
421
+ t_desc = tcg_constant_i32(simd_desc(svl, svl, 0));
422
+
423
+ if (a->v) {
424
+ /* Vertical slice -- use sme mova helpers. */
425
+ if (a->to_vec) {
426
+ zc_fns[a->esz](t_zr, t_za, t_pg, t_desc);
427
+ } else {
428
+ cz_fns[a->esz](t_za, t_zr, t_pg, t_desc);
429
+ }
430
+ } else {
431
+ /* Horizontal slice -- reuse sve sel helpers. */
432
+ if (a->to_vec) {
433
+ h_fns[a->esz](t_zr, t_za, t_zr, t_pg, t_desc);
434
+ } else {
435
+ h_fns[a->esz](t_za, t_zr, t_za, t_pg, t_desc);
436
+ }
437
+ }
438
+
439
+ tcg_temp_free_ptr(t_za);
440
+ tcg_temp_free_ptr(t_zr);
441
+ tcg_temp_free_ptr(t_pg);
442
+
443
+ return true;
444
+}
89
--
445
--
90
2.20.1
446
2.25.1
91
92
diff view generated by jsdifflib
1
The omap_lcdc template header is already only included once, for
1
From: Richard Henderson <richard.henderson@linaro.org>
2
DEPTH==32, but it still has all the macro-driven parameterization
3
for other depths. Expand out all the macros in the header.
4
2
3
We cannot reuse the SVE functions for LD[1-4] and ST[1-4],
4
because those functions accept only a Zreg register number.
5
For SME, we want to pass a pointer into ZA storage.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220708151540.18136-21-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210215103215.4944-6-peter.maydell@linaro.org
9
---
11
---
10
hw/display/omap_lcd_template.h | 67 ++++++++++++++--------------------
12
target/arm/helper-sme.h | 82 +++++
11
1 file changed, 28 insertions(+), 39 deletions(-)
13
target/arm/sme.decode | 9 +
14
target/arm/sme_helper.c | 595 +++++++++++++++++++++++++++++++++++++
15
target/arm/translate-sme.c | 70 +++++
16
4 files changed, 756 insertions(+)
12
17
13
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
18
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/display/omap_lcd_template.h
20
--- a/target/arm/helper-sme.h
16
+++ b/hw/display/omap_lcd_template.h
21
+++ b/target/arm/helper-sme.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sme_mova_cz_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
DEF_HELPER_FLAGS_4(sme_mova_zc_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
DEF_HELPER_FLAGS_4(sme_mova_cz_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
DEF_HELPER_FLAGS_4(sme_mova_zc_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
+
27
+DEF_HELPER_FLAGS_5(sme_ld1b_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
28
+DEF_HELPER_FLAGS_5(sme_ld1b_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
29
+DEF_HELPER_FLAGS_5(sme_ld1b_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
30
+DEF_HELPER_FLAGS_5(sme_ld1b_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
31
+
32
+DEF_HELPER_FLAGS_5(sme_ld1h_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
33
+DEF_HELPER_FLAGS_5(sme_ld1h_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
34
+DEF_HELPER_FLAGS_5(sme_ld1h_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
35
+DEF_HELPER_FLAGS_5(sme_ld1h_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
36
+DEF_HELPER_FLAGS_5(sme_ld1h_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
37
+DEF_HELPER_FLAGS_5(sme_ld1h_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
38
+DEF_HELPER_FLAGS_5(sme_ld1h_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
39
+DEF_HELPER_FLAGS_5(sme_ld1h_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
40
+
41
+DEF_HELPER_FLAGS_5(sme_ld1s_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
42
+DEF_HELPER_FLAGS_5(sme_ld1s_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
43
+DEF_HELPER_FLAGS_5(sme_ld1s_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
44
+DEF_HELPER_FLAGS_5(sme_ld1s_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
45
+DEF_HELPER_FLAGS_5(sme_ld1s_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
46
+DEF_HELPER_FLAGS_5(sme_ld1s_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
47
+DEF_HELPER_FLAGS_5(sme_ld1s_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
48
+DEF_HELPER_FLAGS_5(sme_ld1s_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
49
+
50
+DEF_HELPER_FLAGS_5(sme_ld1d_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
51
+DEF_HELPER_FLAGS_5(sme_ld1d_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
52
+DEF_HELPER_FLAGS_5(sme_ld1d_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
53
+DEF_HELPER_FLAGS_5(sme_ld1d_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
54
+DEF_HELPER_FLAGS_5(sme_ld1d_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
55
+DEF_HELPER_FLAGS_5(sme_ld1d_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
56
+DEF_HELPER_FLAGS_5(sme_ld1d_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
57
+DEF_HELPER_FLAGS_5(sme_ld1d_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
58
+
59
+DEF_HELPER_FLAGS_5(sme_ld1q_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
60
+DEF_HELPER_FLAGS_5(sme_ld1q_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
61
+DEF_HELPER_FLAGS_5(sme_ld1q_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
62
+DEF_HELPER_FLAGS_5(sme_ld1q_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
63
+DEF_HELPER_FLAGS_5(sme_ld1q_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
64
+DEF_HELPER_FLAGS_5(sme_ld1q_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
65
+DEF_HELPER_FLAGS_5(sme_ld1q_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
66
+DEF_HELPER_FLAGS_5(sme_ld1q_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
67
+
68
+DEF_HELPER_FLAGS_5(sme_st1b_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
69
+DEF_HELPER_FLAGS_5(sme_st1b_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
70
+DEF_HELPER_FLAGS_5(sme_st1b_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
71
+DEF_HELPER_FLAGS_5(sme_st1b_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
72
+
73
+DEF_HELPER_FLAGS_5(sme_st1h_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
74
+DEF_HELPER_FLAGS_5(sme_st1h_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
75
+DEF_HELPER_FLAGS_5(sme_st1h_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
76
+DEF_HELPER_FLAGS_5(sme_st1h_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
77
+DEF_HELPER_FLAGS_5(sme_st1h_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
78
+DEF_HELPER_FLAGS_5(sme_st1h_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
79
+DEF_HELPER_FLAGS_5(sme_st1h_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
80
+DEF_HELPER_FLAGS_5(sme_st1h_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
81
+
82
+DEF_HELPER_FLAGS_5(sme_st1s_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
83
+DEF_HELPER_FLAGS_5(sme_st1s_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
84
+DEF_HELPER_FLAGS_5(sme_st1s_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
85
+DEF_HELPER_FLAGS_5(sme_st1s_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
86
+DEF_HELPER_FLAGS_5(sme_st1s_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
87
+DEF_HELPER_FLAGS_5(sme_st1s_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
88
+DEF_HELPER_FLAGS_5(sme_st1s_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
89
+DEF_HELPER_FLAGS_5(sme_st1s_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
90
+
91
+DEF_HELPER_FLAGS_5(sme_st1d_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
92
+DEF_HELPER_FLAGS_5(sme_st1d_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
93
+DEF_HELPER_FLAGS_5(sme_st1d_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
94
+DEF_HELPER_FLAGS_5(sme_st1d_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
95
+DEF_HELPER_FLAGS_5(sme_st1d_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
96
+DEF_HELPER_FLAGS_5(sme_st1d_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
97
+DEF_HELPER_FLAGS_5(sme_st1d_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
98
+DEF_HELPER_FLAGS_5(sme_st1d_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
99
+
100
+DEF_HELPER_FLAGS_5(sme_st1q_be_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
101
+DEF_HELPER_FLAGS_5(sme_st1q_le_h, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
102
+DEF_HELPER_FLAGS_5(sme_st1q_be_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
103
+DEF_HELPER_FLAGS_5(sme_st1q_le_v, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
104
+DEF_HELPER_FLAGS_5(sme_st1q_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
105
+DEF_HELPER_FLAGS_5(sme_st1q_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
106
+DEF_HELPER_FLAGS_5(sme_st1q_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
107
+DEF_HELPER_FLAGS_5(sme_st1q_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
108
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
109
index XXXXXXX..XXXXXXX 100644
110
--- a/target/arm/sme.decode
111
+++ b/target/arm/sme.decode
112
@@ -XXX,XX +XXX,XX @@ MOVA 11000000 esz:2 00001 0 v:1 .. pg:3 0 za_imm:4 zr:5 \
113
&mova to_vec=1 rs=%mova_rs
114
MOVA 11000000 11 00001 1 v:1 .. pg:3 0 za_imm:4 zr:5 \
115
&mova to_vec=1 rs=%mova_rs esz=4
116
+
117
+### SME Memory
118
+
119
+&ldst esz rs pg rn rm za_imm v:bool st:bool
120
+
121
+LDST1 1110000 0 esz:2 st:1 rm:5 v:1 .. pg:3 rn:5 0 za_imm:4 \
122
+ &ldst rs=%mova_rs
123
+LDST1 1110000 111 st:1 rm:5 v:1 .. pg:3 rn:5 0 za_imm:4 \
124
+ &ldst esz=4 rs=%mova_rs
125
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
126
index XXXXXXX..XXXXXXX 100644
127
--- a/target/arm/sme_helper.c
128
+++ b/target/arm/sme_helper.c
17
@@ -XXX,XX +XXX,XX @@
129
@@ -XXX,XX +XXX,XX @@
18
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
130
19
*/
131
#include "qemu/osdep.h"
20
132
#include "cpu.h"
21
-#if DEPTH == 32
133
+#include "internals.h"
22
-# define BPP 4
134
#include "tcg/tcg-gvec-desc.h"
23
-# define PIXEL_TYPE uint32_t
135
#include "exec/helper-proto.h"
24
-#else
136
+#include "exec/cpu_ldst.h"
25
-# error unsupport depth
137
+#include "exec/exec-all.h"
26
-#endif
138
#include "qemu/int128.h"
27
-
139
#include "vec_internal.h"
28
/*
140
+#include "sve_ldst_internal.h"
29
* 2-bit colour
141
30
*/
142
/* ResetSVEState */
31
-static void glue(draw_line2_, DEPTH)(void *opaque,
143
void arm_reset_sve_state(CPUARMState *env)
32
- uint8_t *d, const uint8_t *s, int width, int deststep)
144
@@ -XXX,XX +XXX,XX @@ void HELPER(sme_mova_zc_q)(void *vd, void *za, void *vg, uint32_t desc)
33
+static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
34
+ int width, int deststep)
35
{
36
uint16_t *pal = opaque;
37
uint8_t v, r, g, b;
38
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line2_, DEPTH)(void *opaque,
39
r = (pal[v & 3] >> 4) & 0xf0;
40
g = pal[v & 3] & 0xf0;
41
b = (pal[v & 3] << 4) & 0xf0;
42
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
43
- d += BPP;
44
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
45
+ d += 4;
46
v >>= 2;
47
r = (pal[v & 3] >> 4) & 0xf0;
48
g = pal[v & 3] & 0xf0;
49
b = (pal[v & 3] << 4) & 0xf0;
50
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
51
- d += BPP;
52
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
53
+ d += 4;
54
v >>= 2;
55
r = (pal[v & 3] >> 4) & 0xf0;
56
g = pal[v & 3] & 0xf0;
57
b = (pal[v & 3] << 4) & 0xf0;
58
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
59
- d += BPP;
60
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
61
+ d += 4;
62
v >>= 2;
63
r = (pal[v & 3] >> 4) & 0xf0;
64
g = pal[v & 3] & 0xf0;
65
b = (pal[v & 3] << 4) & 0xf0;
66
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
67
- d += BPP;
68
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
69
+ d += 4;
70
s ++;
71
width -= 4;
72
} while (width > 0);
73
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line2_, DEPTH)(void *opaque,
74
/*
75
* 4-bit colour
76
*/
77
-static void glue(draw_line4_, DEPTH)(void *opaque,
78
- uint8_t *d, const uint8_t *s, int width, int deststep)
79
+static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
80
+ int width, int deststep)
81
{
82
uint16_t *pal = opaque;
83
uint8_t v, r, g, b;
84
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line4_, DEPTH)(void *opaque,
85
r = (pal[v & 0xf] >> 4) & 0xf0;
86
g = pal[v & 0xf] & 0xf0;
87
b = (pal[v & 0xf] << 4) & 0xf0;
88
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
89
- d += BPP;
90
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
91
+ d += 4;
92
v >>= 4;
93
r = (pal[v & 0xf] >> 4) & 0xf0;
94
g = pal[v & 0xf] & 0xf0;
95
b = (pal[v & 0xf] << 4) & 0xf0;
96
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
97
- d += BPP;
98
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
99
+ d += 4;
100
s ++;
101
width -= 2;
102
} while (width > 0);
103
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line4_, DEPTH)(void *opaque,
104
/*
105
* 8-bit colour
106
*/
107
-static void glue(draw_line8_, DEPTH)(void *opaque,
108
- uint8_t *d, const uint8_t *s, int width, int deststep)
109
+static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
110
+ int width, int deststep)
111
{
112
uint16_t *pal = opaque;
113
uint8_t v, r, g, b;
114
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line8_, DEPTH)(void *opaque,
115
r = (pal[v] >> 4) & 0xf0;
116
g = pal[v] & 0xf0;
117
b = (pal[v] << 4) & 0xf0;
118
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
119
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
120
s ++;
121
- d += BPP;
122
+ d += 4;
123
} while (-- width != 0);
124
}
145
}
125
146
126
/*
147
#undef DO_MOVA_Z
127
* 12-bit colour
148
+
128
*/
149
+/*
129
-static void glue(draw_line12_, DEPTH)(void *opaque,
150
+ * Clear elements in a tile slice comprising len bytes.
130
- uint8_t *d, const uint8_t *s, int width, int deststep)
151
+ */
131
+static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
152
+
132
+ int width, int deststep)
153
+typedef void ClearFn(void *ptr, size_t off, size_t len);
133
{
154
+
134
uint16_t v;
155
+static void clear_horizontal(void *ptr, size_t off, size_t len)
135
uint8_t r, g, b;
156
+{
136
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line12_, DEPTH)(void *opaque,
157
+ memset(ptr + off, 0, len);
137
r = (v >> 4) & 0xf0;
158
+}
138
g = v & 0xf0;
159
+
139
b = (v << 4) & 0xf0;
160
+static void clear_vertical_b(void *vptr, size_t off, size_t len)
140
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
161
+{
141
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
162
+ for (size_t i = 0; i < len; ++i) {
142
s += 2;
163
+ *(uint8_t *)(vptr + tile_vslice_offset(i + off)) = 0;
143
- d += BPP;
164
+ }
144
+ d += 4;
165
+}
145
} while (-- width != 0);
166
+
167
+static void clear_vertical_h(void *vptr, size_t off, size_t len)
168
+{
169
+ for (size_t i = 0; i < len; i += 2) {
170
+ *(uint16_t *)(vptr + tile_vslice_offset(i + off)) = 0;
171
+ }
172
+}
173
+
174
+static void clear_vertical_s(void *vptr, size_t off, size_t len)
175
+{
176
+ for (size_t i = 0; i < len; i += 4) {
177
+ *(uint32_t *)(vptr + tile_vslice_offset(i + off)) = 0;
178
+ }
179
+}
180
+
181
+static void clear_vertical_d(void *vptr, size_t off, size_t len)
182
+{
183
+ for (size_t i = 0; i < len; i += 8) {
184
+ *(uint64_t *)(vptr + tile_vslice_offset(i + off)) = 0;
185
+ }
186
+}
187
+
188
+static void clear_vertical_q(void *vptr, size_t off, size_t len)
189
+{
190
+ for (size_t i = 0; i < len; i += 16) {
191
+ memset(vptr + tile_vslice_offset(i + off), 0, 16);
192
+ }
193
+}
194
+
195
+/*
196
+ * Copy elements from an array into a tile slice comprising len bytes.
197
+ */
198
+
199
+typedef void CopyFn(void *dst, const void *src, size_t len);
200
+
201
+static void copy_horizontal(void *dst, const void *src, size_t len)
202
+{
203
+ memcpy(dst, src, len);
204
+}
205
+
206
+static void copy_vertical_b(void *vdst, const void *vsrc, size_t len)
207
+{
208
+ const uint8_t *src = vsrc;
209
+ uint8_t *dst = vdst;
210
+ size_t i;
211
+
212
+ for (i = 0; i < len; ++i) {
213
+ dst[tile_vslice_index(i)] = src[i];
214
+ }
215
+}
216
+
217
+static void copy_vertical_h(void *vdst, const void *vsrc, size_t len)
218
+{
219
+ const uint16_t *src = vsrc;
220
+ uint16_t *dst = vdst;
221
+ size_t i;
222
+
223
+ for (i = 0; i < len / 2; ++i) {
224
+ dst[tile_vslice_index(i)] = src[i];
225
+ }
226
+}
227
+
228
+static void copy_vertical_s(void *vdst, const void *vsrc, size_t len)
229
+{
230
+ const uint32_t *src = vsrc;
231
+ uint32_t *dst = vdst;
232
+ size_t i;
233
+
234
+ for (i = 0; i < len / 4; ++i) {
235
+ dst[tile_vslice_index(i)] = src[i];
236
+ }
237
+}
238
+
239
+static void copy_vertical_d(void *vdst, const void *vsrc, size_t len)
240
+{
241
+ const uint64_t *src = vsrc;
242
+ uint64_t *dst = vdst;
243
+ size_t i;
244
+
245
+ for (i = 0; i < len / 8; ++i) {
246
+ dst[tile_vslice_index(i)] = src[i];
247
+ }
248
+}
249
+
250
+static void copy_vertical_q(void *vdst, const void *vsrc, size_t len)
251
+{
252
+ for (size_t i = 0; i < len; i += 16) {
253
+ memcpy(vdst + tile_vslice_offset(i), vsrc + i, 16);
254
+ }
255
+}
256
+
257
+/*
258
+ * Host and TLB primitives for vertical tile slice addressing.
259
+ */
260
+
261
+#define DO_LD(NAME, TYPE, HOST, TLB) \
262
+static inline void sme_##NAME##_v_host(void *za, intptr_t off, void *host) \
263
+{ \
264
+ TYPE val = HOST(host); \
265
+ *(TYPE *)(za + tile_vslice_offset(off)) = val; \
266
+} \
267
+static inline void sme_##NAME##_v_tlb(CPUARMState *env, void *za, \
268
+ intptr_t off, target_ulong addr, uintptr_t ra) \
269
+{ \
270
+ TYPE val = TLB(env, useronly_clean_ptr(addr), ra); \
271
+ *(TYPE *)(za + tile_vslice_offset(off)) = val; \
272
+}
273
+
274
+#define DO_ST(NAME, TYPE, HOST, TLB) \
275
+static inline void sme_##NAME##_v_host(void *za, intptr_t off, void *host) \
276
+{ \
277
+ TYPE val = *(TYPE *)(za + tile_vslice_offset(off)); \
278
+ HOST(host, val); \
279
+} \
280
+static inline void sme_##NAME##_v_tlb(CPUARMState *env, void *za, \
281
+ intptr_t off, target_ulong addr, uintptr_t ra) \
282
+{ \
283
+ TYPE val = *(TYPE *)(za + tile_vslice_offset(off)); \
284
+ TLB(env, useronly_clean_ptr(addr), val, ra); \
285
+}
286
+
287
+/*
288
+ * The ARMVectorReg elements are stored in host-endian 64-bit units.
289
+ * For 128-bit quantities, the sequence defined by the Elem[] pseudocode
290
+ * corresponds to storing the two 64-bit pieces in little-endian order.
291
+ */
292
+#define DO_LDQ(HNAME, VNAME, BE, HOST, TLB) \
293
+static inline void HNAME##_host(void *za, intptr_t off, void *host) \
294
+{ \
295
+ uint64_t val0 = HOST(host), val1 = HOST(host + 8); \
296
+ uint64_t *ptr = za + off; \
297
+ ptr[0] = BE ? val1 : val0, ptr[1] = BE ? val0 : val1; \
298
+} \
299
+static inline void VNAME##_v_host(void *za, intptr_t off, void *host) \
300
+{ \
301
+ HNAME##_host(za, tile_vslice_offset(off), host); \
302
+} \
303
+static inline void HNAME##_tlb(CPUARMState *env, void *za, intptr_t off, \
304
+ target_ulong addr, uintptr_t ra) \
305
+{ \
306
+ uint64_t val0 = TLB(env, useronly_clean_ptr(addr), ra); \
307
+ uint64_t val1 = TLB(env, useronly_clean_ptr(addr + 8), ra); \
308
+ uint64_t *ptr = za + off; \
309
+ ptr[0] = BE ? val1 : val0, ptr[1] = BE ? val0 : val1; \
310
+} \
311
+static inline void VNAME##_v_tlb(CPUARMState *env, void *za, intptr_t off, \
312
+ target_ulong addr, uintptr_t ra) \
313
+{ \
314
+ HNAME##_tlb(env, za, tile_vslice_offset(off), addr, ra); \
315
+}
316
+
317
+#define DO_STQ(HNAME, VNAME, BE, HOST, TLB) \
318
+static inline void HNAME##_host(void *za, intptr_t off, void *host) \
319
+{ \
320
+ uint64_t *ptr = za + off; \
321
+ HOST(host, ptr[BE]); \
322
+ HOST(host + 1, ptr[!BE]); \
323
+} \
324
+static inline void VNAME##_v_host(void *za, intptr_t off, void *host) \
325
+{ \
326
+ HNAME##_host(za, tile_vslice_offset(off), host); \
327
+} \
328
+static inline void HNAME##_tlb(CPUARMState *env, void *za, intptr_t off, \
329
+ target_ulong addr, uintptr_t ra) \
330
+{ \
331
+ uint64_t *ptr = za + off; \
332
+ TLB(env, useronly_clean_ptr(addr), ptr[BE], ra); \
333
+ TLB(env, useronly_clean_ptr(addr + 8), ptr[!BE], ra); \
334
+} \
335
+static inline void VNAME##_v_tlb(CPUARMState *env, void *za, intptr_t off, \
336
+ target_ulong addr, uintptr_t ra) \
337
+{ \
338
+ HNAME##_tlb(env, za, tile_vslice_offset(off), addr, ra); \
339
+}
340
+
341
+DO_LD(ld1b, uint8_t, ldub_p, cpu_ldub_data_ra)
342
+DO_LD(ld1h_be, uint16_t, lduw_be_p, cpu_lduw_be_data_ra)
343
+DO_LD(ld1h_le, uint16_t, lduw_le_p, cpu_lduw_le_data_ra)
344
+DO_LD(ld1s_be, uint32_t, ldl_be_p, cpu_ldl_be_data_ra)
345
+DO_LD(ld1s_le, uint32_t, ldl_le_p, cpu_ldl_le_data_ra)
346
+DO_LD(ld1d_be, uint64_t, ldq_be_p, cpu_ldq_be_data_ra)
347
+DO_LD(ld1d_le, uint64_t, ldq_le_p, cpu_ldq_le_data_ra)
348
+
349
+DO_LDQ(sve_ld1qq_be, sme_ld1q_be, 1, ldq_be_p, cpu_ldq_be_data_ra)
350
+DO_LDQ(sve_ld1qq_le, sme_ld1q_le, 0, ldq_le_p, cpu_ldq_le_data_ra)
351
+
352
+DO_ST(st1b, uint8_t, stb_p, cpu_stb_data_ra)
353
+DO_ST(st1h_be, uint16_t, stw_be_p, cpu_stw_be_data_ra)
354
+DO_ST(st1h_le, uint16_t, stw_le_p, cpu_stw_le_data_ra)
355
+DO_ST(st1s_be, uint32_t, stl_be_p, cpu_stl_be_data_ra)
356
+DO_ST(st1s_le, uint32_t, stl_le_p, cpu_stl_le_data_ra)
357
+DO_ST(st1d_be, uint64_t, stq_be_p, cpu_stq_be_data_ra)
358
+DO_ST(st1d_le, uint64_t, stq_le_p, cpu_stq_le_data_ra)
359
+
360
+DO_STQ(sve_st1qq_be, sme_st1q_be, 1, stq_be_p, cpu_stq_be_data_ra)
361
+DO_STQ(sve_st1qq_le, sme_st1q_le, 0, stq_le_p, cpu_stq_le_data_ra)
362
+
363
+#undef DO_LD
364
+#undef DO_ST
365
+#undef DO_LDQ
366
+#undef DO_STQ
367
+
368
+/*
369
+ * Common helper for all contiguous predicated loads.
370
+ */
371
+
372
+static inline QEMU_ALWAYS_INLINE
373
+void sme_ld1(CPUARMState *env, void *za, uint64_t *vg,
374
+ const target_ulong addr, uint32_t desc, const uintptr_t ra,
375
+ const int esz, uint32_t mtedesc, bool vertical,
376
+ sve_ldst1_host_fn *host_fn,
377
+ sve_ldst1_tlb_fn *tlb_fn,
378
+ ClearFn *clr_fn,
379
+ CopyFn *cpy_fn)
380
+{
381
+ const intptr_t reg_max = simd_oprsz(desc);
382
+ const intptr_t esize = 1 << esz;
383
+ intptr_t reg_off, reg_last;
384
+ SVEContLdSt info;
385
+ void *host;
386
+ int flags;
387
+
388
+ /* Find the active elements. */
389
+ if (!sve_cont_ldst_elements(&info, addr, vg, reg_max, esz, esize)) {
390
+ /* The entire predicate was false; no load occurs. */
391
+ clr_fn(za, 0, reg_max);
392
+ return;
393
+ }
394
+
395
+ /* Probe the page(s). Exit with exception for any invalid page. */
396
+ sve_cont_ldst_pages(&info, FAULT_ALL, env, addr, MMU_DATA_LOAD, ra);
397
+
398
+ /* Handle watchpoints for all active elements. */
399
+ sve_cont_ldst_watchpoints(&info, env, vg, addr, esize, esize,
400
+ BP_MEM_READ, ra);
401
+
402
+ /*
403
+ * Handle mte checks for all active elements.
404
+ * Since TBI must be set for MTE, !mtedesc => !mte_active.
405
+ */
406
+ if (mtedesc) {
407
+ sve_cont_ldst_mte_check(&info, env, vg, addr, esize, esize,
408
+ mtedesc, ra);
409
+ }
410
+
411
+ flags = info.page[0].flags | info.page[1].flags;
412
+ if (unlikely(flags != 0)) {
413
+#ifdef CONFIG_USER_ONLY
414
+ g_assert_not_reached();
415
+#else
416
+ /*
417
+ * At least one page includes MMIO.
418
+ * Any bus operation can fail with cpu_transaction_failed,
419
+ * which for ARM will raise SyncExternal. Perform the load
420
+ * into scratch memory to preserve register state until the end.
421
+ */
422
+ ARMVectorReg scratch = { };
423
+
424
+ reg_off = info.reg_off_first[0];
425
+ reg_last = info.reg_off_last[1];
426
+ if (reg_last < 0) {
427
+ reg_last = info.reg_off_split;
428
+ if (reg_last < 0) {
429
+ reg_last = info.reg_off_last[0];
430
+ }
431
+ }
432
+
433
+ do {
434
+ uint64_t pg = vg[reg_off >> 6];
435
+ do {
436
+ if ((pg >> (reg_off & 63)) & 1) {
437
+ tlb_fn(env, &scratch, reg_off, addr + reg_off, ra);
438
+ }
439
+ reg_off += esize;
440
+ } while (reg_off & 63);
441
+ } while (reg_off <= reg_last);
442
+
443
+ cpy_fn(za, &scratch, reg_max);
444
+ return;
445
+#endif
446
+ }
447
+
448
+ /* The entire operation is in RAM, on valid pages. */
449
+
450
+ reg_off = info.reg_off_first[0];
451
+ reg_last = info.reg_off_last[0];
452
+ host = info.page[0].host;
453
+
454
+ if (!vertical) {
455
+ memset(za, 0, reg_max);
456
+ } else if (reg_off) {
457
+ clr_fn(za, 0, reg_off);
458
+ }
459
+
460
+ while (reg_off <= reg_last) {
461
+ uint64_t pg = vg[reg_off >> 6];
462
+ do {
463
+ if ((pg >> (reg_off & 63)) & 1) {
464
+ host_fn(za, reg_off, host + reg_off);
465
+ } else if (vertical) {
466
+ clr_fn(za, reg_off, esize);
467
+ }
468
+ reg_off += esize;
469
+ } while (reg_off <= reg_last && (reg_off & 63));
470
+ }
471
+
472
+ /*
473
+ * Use the slow path to manage the cross-page misalignment.
474
+ * But we know this is RAM and cannot trap.
475
+ */
476
+ reg_off = info.reg_off_split;
477
+ if (unlikely(reg_off >= 0)) {
478
+ tlb_fn(env, za, reg_off, addr + reg_off, ra);
479
+ }
480
+
481
+ reg_off = info.reg_off_first[1];
482
+ if (unlikely(reg_off >= 0)) {
483
+ reg_last = info.reg_off_last[1];
484
+ host = info.page[1].host;
485
+
486
+ do {
487
+ uint64_t pg = vg[reg_off >> 6];
488
+ do {
489
+ if ((pg >> (reg_off & 63)) & 1) {
490
+ host_fn(za, reg_off, host + reg_off);
491
+ } else if (vertical) {
492
+ clr_fn(za, reg_off, esize);
493
+ }
494
+ reg_off += esize;
495
+ } while (reg_off & 63);
496
+ } while (reg_off <= reg_last);
497
+ }
498
+}
499
+
500
+static inline QEMU_ALWAYS_INLINE
501
+void sme_ld1_mte(CPUARMState *env, void *za, uint64_t *vg,
502
+ target_ulong addr, uint32_t desc, uintptr_t ra,
503
+ const int esz, bool vertical,
504
+ sve_ldst1_host_fn *host_fn,
505
+ sve_ldst1_tlb_fn *tlb_fn,
506
+ ClearFn *clr_fn,
507
+ CopyFn *cpy_fn)
508
+{
509
+ uint32_t mtedesc = desc >> (SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
510
+ int bit55 = extract64(addr, 55, 1);
511
+
512
+ /* Remove mtedesc from the normal sve descriptor. */
513
+ desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
514
+
515
+ /* Perform gross MTE suppression early. */
516
+ if (!tbi_check(desc, bit55) ||
517
+ tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
518
+ mtedesc = 0;
519
+ }
520
+
521
+ sme_ld1(env, za, vg, addr, desc, ra, esz, mtedesc, vertical,
522
+ host_fn, tlb_fn, clr_fn, cpy_fn);
523
+}
524
+
525
+#define DO_LD(L, END, ESZ) \
526
+void HELPER(sme_ld1##L##END##_h)(CPUARMState *env, void *za, void *vg, \
527
+ target_ulong addr, uint32_t desc) \
528
+{ \
529
+ sme_ld1(env, za, vg, addr, desc, GETPC(), ESZ, 0, false, \
530
+ sve_ld1##L##L##END##_host, sve_ld1##L##L##END##_tlb, \
531
+ clear_horizontal, copy_horizontal); \
532
+} \
533
+void HELPER(sme_ld1##L##END##_v)(CPUARMState *env, void *za, void *vg, \
534
+ target_ulong addr, uint32_t desc) \
535
+{ \
536
+ sme_ld1(env, za, vg, addr, desc, GETPC(), ESZ, 0, true, \
537
+ sme_ld1##L##END##_v_host, sme_ld1##L##END##_v_tlb, \
538
+ clear_vertical_##L, copy_vertical_##L); \
539
+} \
540
+void HELPER(sme_ld1##L##END##_h_mte)(CPUARMState *env, void *za, void *vg, \
541
+ target_ulong addr, uint32_t desc) \
542
+{ \
543
+ sme_ld1_mte(env, za, vg, addr, desc, GETPC(), ESZ, false, \
544
+ sve_ld1##L##L##END##_host, sve_ld1##L##L##END##_tlb, \
545
+ clear_horizontal, copy_horizontal); \
546
+} \
547
+void HELPER(sme_ld1##L##END##_v_mte)(CPUARMState *env, void *za, void *vg, \
548
+ target_ulong addr, uint32_t desc) \
549
+{ \
550
+ sme_ld1_mte(env, za, vg, addr, desc, GETPC(), ESZ, true, \
551
+ sme_ld1##L##END##_v_host, sme_ld1##L##END##_v_tlb, \
552
+ clear_vertical_##L, copy_vertical_##L); \
553
+}
554
+
555
+DO_LD(b, , MO_8)
556
+DO_LD(h, _be, MO_16)
557
+DO_LD(h, _le, MO_16)
558
+DO_LD(s, _be, MO_32)
559
+DO_LD(s, _le, MO_32)
560
+DO_LD(d, _be, MO_64)
561
+DO_LD(d, _le, MO_64)
562
+DO_LD(q, _be, MO_128)
563
+DO_LD(q, _le, MO_128)
564
+
565
+#undef DO_LD
566
+
567
+/*
568
+ * Common helper for all contiguous predicated stores.
569
+ */
570
+
571
+static inline QEMU_ALWAYS_INLINE
572
+void sme_st1(CPUARMState *env, void *za, uint64_t *vg,
573
+ const target_ulong addr, uint32_t desc, const uintptr_t ra,
574
+ const int esz, uint32_t mtedesc, bool vertical,
575
+ sve_ldst1_host_fn *host_fn,
576
+ sve_ldst1_tlb_fn *tlb_fn)
577
+{
578
+ const intptr_t reg_max = simd_oprsz(desc);
579
+ const intptr_t esize = 1 << esz;
580
+ intptr_t reg_off, reg_last;
581
+ SVEContLdSt info;
582
+ void *host;
583
+ int flags;
584
+
585
+ /* Find the active elements. */
586
+ if (!sve_cont_ldst_elements(&info, addr, vg, reg_max, esz, esize)) {
587
+ /* The entire predicate was false; no store occurs. */
588
+ return;
589
+ }
590
+
591
+ /* Probe the page(s). Exit with exception for any invalid page. */
592
+ sve_cont_ldst_pages(&info, FAULT_ALL, env, addr, MMU_DATA_STORE, ra);
593
+
594
+ /* Handle watchpoints for all active elements. */
595
+ sve_cont_ldst_watchpoints(&info, env, vg, addr, esize, esize,
596
+ BP_MEM_WRITE, ra);
597
+
598
+ /*
599
+ * Handle mte checks for all active elements.
600
+ * Since TBI must be set for MTE, !mtedesc => !mte_active.
601
+ */
602
+ if (mtedesc) {
603
+ sve_cont_ldst_mte_check(&info, env, vg, addr, esize, esize,
604
+ mtedesc, ra);
605
+ }
606
+
607
+ flags = info.page[0].flags | info.page[1].flags;
608
+ if (unlikely(flags != 0)) {
609
+#ifdef CONFIG_USER_ONLY
610
+ g_assert_not_reached();
611
+#else
612
+ /*
613
+ * At least one page includes MMIO.
614
+ * Any bus operation can fail with cpu_transaction_failed,
615
+ * which for ARM will raise SyncExternal. We cannot avoid
616
+ * this fault and will leave with the store incomplete.
617
+ */
618
+ reg_off = info.reg_off_first[0];
619
+ reg_last = info.reg_off_last[1];
620
+ if (reg_last < 0) {
621
+ reg_last = info.reg_off_split;
622
+ if (reg_last < 0) {
623
+ reg_last = info.reg_off_last[0];
624
+ }
625
+ }
626
+
627
+ do {
628
+ uint64_t pg = vg[reg_off >> 6];
629
+ do {
630
+ if ((pg >> (reg_off & 63)) & 1) {
631
+ tlb_fn(env, za, reg_off, addr + reg_off, ra);
632
+ }
633
+ reg_off += esize;
634
+ } while (reg_off & 63);
635
+ } while (reg_off <= reg_last);
636
+ return;
637
+#endif
638
+ }
639
+
640
+ reg_off = info.reg_off_first[0];
641
+ reg_last = info.reg_off_last[0];
642
+ host = info.page[0].host;
643
+
644
+ while (reg_off <= reg_last) {
645
+ uint64_t pg = vg[reg_off >> 6];
646
+ do {
647
+ if ((pg >> (reg_off & 63)) & 1) {
648
+ host_fn(za, reg_off, host + reg_off);
649
+ }
650
+ reg_off += 1 << esz;
651
+ } while (reg_off <= reg_last && (reg_off & 63));
652
+ }
653
+
654
+ /*
655
+ * Use the slow path to manage the cross-page misalignment.
656
+ * But we know this is RAM and cannot trap.
657
+ */
658
+ reg_off = info.reg_off_split;
659
+ if (unlikely(reg_off >= 0)) {
660
+ tlb_fn(env, za, reg_off, addr + reg_off, ra);
661
+ }
662
+
663
+ reg_off = info.reg_off_first[1];
664
+ if (unlikely(reg_off >= 0)) {
665
+ reg_last = info.reg_off_last[1];
666
+ host = info.page[1].host;
667
+
668
+ do {
669
+ uint64_t pg = vg[reg_off >> 6];
670
+ do {
671
+ if ((pg >> (reg_off & 63)) & 1) {
672
+ host_fn(za, reg_off, host + reg_off);
673
+ }
674
+ reg_off += 1 << esz;
675
+ } while (reg_off & 63);
676
+ } while (reg_off <= reg_last);
677
+ }
678
+}
679
+
680
+static inline QEMU_ALWAYS_INLINE
681
+void sme_st1_mte(CPUARMState *env, void *za, uint64_t *vg, target_ulong addr,
682
+ uint32_t desc, uintptr_t ra, int esz, bool vertical,
683
+ sve_ldst1_host_fn *host_fn,
684
+ sve_ldst1_tlb_fn *tlb_fn)
685
+{
686
+ uint32_t mtedesc = desc >> (SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
687
+ int bit55 = extract64(addr, 55, 1);
688
+
689
+ /* Remove mtedesc from the normal sve descriptor. */
690
+ desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
691
+
692
+ /* Perform gross MTE suppression early. */
693
+ if (!tbi_check(desc, bit55) ||
694
+ tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
695
+ mtedesc = 0;
696
+ }
697
+
698
+ sme_st1(env, za, vg, addr, desc, ra, esz, mtedesc,
699
+ vertical, host_fn, tlb_fn);
700
+}
701
+
702
+#define DO_ST(L, END, ESZ) \
703
+void HELPER(sme_st1##L##END##_h)(CPUARMState *env, void *za, void *vg, \
704
+ target_ulong addr, uint32_t desc) \
705
+{ \
706
+ sme_st1(env, za, vg, addr, desc, GETPC(), ESZ, 0, false, \
707
+ sve_st1##L##L##END##_host, sve_st1##L##L##END##_tlb); \
708
+} \
709
+void HELPER(sme_st1##L##END##_v)(CPUARMState *env, void *za, void *vg, \
710
+ target_ulong addr, uint32_t desc) \
711
+{ \
712
+ sme_st1(env, za, vg, addr, desc, GETPC(), ESZ, 0, true, \
713
+ sme_st1##L##END##_v_host, sme_st1##L##END##_v_tlb); \
714
+} \
715
+void HELPER(sme_st1##L##END##_h_mte)(CPUARMState *env, void *za, void *vg, \
716
+ target_ulong addr, uint32_t desc) \
717
+{ \
718
+ sme_st1_mte(env, za, vg, addr, desc, GETPC(), ESZ, false, \
719
+ sve_st1##L##L##END##_host, sve_st1##L##L##END##_tlb); \
720
+} \
721
+void HELPER(sme_st1##L##END##_v_mte)(CPUARMState *env, void *za, void *vg, \
722
+ target_ulong addr, uint32_t desc) \
723
+{ \
724
+ sme_st1_mte(env, za, vg, addr, desc, GETPC(), ESZ, true, \
725
+ sme_st1##L##END##_v_host, sme_st1##L##END##_v_tlb); \
726
+}
727
+
728
+DO_ST(b, , MO_8)
729
+DO_ST(h, _be, MO_16)
730
+DO_ST(h, _le, MO_16)
731
+DO_ST(s, _be, MO_32)
732
+DO_ST(s, _le, MO_32)
733
+DO_ST(d, _be, MO_64)
734
+DO_ST(d, _le, MO_64)
735
+DO_ST(q, _be, MO_128)
736
+DO_ST(q, _le, MO_128)
737
+
738
+#undef DO_ST
739
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
740
index XXXXXXX..XXXXXXX 100644
741
--- a/target/arm/translate-sme.c
742
+++ b/target/arm/translate-sme.c
743
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVA(DisasContext *s, arg_MOVA *a)
744
745
return true;
146
}
746
}
147
747
+
148
/*
748
+static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
149
* 16-bit colour
749
+{
150
*/
750
+ typedef void GenLdSt1(TCGv_env, TCGv_ptr, TCGv_ptr, TCGv, TCGv_i32);
151
-static void glue(draw_line16_, DEPTH)(void *opaque,
751
+
152
- uint8_t *d, const uint8_t *s, int width, int deststep)
752
+ /*
153
+static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
753
+ * Indexed by [esz][be][v][mte][st], which is (except for load/store)
154
+ int width, int deststep)
754
+ * also the order in which the elements appear in the function names,
155
{
755
+ * and so how we must concatenate the pieces.
156
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
756
+ */
157
memcpy(d, s, width * 2);
757
+
158
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line16_, DEPTH)(void *opaque,
758
+#define FN_LS(F) { gen_helper_sme_ld1##F, gen_helper_sme_st1##F }
159
r = (v >> 8) & 0xf8;
759
+#define FN_MTE(F) { FN_LS(F), FN_LS(F##_mte) }
160
g = (v >> 3) & 0xfc;
760
+#define FN_HV(F) { FN_MTE(F##_h), FN_MTE(F##_v) }
161
b = (v << 3) & 0xf8;
761
+#define FN_END(L, B) { FN_HV(L), FN_HV(B) }
162
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
762
+
163
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
763
+ static GenLdSt1 * const fns[5][2][2][2][2] = {
164
s += 2;
764
+ FN_END(b, b),
165
- d += BPP;
765
+ FN_END(h_le, h_be),
166
+ d += 4;
766
+ FN_END(s_le, s_be),
167
} while (-- width != 0);
767
+ FN_END(d_le, d_be),
168
#endif
768
+ FN_END(q_le, q_be),
169
}
769
+ };
170
-
770
+
171
-#undef DEPTH
771
+#undef FN_LS
172
-#undef BPP
772
+#undef FN_MTE
173
-#undef PIXEL_TYPE
773
+#undef FN_HV
774
+#undef FN_END
775
+
776
+ TCGv_ptr t_za, t_pg;
777
+ TCGv_i64 addr;
778
+ int svl, desc = 0;
779
+ bool be = s->be_data == MO_BE;
780
+ bool mte = s->mte_active[0];
781
+
782
+ if (!dc_isar_feature(aa64_sme, s)) {
783
+ return false;
784
+ }
785
+ if (!sme_smza_enabled_check(s)) {
786
+ return true;
787
+ }
788
+
789
+ t_za = get_tile_rowcol(s, a->esz, a->rs, a->za_imm, a->v);
790
+ t_pg = pred_full_reg_ptr(s, a->pg);
791
+ addr = tcg_temp_new_i64();
792
+
793
+ tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->esz);
794
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
795
+
796
+ if (mte) {
797
+ desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
798
+ desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
799
+ desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
800
+ desc = FIELD_DP32(desc, MTEDESC, WRITE, a->st);
801
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << a->esz) - 1);
802
+ desc <<= SVE_MTEDESC_SHIFT;
803
+ } else {
804
+ addr = clean_data_tbi(s, addr);
805
+ }
806
+ svl = streaming_vec_reg_size(s);
807
+ desc = simd_desc(svl, svl, desc);
808
+
809
+ fns[a->esz][be][a->v][mte][a->st](cpu_env, t_za, t_pg, addr,
810
+ tcg_constant_i32(desc));
811
+
812
+ tcg_temp_free_ptr(t_za);
813
+ tcg_temp_free_ptr(t_pg);
814
+ tcg_temp_free_i64(addr);
815
+ return true;
816
+}
174
--
817
--
175
2.20.1
818
2.25.1
176
177
diff view generated by jsdifflib
1
For a long time now the UI layer has guaranteed that the console
1
From: Richard Henderson <richard.henderson@linaro.org>
2
surface is always 32 bits per pixel RGB. Remove the legacy dead
3
code from the milkymist display device which was handling the
4
possibility that the console surface was some other format.
5
2
3
Add a TCGv_ptr base argument, which will be cpu_env for SVE.
4
We will reuse this for SME save and restore array insns.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-22-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215103215.4944-2-peter.maydell@linaro.org
9
---
10
---
10
hw/arm/musicpal.c | 64 ++++++++++++++++++-----------------------------
11
target/arm/translate-a64.h | 3 +++
11
1 file changed, 24 insertions(+), 40 deletions(-)
12
target/arm/translate-sve.c | 48 ++++++++++++++++++++++++++++----------
13
2 files changed, 39 insertions(+), 12 deletions(-)
12
14
13
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
15
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/musicpal.c
17
--- a/target/arm/translate-a64.h
16
+++ b/hw/arm/musicpal.c
18
+++ b/target/arm/translate-a64.h
17
@@ -XXX,XX +XXX,XX @@ static uint8_t scale_lcd_color(musicpal_lcd_state *s, uint8_t col)
19
@@ -XXX,XX +XXX,XX @@ void gen_gvec_xar(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
20
uint32_t rm_ofs, int64_t shift,
21
uint32_t opr_sz, uint32_t max_sz);
22
23
+void gen_sve_ldr(DisasContext *s, TCGv_ptr, int vofs, int len, int rn, int imm);
24
+void gen_sve_str(DisasContext *s, TCGv_ptr, int vofs, int len, int rn, int imm);
25
+
26
#endif /* TARGET_ARM_TRANSLATE_A64_H */
27
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-sve.c
30
+++ b/target/arm/translate-sve.c
31
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(UCVTF_dd, aa64_sve, gen_gvec_fpst_arg_zpz,
32
* The load should begin at the address Rn + IMM.
33
*/
34
35
-static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
36
+void gen_sve_ldr(DisasContext *s, TCGv_ptr base, int vofs,
37
+ int len, int rn, int imm)
38
{
39
int len_align = QEMU_ALIGN_DOWN(len, 8);
40
int len_remain = len % 8;
41
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
42
t0 = tcg_temp_new_i64();
43
for (i = 0; i < len_align; i += 8) {
44
tcg_gen_qemu_ld_i64(t0, clean_addr, midx, MO_LEUQ);
45
- tcg_gen_st_i64(t0, cpu_env, vofs + i);
46
+ tcg_gen_st_i64(t0, base, vofs + i);
47
tcg_gen_addi_i64(clean_addr, clean_addr, 8);
48
}
49
tcg_temp_free_i64(t0);
50
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
51
clean_addr = new_tmp_a64_local(s);
52
tcg_gen_mov_i64(clean_addr, t0);
53
54
+ if (base != cpu_env) {
55
+ TCGv_ptr b = tcg_temp_local_new_ptr();
56
+ tcg_gen_mov_ptr(b, base);
57
+ base = b;
58
+ }
59
+
60
gen_set_label(loop);
61
62
t0 = tcg_temp_new_i64();
63
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
64
tcg_gen_addi_i64(clean_addr, clean_addr, 8);
65
66
tp = tcg_temp_new_ptr();
67
- tcg_gen_add_ptr(tp, cpu_env, i);
68
+ tcg_gen_add_ptr(tp, base, i);
69
tcg_gen_addi_ptr(i, i, 8);
70
tcg_gen_st_i64(t0, tp, vofs);
71
tcg_temp_free_ptr(tp);
72
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
73
74
tcg_gen_brcondi_ptr(TCG_COND_LTU, i, len_align, loop);
75
tcg_temp_free_ptr(i);
76
+
77
+ if (base != cpu_env) {
78
+ tcg_temp_free_ptr(base);
79
+ assert(len_remain == 0);
80
+ }
81
}
82
83
/*
84
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
85
default:
86
g_assert_not_reached();
87
}
88
- tcg_gen_st_i64(t0, cpu_env, vofs + len_align);
89
+ tcg_gen_st_i64(t0, base, vofs + len_align);
90
tcg_temp_free_i64(t0);
18
}
91
}
19
}
92
}
20
93
21
-#define SET_LCD_PIXEL(depth, type) \
94
/* Similarly for stores. */
22
-static inline void glue(set_lcd_pixel, depth) \
95
-static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
23
- (musicpal_lcd_state *s, int x, int y, type col) \
96
+void gen_sve_str(DisasContext *s, TCGv_ptr base, int vofs,
24
-{ \
97
+ int len, int rn, int imm)
25
- int dx, dy; \
98
{
26
- DisplaySurface *surface = qemu_console_surface(s->con); \
99
int len_align = QEMU_ALIGN_DOWN(len, 8);
27
- type *pixel = &((type *) surface_data(surface))[(y * 128 * 3 + x) * 3]; \
100
int len_remain = len % 8;
28
-\
101
@@ -XXX,XX +XXX,XX @@ static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
29
- for (dy = 0; dy < 3; dy++, pixel += 127 * 3) \
102
30
- for (dx = 0; dx < 3; dx++, pixel++) \
103
t0 = tcg_temp_new_i64();
31
- *pixel = col; \
104
for (i = 0; i < len_align; i += 8) {
32
+static inline void set_lcd_pixel32(musicpal_lcd_state *s,
105
- tcg_gen_ld_i64(t0, cpu_env, vofs + i);
33
+ int x, int y, uint32_t col)
106
+ tcg_gen_ld_i64(t0, base, vofs + i);
34
+{
107
tcg_gen_qemu_st_i64(t0, clean_addr, midx, MO_LEUQ);
35
+ int dx, dy;
108
tcg_gen_addi_i64(clean_addr, clean_addr, 8);
36
+ DisplaySurface *surface = qemu_console_surface(s->con);
109
}
37
+ uint32_t *pixel =
110
@@ -XXX,XX +XXX,XX @@ static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
38
+ &((uint32_t *) surface_data(surface))[(y * 128 * 3 + x) * 3];
111
clean_addr = new_tmp_a64_local(s);
112
tcg_gen_mov_i64(clean_addr, t0);
113
114
+ if (base != cpu_env) {
115
+ TCGv_ptr b = tcg_temp_local_new_ptr();
116
+ tcg_gen_mov_ptr(b, base);
117
+ base = b;
118
+ }
39
+
119
+
40
+ for (dy = 0; dy < 3; dy++, pixel += 127 * 3) {
120
gen_set_label(loop);
41
+ for (dx = 0; dx < 3; dx++, pixel++) {
121
42
+ *pixel = col;
122
t0 = tcg_temp_new_i64();
43
+ }
123
tp = tcg_temp_new_ptr();
44
+ }
124
- tcg_gen_add_ptr(tp, cpu_env, i);
45
}
125
+ tcg_gen_add_ptr(tp, base, i);
46
-SET_LCD_PIXEL(8, uint8_t)
126
tcg_gen_ld_i64(t0, tp, vofs);
47
-SET_LCD_PIXEL(16, uint16_t)
127
tcg_gen_addi_ptr(i, i, 8);
48
-SET_LCD_PIXEL(32, uint32_t)
128
tcg_temp_free_ptr(tp);
49
129
@@ -XXX,XX +XXX,XX @@ static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
50
static void lcd_refresh(void *opaque)
130
51
{
131
tcg_gen_brcondi_ptr(TCG_COND_LTU, i, len_align, loop);
52
musicpal_lcd_state *s = opaque;
132
tcg_temp_free_ptr(i);
53
- DisplaySurface *surface = qemu_console_surface(s->con);
133
+
54
int x, y, col;
134
+ if (base != cpu_env) {
55
135
+ tcg_temp_free_ptr(base);
56
- switch (surface_bits_per_pixel(surface)) {
136
+ assert(len_remain == 0);
57
- case 0:
58
- return;
59
-#define LCD_REFRESH(depth, func) \
60
- case depth: \
61
- col = func(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff), \
62
- scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff), \
63
- scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff)); \
64
- for (x = 0; x < 128; x++) { \
65
- for (y = 0; y < 64; y++) { \
66
- if (s->video_ram[x + (y/8)*128] & (1 << (y % 8))) { \
67
- glue(set_lcd_pixel, depth)(s, x, y, col); \
68
- } else { \
69
- glue(set_lcd_pixel, depth)(s, x, y, 0); \
70
- } \
71
- } \
72
- } \
73
- break;
74
- LCD_REFRESH(8, rgb_to_pixel8)
75
- LCD_REFRESH(16, rgb_to_pixel16)
76
- LCD_REFRESH(32, (is_surface_bgr(surface) ?
77
- rgb_to_pixel32bgr : rgb_to_pixel32))
78
- default:
79
- hw_error("unsupported colour depth %i\n",
80
- surface_bits_per_pixel(surface));
81
+ col = rgb_to_pixel32(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff),
82
+ scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff),
83
+ scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff));
84
+ for (x = 0; x < 128; x++) {
85
+ for (y = 0; y < 64; y++) {
86
+ if (s->video_ram[x + (y / 8) * 128] & (1 << (y % 8))) {
87
+ set_lcd_pixel32(s, x, y, col);
88
+ } else {
89
+ set_lcd_pixel32(s, x, y, 0);
90
+ }
91
+ }
137
+ }
92
}
138
}
93
139
94
dpy_gfx_update(s->con, 0, 0, 128*3, 64*3);
140
/* Predicate register stores can be any multiple of 2. */
141
if (len_remain) {
142
t0 = tcg_temp_new_i64();
143
- tcg_gen_ld_i64(t0, cpu_env, vofs + len_align);
144
+ tcg_gen_ld_i64(t0, base, vofs + len_align);
145
146
switch (len_remain) {
147
case 2:
148
@@ -XXX,XX +XXX,XX @@ static bool trans_LDR_zri(DisasContext *s, arg_rri *a)
149
if (sve_access_check(s)) {
150
int size = vec_full_reg_size(s);
151
int off = vec_full_reg_offset(s, a->rd);
152
- do_ldr(s, off, size, a->rn, a->imm * size);
153
+ gen_sve_ldr(s, cpu_env, off, size, a->rn, a->imm * size);
154
}
155
return true;
156
}
157
@@ -XXX,XX +XXX,XX @@ static bool trans_LDR_pri(DisasContext *s, arg_rri *a)
158
if (sve_access_check(s)) {
159
int size = pred_full_reg_size(s);
160
int off = pred_full_reg_offset(s, a->rd);
161
- do_ldr(s, off, size, a->rn, a->imm * size);
162
+ gen_sve_ldr(s, cpu_env, off, size, a->rn, a->imm * size);
163
}
164
return true;
165
}
166
@@ -XXX,XX +XXX,XX @@ static bool trans_STR_zri(DisasContext *s, arg_rri *a)
167
if (sve_access_check(s)) {
168
int size = vec_full_reg_size(s);
169
int off = vec_full_reg_offset(s, a->rd);
170
- do_str(s, off, size, a->rn, a->imm * size);
171
+ gen_sve_str(s, cpu_env, off, size, a->rn, a->imm * size);
172
}
173
return true;
174
}
175
@@ -XXX,XX +XXX,XX @@ static bool trans_STR_pri(DisasContext *s, arg_rri *a)
176
if (sve_access_check(s)) {
177
int size = pred_full_reg_size(s);
178
int off = pred_full_reg_offset(s, a->rd);
179
- do_str(s, off, size, a->rn, a->imm * size);
180
+ gen_sve_str(s, cpu_env, off, size, a->rn, a->imm * size);
181
}
182
return true;
183
}
95
--
184
--
96
2.20.1
185
2.25.1
97
98
diff view generated by jsdifflib
1
The AN524 version of the SCC interface has different behaviour for
1
From: Richard Henderson <richard.henderson@linaro.org>
2
some of the CFG registers; implement it.
3
2
4
Each board in this family can have minor differences in the meaning
3
We can reuse the SVE functions for LDR and STR, passing in the
5
of the CFG registers, so rather than trying to specify all the
4
base of the ZA vector and a zero offset.
6
possible semantics via individual device properties, we make the
7
behaviour conditional on the part-number field of the SCC_ID register
8
which the board code already passes us.
9
5
10
For the AN524, the differences are:
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
* CFG3 is reserved rather than being board switches
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
* CFG5 is a new register ("ACLK Frequency in Hz")
8
Message-id: 20220708151540.18136-23-richard.henderson@linaro.org
13
* CFG6 is a new register ("Clock divider for BRAM")
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/sme.decode | 7 +++++++
12
target/arm/translate-sme.c | 24 ++++++++++++++++++++++++
13
2 files changed, 31 insertions(+)
14
14
15
We implement both of the new registers as reads-as-written.
15
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
16
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210215115138.20465-11-peter.maydell@linaro.org
20
---
21
include/hw/misc/mps2-scc.h | 3 ++
22
hw/misc/mps2-scc.c | 71 ++++++++++++++++++++++++++++++++++++--
23
2 files changed, 72 insertions(+), 2 deletions(-)
24
25
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
26
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/misc/mps2-scc.h
17
--- a/target/arm/sme.decode
28
+++ b/include/hw/misc/mps2-scc.h
18
+++ b/target/arm/sme.decode
29
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
19
@@ -XXX,XX +XXX,XX @@ LDST1 1110000 0 esz:2 st:1 rm:5 v:1 .. pg:3 rn:5 0 za_imm:4 \
30
20
&ldst rs=%mova_rs
31
uint32_t cfg0;
21
LDST1 1110000 111 st:1 rm:5 v:1 .. pg:3 rn:5 0 za_imm:4 \
32
uint32_t cfg1;
22
&ldst esz=4 rs=%mova_rs
33
+ uint32_t cfg2;
23
+
34
uint32_t cfg4;
24
+&ldstr rv rn imm
35
+ uint32_t cfg5;
25
+@ldstr ....... ... . ...... .. ... rn:5 . imm:4 \
36
+ uint32_t cfg6;
26
+ &ldstr rv=%mova_rs
37
uint32_t cfgdata_rtn;
27
+
38
uint32_t cfgdata_out;
28
+LDR 1110000 100 0 000000 .. 000 ..... 0 .... @ldstr
39
uint32_t cfgctrl;
29
+STR 1110000 100 1 000000 .. 000 ..... 0 .... @ldstr
40
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
30
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
41
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/misc/mps2-scc.c
32
--- a/target/arm/translate-sme.c
43
+++ b/hw/misc/mps2-scc.c
33
+++ b/target/arm/translate-sme.c
44
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
45
35
tcg_temp_free_i64(addr);
46
REG32(CFG0, 0)
36
return true;
47
REG32(CFG1, 4)
37
}
48
+REG32(CFG2, 8)
38
+
49
REG32(CFG3, 0xc)
39
+typedef void GenLdStR(DisasContext *, TCGv_ptr, int, int, int, int);
50
REG32(CFG4, 0x10)
40
+
51
+REG32(CFG5, 0x14)
41
+static bool do_ldst_r(DisasContext *s, arg_ldstr *a, GenLdStR *fn)
52
+REG32(CFG6, 0x18)
53
REG32(CFGDATA_RTN, 0xa0)
54
REG32(CFGDATA_OUT, 0xa4)
55
REG32(CFGCTRL, 0xa8)
56
@@ -XXX,XX +XXX,XX @@ REG32(DLL, 0x100)
57
REG32(AID, 0xFF8)
58
REG32(ID, 0xFFC)
59
60
+static int scc_partno(MPS2SCC *s)
61
+{
42
+{
62
+ /* Return the partno field of the SCC_ID (0x524, 0x511, etc) */
43
+ int svl = streaming_vec_reg_size(s);
63
+ return extract32(s->id, 4, 8);
44
+ int imm = a->imm;
45
+ TCGv_ptr base;
46
+
47
+ if (!sme_za_enabled_check(s)) {
48
+ return true;
49
+ }
50
+
51
+ /* ZA[n] equates to ZA0H.B[n]. */
52
+ base = get_tile_rowcol(s, MO_8, a->rv, imm, false);
53
+
54
+ fn(s, base, 0, svl, a->rn, imm * svl);
55
+
56
+ tcg_temp_free_ptr(base);
57
+ return true;
64
+}
58
+}
65
+
59
+
66
/* Handle a write via the SYS_CFG channel to the specified function/device.
60
+TRANS_FEAT(LDR, aa64_sme, do_ldst_r, a, gen_sve_ldr)
67
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
61
+TRANS_FEAT(STR, aa64_sme, do_ldst_r, a, gen_sve_str)
68
*/
69
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
70
case A_CFG1:
71
r = s->cfg1;
72
break;
73
+ case A_CFG2:
74
+ if (scc_partno(s) != 0x524) {
75
+ /* CFG2 reserved on other boards */
76
+ goto bad_offset;
77
+ }
78
+ r = s->cfg2;
79
+ break;
80
case A_CFG3:
81
+ if (scc_partno(s) == 0x524) {
82
+ /* CFG3 reserved on AN524 */
83
+ goto bad_offset;
84
+ }
85
/* These are user-settable DIP switches on the board. We don't
86
* model that, so just return zeroes.
87
*/
88
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
89
case A_CFG4:
90
r = s->cfg4;
91
break;
92
+ case A_CFG5:
93
+ if (scc_partno(s) != 0x524) {
94
+ /* CFG5 reserved on other boards */
95
+ goto bad_offset;
96
+ }
97
+ r = s->cfg5;
98
+ break;
99
+ case A_CFG6:
100
+ if (scc_partno(s) != 0x524) {
101
+ /* CFG6 reserved on other boards */
102
+ goto bad_offset;
103
+ }
104
+ r = s->cfg6;
105
+ break;
106
case A_CFGDATA_RTN:
107
r = s->cfgdata_rtn;
108
break;
109
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
110
r = s->id;
111
break;
112
default:
113
+ bad_offset:
114
qemu_log_mask(LOG_GUEST_ERROR,
115
"MPS2 SCC read: bad offset %x\n", (int) offset);
116
r = 0;
117
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
118
led_set_state(s->led[i], extract32(value, i, 1));
119
}
120
break;
121
+ case A_CFG2:
122
+ if (scc_partno(s) != 0x524) {
123
+ /* CFG2 reserved on other boards */
124
+ goto bad_offset;
125
+ }
126
+ /* AN524: QSPI Select signal */
127
+ s->cfg2 = value;
128
+ break;
129
+ case A_CFG5:
130
+ if (scc_partno(s) != 0x524) {
131
+ /* CFG5 reserved on other boards */
132
+ goto bad_offset;
133
+ }
134
+ /* AN524: ACLK frequency in Hz */
135
+ s->cfg5 = value;
136
+ break;
137
+ case A_CFG6:
138
+ if (scc_partno(s) != 0x524) {
139
+ /* CFG6 reserved on other boards */
140
+ goto bad_offset;
141
+ }
142
+ /* AN524: Clock divider for BRAM */
143
+ s->cfg6 = value;
144
+ break;
145
case A_CFGDATA_OUT:
146
s->cfgdata_out = value;
147
break;
148
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
149
s->dll = deposit32(s->dll, 24, 8, extract32(value, 24, 8));
150
break;
151
default:
152
+ bad_offset:
153
qemu_log_mask(LOG_GUEST_ERROR,
154
"MPS2 SCC write: bad offset 0x%x\n", (int) offset);
155
break;
156
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_reset(DeviceState *dev)
157
trace_mps2_scc_reset();
158
s->cfg0 = 0;
159
s->cfg1 = 0;
160
+ s->cfg2 = 0;
161
+ s->cfg5 = 0;
162
+ s->cfg6 = 0;
163
s->cfgdata_rtn = 0;
164
s->cfgdata_out = 0;
165
s->cfgctrl = 0x100000;
166
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_realize(DeviceState *dev, Error **errp)
167
168
static const VMStateDescription mps2_scc_vmstate = {
169
.name = "mps2-scc",
170
- .version_id = 2,
171
- .minimum_version_id = 2,
172
+ .version_id = 3,
173
+ .minimum_version_id = 3,
174
.fields = (VMStateField[]) {
175
VMSTATE_UINT32(cfg0, MPS2SCC),
176
VMSTATE_UINT32(cfg1, MPS2SCC),
177
+ VMSTATE_UINT32(cfg2, MPS2SCC),
178
+ /* cfg3, cfg4 are read-only so need not be migrated */
179
+ VMSTATE_UINT32(cfg5, MPS2SCC),
180
+ VMSTATE_UINT32(cfg6, MPS2SCC),
181
VMSTATE_UINT32(cfgdata_rtn, MPS2SCC),
182
VMSTATE_UINT32(cfgdata_out, MPS2SCC),
183
VMSTATE_UINT32(cfgctrl, MPS2SCC),
184
--
62
--
185
2.20.1
63
2.25.1
186
187
diff view generated by jsdifflib
1
From: Doug Evans <dje@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Hao Wu <wuhaotsh@google.com>
4
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Doug Evans <dje@google.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210218212453.831406-4-dje@google.com
5
Message-id: 20220708151540.18136-24-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
7
---
10
tests/qtest/npcm7xx_emc-test.c | 862 +++++++++++++++++++++++++++++++++
8
target/arm/helper-sme.h | 5 +++
11
tests/qtest/meson.build | 3 +-
9
target/arm/sme.decode | 11 +++++
12
2 files changed, 864 insertions(+), 1 deletion(-)
10
target/arm/sme_helper.c | 90 ++++++++++++++++++++++++++++++++++++++
13
create mode 100644 tests/qtest/npcm7xx_emc-test.c
11
target/arm/translate-sme.c | 31 +++++++++++++
12
4 files changed, 137 insertions(+)
14
13
15
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
14
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
16
new file mode 100644
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX
16
--- a/target/arm/helper-sme.h
18
--- /dev/null
17
+++ b/target/arm/helper-sme.h
19
+++ b/tests/qtest/npcm7xx_emc-test.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sme_st1q_be_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i
20
@@ -XXX,XX +XXX,XX @@
19
DEF_HELPER_FLAGS_5(sme_st1q_le_h_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
21
+/*
20
DEF_HELPER_FLAGS_5(sme_st1q_be_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
22
+ * QTests for Nuvoton NPCM7xx EMC Modules.
21
DEF_HELPER_FLAGS_5(sme_st1q_le_v_mte, TCG_CALL_NO_WG, void, env, ptr, ptr, tl, i32)
23
+ *
24
+ * Copyright 2020 Google LLC
25
+ *
26
+ * This program is free software; you can redistribute it and/or modify it
27
+ * under the terms of the GNU General Public License as published by the
28
+ * Free Software Foundation; either version 2 of the License, or
29
+ * (at your option) any later version.
30
+ *
31
+ * This program is distributed in the hope that it will be useful, but WITHOUT
32
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
33
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
34
+ * for more details.
35
+ */
36
+
22
+
37
+#include "qemu/osdep.h"
23
+DEF_HELPER_FLAGS_5(sme_addha_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
38
+#include "qemu-common.h"
24
+DEF_HELPER_FLAGS_5(sme_addva_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
39
+#include "libqos/libqos.h"
25
+DEF_HELPER_FLAGS_5(sme_addha_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
40
+#include "qapi/qmp/qdict.h"
26
+DEF_HELPER_FLAGS_5(sme_addva_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
41
+#include "qapi/qmp/qnum.h"
27
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
42
+#include "qemu/bitops.h"
28
index XXXXXXX..XXXXXXX 100644
43
+#include "qemu/iov.h"
29
--- a/target/arm/sme.decode
30
+++ b/target/arm/sme.decode
31
@@ -XXX,XX +XXX,XX @@ LDST1 1110000 111 st:1 rm:5 v:1 .. pg:3 rn:5 0 za_imm:4 \
32
33
LDR 1110000 100 0 000000 .. 000 ..... 0 .... @ldstr
34
STR 1110000 100 1 000000 .. 000 ..... 0 .... @ldstr
44
+
35
+
45
+/* Name of the emc device. */
36
+### SME Add Vector to Array
46
+#define TYPE_NPCM7XX_EMC "npcm7xx-emc"
47
+
37
+
48
+/* Timeout for various operations, in seconds. */
38
+&adda zad zn pm pn
49
+#define TIMEOUT_SECONDS 10
39
+@adda_32 ........ .. ..... . pm:3 pn:3 zn:5 ... zad:2 &adda
40
+@adda_64 ........ .. ..... . pm:3 pn:3 zn:5 .. zad:3 &adda
50
+
41
+
51
+/* Address in memory of the descriptor. */
42
+ADDHA_s 11000000 10 01000 0 ... ... ..... 000 .. @adda_32
52
+#define DESC_ADDR (1 << 20) /* 1 MiB */
43
+ADDVA_s 11000000 10 01000 1 ... ... ..... 000 .. @adda_32
44
+ADDHA_d 11000000 11 01000 0 ... ... ..... 00 ... @adda_64
45
+ADDVA_d 11000000 11 01000 1 ... ... ..... 00 ... @adda_64
46
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/sme_helper.c
49
+++ b/target/arm/sme_helper.c
50
@@ -XXX,XX +XXX,XX @@ DO_ST(q, _be, MO_128)
51
DO_ST(q, _le, MO_128)
52
53
#undef DO_ST
53
+
54
+
54
+/* Address in memory of the data packet. */
55
+void HELPER(sme_addha_s)(void *vzda, void *vzn, void *vpn,
55
+#define DATA_ADDR (DESC_ADDR + 4096)
56
+ void *vpm, uint32_t desc)
57
+{
58
+ intptr_t row, col, oprsz = simd_oprsz(desc) / 4;
59
+ uint64_t *pn = vpn, *pm = vpm;
60
+ uint32_t *zda = vzda, *zn = vzn;
56
+
61
+
57
+#define CRC_LENGTH 4
62
+ for (row = 0; row < oprsz; ) {
58
+
63
+ uint64_t pa = pn[row >> 4];
59
+#define NUM_TX_DESCRIPTORS 3
60
+#define NUM_RX_DESCRIPTORS 2
61
+
62
+/* Size of tx,rx test buffers. */
63
+#define TX_DATA_LEN 64
64
+#define RX_DATA_LEN 64
65
+
66
+#define TX_STEP_COUNT 10000
67
+#define RX_STEP_COUNT 10000
68
+
69
+/* 32-bit register indices. */
70
+typedef enum NPCM7xxPWMRegister {
71
+ /* Control registers. */
72
+ REG_CAMCMR,
73
+ REG_CAMEN,
74
+
75
+ /* There are 16 CAMn[ML] registers. */
76
+ REG_CAMM_BASE,
77
+ REG_CAML_BASE,
78
+
79
+ REG_TXDLSA = 0x22,
80
+ REG_RXDLSA,
81
+ REG_MCMDR,
82
+ REG_MIID,
83
+ REG_MIIDA,
84
+ REG_FFTCR,
85
+ REG_TSDR,
86
+ REG_RSDR,
87
+ REG_DMARFC,
88
+ REG_MIEN,
89
+
90
+ /* Status registers. */
91
+ REG_MISTA,
92
+ REG_MGSTA,
93
+ REG_MPCNT,
94
+ REG_MRPC,
95
+ REG_MRPCC,
96
+ REG_MREPC,
97
+ REG_DMARFS,
98
+ REG_CTXDSA,
99
+ REG_CTXBSA,
100
+ REG_CRXDSA,
101
+ REG_CRXBSA,
102
+
103
+ NPCM7XX_NUM_EMC_REGS,
104
+} NPCM7xxPWMRegister;
105
+
106
+enum { NUM_CAMML_REGS = 16 };
107
+
108
+/* REG_CAMCMR fields */
109
+/* Enable CAM Compare */
110
+#define REG_CAMCMR_ECMP (1 << 4)
111
+/* Accept Unicast Packet */
112
+#define REG_CAMCMR_AUP (1 << 0)
113
+
114
+/* REG_MCMDR fields */
115
+/* Software Reset */
116
+#define REG_MCMDR_SWR (1 << 24)
117
+/* Frame Transmission On */
118
+#define REG_MCMDR_TXON (1 << 8)
119
+/* Accept Long Packet */
120
+#define REG_MCMDR_ALP (1 << 1)
121
+/* Frame Reception On */
122
+#define REG_MCMDR_RXON (1 << 0)
123
+
124
+/* REG_MIEN fields */
125
+/* Enable Transmit Completion Interrupt */
126
+#define REG_MIEN_ENTXCP (1 << 18)
127
+/* Enable Transmit Interrupt */
128
+#define REG_MIEN_ENTXINTR (1 << 16)
129
+/* Enable Receive Good Interrupt */
130
+#define REG_MIEN_ENRXGD (1 << 4)
131
+/* ENable Receive Interrupt */
132
+#define REG_MIEN_ENRXINTR (1 << 0)
133
+
134
+/* REG_MISTA fields */
135
+/* Transmit Bus Error Interrupt */
136
+#define REG_MISTA_TXBERR (1 << 24)
137
+/* Transmit Descriptor Unavailable Interrupt */
138
+#define REG_MISTA_TDU (1 << 23)
139
+/* Transmit Completion Interrupt */
140
+#define REG_MISTA_TXCP (1 << 18)
141
+/* Transmit Interrupt */
142
+#define REG_MISTA_TXINTR (1 << 16)
143
+/* Receive Bus Error Interrupt */
144
+#define REG_MISTA_RXBERR (1 << 11)
145
+/* Receive Descriptor Unavailable Interrupt */
146
+#define REG_MISTA_RDU (1 << 10)
147
+/* DMA Early Notification Interrupt */
148
+#define REG_MISTA_DENI (1 << 9)
149
+/* Maximum Frame Length Interrupt */
150
+#define REG_MISTA_DFOI (1 << 8)
151
+/* Receive Good Interrupt */
152
+#define REG_MISTA_RXGD (1 << 4)
153
+/* Packet Too Long Interrupt */
154
+#define REG_MISTA_PTLE (1 << 3)
155
+/* Receive Interrupt */
156
+#define REG_MISTA_RXINTR (1 << 0)
157
+
158
+typedef struct NPCM7xxEMCTxDesc NPCM7xxEMCTxDesc;
159
+typedef struct NPCM7xxEMCRxDesc NPCM7xxEMCRxDesc;
160
+
161
+struct NPCM7xxEMCTxDesc {
162
+ uint32_t flags;
163
+ uint32_t txbsa;
164
+ uint32_t status_and_length;
165
+ uint32_t ntxdsa;
166
+};
167
+
168
+struct NPCM7xxEMCRxDesc {
169
+ uint32_t status_and_length;
170
+ uint32_t rxbsa;
171
+ uint32_t reserved;
172
+ uint32_t nrxdsa;
173
+};
174
+
175
+/* NPCM7xxEMCTxDesc.flags values */
176
+/* Owner: 0 = cpu, 1 = emc */
177
+#define TX_DESC_FLAG_OWNER_MASK (1 << 31)
178
+/* Transmit interrupt enable */
179
+#define TX_DESC_FLAG_INTEN (1 << 2)
180
+
181
+/* NPCM7xxEMCTxDesc.status_and_length values */
182
+/* Transmission complete */
183
+#define TX_DESC_STATUS_TXCP (1 << 19)
184
+/* Transmit interrupt */
185
+#define TX_DESC_STATUS_TXINTR (1 << 16)
186
+
187
+/* NPCM7xxEMCRxDesc.status_and_length values */
188
+/* Owner: 0b00 = cpu, 0b10 = emc */
189
+#define RX_DESC_STATUS_OWNER_SHIFT 30
190
+#define RX_DESC_STATUS_OWNER_MASK 0xc0000000
191
+/* Frame Reception Complete */
192
+#define RX_DESC_STATUS_RXGD (1 << 20)
193
+/* Packet too long */
194
+#define RX_DESC_STATUS_PTLE (1 << 19)
195
+/* Receive Interrupt */
196
+#define RX_DESC_STATUS_RXINTR (1 << 16)
197
+
198
+#define RX_DESC_PKT_LEN(word) ((uint32_t) (word) & 0xffff)
199
+
200
+typedef struct EMCModule {
201
+ int rx_irq;
202
+ int tx_irq;
203
+ uint64_t base_addr;
204
+} EMCModule;
205
+
206
+typedef struct TestData {
207
+ const EMCModule *module;
208
+} TestData;
209
+
210
+static const EMCModule emc_module_list[] = {
211
+ {
212
+ .rx_irq = 15,
213
+ .tx_irq = 16,
214
+ .base_addr = 0xf0825000
215
+ },
216
+ {
217
+ .rx_irq = 114,
218
+ .tx_irq = 115,
219
+ .base_addr = 0xf0826000
220
+ }
221
+};
222
+
223
+/* Returns the index of the EMC module. */
224
+static int emc_module_index(const EMCModule *mod)
225
+{
226
+ ptrdiff_t diff = mod - emc_module_list;
227
+
228
+ g_assert_true(diff >= 0 && diff < ARRAY_SIZE(emc_module_list));
229
+
230
+ return diff;
231
+}
232
+
233
+static void packet_test_clear(void *sockets)
234
+{
235
+ int *test_sockets = sockets;
236
+
237
+ close(test_sockets[0]);
238
+ g_free(test_sockets);
239
+}
240
+
241
+static int *packet_test_init(int module_num, GString *cmd_line)
242
+{
243
+ int *test_sockets = g_new(int, 2);
244
+ int ret = socketpair(PF_UNIX, SOCK_STREAM, 0, test_sockets);
245
+ g_assert_cmpint(ret, != , -1);
246
+
247
+ /*
248
+ * KISS and use -nic. We specify two nics (both emc{0,1}) because there's
249
+ * currently no way to specify only emc1: The driver implicitly relies on
250
+ * emc[i] == nd_table[i].
251
+ */
252
+ if (module_num == 0) {
253
+ g_string_append_printf(cmd_line,
254
+ " -nic socket,fd=%d,model=" TYPE_NPCM7XX_EMC " "
255
+ " -nic user,model=" TYPE_NPCM7XX_EMC " ",
256
+ test_sockets[1]);
257
+ } else {
258
+ g_string_append_printf(cmd_line,
259
+ " -nic user,model=" TYPE_NPCM7XX_EMC " "
260
+ " -nic socket,fd=%d,model=" TYPE_NPCM7XX_EMC " ",
261
+ test_sockets[1]);
262
+ }
263
+
264
+ g_test_queue_destroy(packet_test_clear, test_sockets);
265
+ return test_sockets;
266
+}
267
+
268
+static uint32_t emc_read(QTestState *qts, const EMCModule *mod,
269
+ NPCM7xxPWMRegister regno)
270
+{
271
+ return qtest_readl(qts, mod->base_addr + regno * sizeof(uint32_t));
272
+}
273
+
274
+static void emc_write(QTestState *qts, const EMCModule *mod,
275
+ NPCM7xxPWMRegister regno, uint32_t value)
276
+{
277
+ qtest_writel(qts, mod->base_addr + regno * sizeof(uint32_t), value);
278
+}
279
+
280
+static void emc_read_tx_desc(QTestState *qts, uint32_t addr,
281
+ NPCM7xxEMCTxDesc *desc)
282
+{
283
+ qtest_memread(qts, addr, desc, sizeof(*desc));
284
+ desc->flags = le32_to_cpu(desc->flags);
285
+ desc->txbsa = le32_to_cpu(desc->txbsa);
286
+ desc->status_and_length = le32_to_cpu(desc->status_and_length);
287
+ desc->ntxdsa = le32_to_cpu(desc->ntxdsa);
288
+}
289
+
290
+static void emc_write_tx_desc(QTestState *qts, const NPCM7xxEMCTxDesc *desc,
291
+ uint32_t addr)
292
+{
293
+ NPCM7xxEMCTxDesc le_desc;
294
+
295
+ le_desc.flags = cpu_to_le32(desc->flags);
296
+ le_desc.txbsa = cpu_to_le32(desc->txbsa);
297
+ le_desc.status_and_length = cpu_to_le32(desc->status_and_length);
298
+ le_desc.ntxdsa = cpu_to_le32(desc->ntxdsa);
299
+ qtest_memwrite(qts, addr, &le_desc, sizeof(le_desc));
300
+}
301
+
302
+static void emc_read_rx_desc(QTestState *qts, uint32_t addr,
303
+ NPCM7xxEMCRxDesc *desc)
304
+{
305
+ qtest_memread(qts, addr, desc, sizeof(*desc));
306
+ desc->status_and_length = le32_to_cpu(desc->status_and_length);
307
+ desc->rxbsa = le32_to_cpu(desc->rxbsa);
308
+ desc->reserved = le32_to_cpu(desc->reserved);
309
+ desc->nrxdsa = le32_to_cpu(desc->nrxdsa);
310
+}
311
+
312
+static void emc_write_rx_desc(QTestState *qts, const NPCM7xxEMCRxDesc *desc,
313
+ uint32_t addr)
314
+{
315
+ NPCM7xxEMCRxDesc le_desc;
316
+
317
+ le_desc.status_and_length = cpu_to_le32(desc->status_and_length);
318
+ le_desc.rxbsa = cpu_to_le32(desc->rxbsa);
319
+ le_desc.reserved = cpu_to_le32(desc->reserved);
320
+ le_desc.nrxdsa = cpu_to_le32(desc->nrxdsa);
321
+ qtest_memwrite(qts, addr, &le_desc, sizeof(le_desc));
322
+}
323
+
324
+/*
325
+ * Reset the EMC module.
326
+ * The module must be reset before, e.g., TXDLSA,RXDLSA are changed.
327
+ */
328
+static bool emc_soft_reset(QTestState *qts, const EMCModule *mod)
329
+{
330
+ uint32_t val;
331
+ uint64_t end_time;
332
+
333
+ emc_write(qts, mod, REG_MCMDR, REG_MCMDR_SWR);
334
+
335
+ /*
336
+ * Wait for device to reset as the linux driver does.
337
+ * During reset the AHB reads 0 for all registers. So first wait for
338
+ * something that resets to non-zero, and then wait for SWR becoming 0.
339
+ */
340
+ end_time = g_get_monotonic_time() + TIMEOUT_SECONDS * G_TIME_SPAN_SECOND;
341
+
342
+ do {
343
+ qtest_clock_step(qts, 100);
344
+ val = emc_read(qts, mod, REG_FFTCR);
345
+ } while (val == 0 && g_get_monotonic_time() < end_time);
346
+ if (val != 0) {
347
+ do {
64
+ do {
348
+ qtest_clock_step(qts, 100);
65
+ if (pa & 1) {
349
+ val = emc_read(qts, mod, REG_MCMDR);
66
+ for (col = 0; col < oprsz; ) {
350
+ if ((val & REG_MCMDR_SWR) == 0) {
67
+ uint64_t pb = pm[col >> 4];
351
+ /*
68
+ do {
352
+ * N.B. The CAMs have been reset here, so macaddr matching of
69
+ if (pb & 1) {
353
+ * incoming packets will not work.
70
+ zda[tile_vslice_index(row) + H4(col)] += zn[H4(col)];
354
+ */
71
+ }
355
+ return true;
72
+ pb >>= 4;
73
+ } while (++col & 15);
74
+ }
356
+ }
75
+ }
357
+ } while (g_get_monotonic_time() < end_time);
76
+ pa >>= 4;
358
+ }
77
+ } while (++row & 15);
359
+
360
+ g_message("%s: Timeout expired", __func__);
361
+ return false;
362
+}
363
+
364
+/* Check emc registers are reset to default value. */
365
+static void test_init(gconstpointer test_data)
366
+{
367
+ const TestData *td = test_data;
368
+ const EMCModule *mod = td->module;
369
+ QTestState *qts = qtest_init("-machine quanta-gsj");
370
+ int i;
371
+
372
+#define CHECK_REG(regno, value) \
373
+ do { \
374
+ g_assert_cmphex(emc_read(qts, mod, (regno)), ==, (value)); \
375
+ } while (0)
376
+
377
+ CHECK_REG(REG_CAMCMR, 0);
378
+ CHECK_REG(REG_CAMEN, 0);
379
+ CHECK_REG(REG_TXDLSA, 0xfffffffc);
380
+ CHECK_REG(REG_RXDLSA, 0xfffffffc);
381
+ CHECK_REG(REG_MCMDR, 0);
382
+ CHECK_REG(REG_MIID, 0);
383
+ CHECK_REG(REG_MIIDA, 0x00900000);
384
+ CHECK_REG(REG_FFTCR, 0x0101);
385
+ CHECK_REG(REG_DMARFC, 0x0800);
386
+ CHECK_REG(REG_MIEN, 0);
387
+ CHECK_REG(REG_MISTA, 0);
388
+ CHECK_REG(REG_MGSTA, 0);
389
+ CHECK_REG(REG_MPCNT, 0x7fff);
390
+ CHECK_REG(REG_MRPC, 0);
391
+ CHECK_REG(REG_MRPCC, 0);
392
+ CHECK_REG(REG_MREPC, 0);
393
+ CHECK_REG(REG_DMARFS, 0);
394
+ CHECK_REG(REG_CTXDSA, 0);
395
+ CHECK_REG(REG_CTXBSA, 0);
396
+ CHECK_REG(REG_CRXDSA, 0);
397
+ CHECK_REG(REG_CRXBSA, 0);
398
+
399
+#undef CHECK_REG
400
+
401
+ for (i = 0; i < NUM_CAMML_REGS; ++i) {
402
+ g_assert_cmpuint(emc_read(qts, mod, REG_CAMM_BASE + i * 2), ==,
403
+ 0);
404
+ g_assert_cmpuint(emc_read(qts, mod, REG_CAML_BASE + i * 2), ==,
405
+ 0);
406
+ }
407
+
408
+ qtest_quit(qts);
409
+}
410
+
411
+static bool emc_wait_irq(QTestState *qts, const EMCModule *mod, int step,
412
+ bool is_tx)
413
+{
414
+ uint64_t end_time =
415
+ g_get_monotonic_time() + TIMEOUT_SECONDS * G_TIME_SPAN_SECOND;
416
+
417
+ do {
418
+ if (qtest_get_irq(qts, is_tx ? mod->tx_irq : mod->rx_irq)) {
419
+ return true;
420
+ }
421
+ qtest_clock_step(qts, step);
422
+ } while (g_get_monotonic_time() < end_time);
423
+
424
+ g_message("%s: Timeout expired", __func__);
425
+ return false;
426
+}
427
+
428
+static bool emc_wait_mista(QTestState *qts, const EMCModule *mod, int step,
429
+ uint32_t flag)
430
+{
431
+ uint64_t end_time =
432
+ g_get_monotonic_time() + TIMEOUT_SECONDS * G_TIME_SPAN_SECOND;
433
+
434
+ do {
435
+ uint32_t mista = emc_read(qts, mod, REG_MISTA);
436
+ if (mista & flag) {
437
+ return true;
438
+ }
439
+ qtest_clock_step(qts, step);
440
+ } while (g_get_monotonic_time() < end_time);
441
+
442
+ g_message("%s: Timeout expired", __func__);
443
+ return false;
444
+}
445
+
446
+static bool wait_socket_readable(int fd)
447
+{
448
+ fd_set read_fds;
449
+ struct timeval tv;
450
+ int rv;
451
+
452
+ FD_ZERO(&read_fds);
453
+ FD_SET(fd, &read_fds);
454
+ tv.tv_sec = TIMEOUT_SECONDS;
455
+ tv.tv_usec = 0;
456
+ rv = select(fd + 1, &read_fds, NULL, NULL, &tv);
457
+ if (rv == -1) {
458
+ perror("select");
459
+ } else if (rv == 0) {
460
+ g_message("%s: Timeout expired", __func__);
461
+ }
462
+ return rv == 1;
463
+}
464
+
465
+/* Initialize *desc (in host endian format). */
466
+static void init_tx_desc(NPCM7xxEMCTxDesc *desc, size_t count,
467
+ uint32_t desc_addr)
468
+{
469
+ g_assert(count >= 2);
470
+ memset(&desc[0], 0, sizeof(*desc) * count);
471
+ /* Leave the last one alone, owned by the cpu -> stops transmission. */
472
+ for (size_t i = 0; i < count - 1; ++i) {
473
+ desc[i].flags =
474
+ (TX_DESC_FLAG_OWNER_MASK | /* owner = 1: emc */
475
+ TX_DESC_FLAG_INTEN |
476
+ 0 | /* crc append = 0 */
477
+ 0 /* padding enable = 0 */);
478
+ desc[i].status_and_length =
479
+ (0 | /* collision count = 0 */
480
+ 0 | /* SQE = 0 */
481
+ 0 | /* PAU = 0 */
482
+ 0 | /* TXHA = 0 */
483
+ 0 | /* LC = 0 */
484
+ 0 | /* TXABT = 0 */
485
+ 0 | /* NCS = 0 */
486
+ 0 | /* EXDEF = 0 */
487
+ 0 | /* TXCP = 0 */
488
+ 0 | /* DEF = 0 */
489
+ 0 | /* TXINTR = 0 */
490
+ 0 /* length filled in later */);
491
+ desc[i].ntxdsa = desc_addr + (i + 1) * sizeof(*desc);
492
+ }
78
+ }
493
+}
79
+}
494
+
80
+
495
+static void enable_tx(QTestState *qts, const EMCModule *mod,
81
+void HELPER(sme_addha_d)(void *vzda, void *vzn, void *vpn,
496
+ const NPCM7xxEMCTxDesc *desc, size_t count,
82
+ void *vpm, uint32_t desc)
497
+ uint32_t desc_addr, uint32_t mien_flags)
498
+{
83
+{
499
+ /* Write the descriptors to guest memory. */
84
+ intptr_t row, col, oprsz = simd_oprsz(desc) / 8;
500
+ for (size_t i = 0; i < count; ++i) {
85
+ uint8_t *pn = vpn, *pm = vpm;
501
+ emc_write_tx_desc(qts, desc + i, desc_addr + i * sizeof(*desc));
86
+ uint64_t *zda = vzda, *zn = vzn;
502
+ }
503
+
87
+
504
+ /* Trigger sending the packet. */
88
+ for (row = 0; row < oprsz; ++row) {
505
+ /* The module must be reset before changing TXDLSA. */
89
+ if (pn[H1(row)] & 1) {
506
+ g_assert(emc_soft_reset(qts, mod));
90
+ for (col = 0; col < oprsz; ++col) {
507
+ emc_write(qts, mod, REG_TXDLSA, desc_addr);
91
+ if (pm[H1(col)] & 1) {
508
+ emc_write(qts, mod, REG_CTXDSA, ~0);
92
+ zda[tile_vslice_index(row) + col] += zn[col];
509
+ emc_write(qts, mod, REG_MIEN, REG_MIEN_ENTXCP | mien_flags);
93
+ }
510
+ {
94
+ }
511
+ uint32_t mcmdr = emc_read(qts, mod, REG_MCMDR);
512
+ mcmdr |= REG_MCMDR_TXON;
513
+ emc_write(qts, mod, REG_MCMDR, mcmdr);
514
+ }
515
+
516
+ /* Prod the device to send the packet. */
517
+ emc_write(qts, mod, REG_TSDR, 1);
518
+}
519
+
520
+static void emc_send_verify1(QTestState *qts, const EMCModule *mod, int fd,
521
+ bool with_irq, uint32_t desc_addr,
522
+ uint32_t next_desc_addr,
523
+ const char *test_data, int test_size)
524
+{
525
+ NPCM7xxEMCTxDesc result_desc;
526
+ uint32_t expected_mask, expected_value, recv_len;
527
+ int ret;
528
+ char buffer[TX_DATA_LEN];
529
+
530
+ g_assert(wait_socket_readable(fd));
531
+
532
+ /* Read the descriptor back. */
533
+ emc_read_tx_desc(qts, desc_addr, &result_desc);
534
+ /* Descriptor should be owned by cpu now. */
535
+ g_assert((result_desc.flags & TX_DESC_FLAG_OWNER_MASK) == 0);
536
+ /* Test the status bits, ignoring the length field. */
537
+ expected_mask = 0xffff << 16;
538
+ expected_value = TX_DESC_STATUS_TXCP;
539
+ if (with_irq) {
540
+ expected_value |= TX_DESC_STATUS_TXINTR;
541
+ }
542
+ g_assert_cmphex((result_desc.status_and_length & expected_mask), ==,
543
+ expected_value);
544
+
545
+ /* Check data sent to the backend. */
546
+ recv_len = ~0;
547
+ ret = qemu_recv(fd, &recv_len, sizeof(recv_len), MSG_DONTWAIT);
548
+ g_assert_cmpint(ret, == , sizeof(recv_len));
549
+
550
+ g_assert(wait_socket_readable(fd));
551
+ memset(buffer, 0xff, sizeof(buffer));
552
+ ret = qemu_recv(fd, buffer, test_size, MSG_DONTWAIT);
553
+ g_assert_cmpmem(buffer, ret, test_data, test_size);
554
+}
555
+
556
+static void emc_send_verify(QTestState *qts, const EMCModule *mod, int fd,
557
+ bool with_irq)
558
+{
559
+ NPCM7xxEMCTxDesc desc[NUM_TX_DESCRIPTORS];
560
+ uint32_t desc_addr = DESC_ADDR;
561
+ static const char test1_data[] = "TEST1";
562
+ static const char test2_data[] = "Testing 1 2 3 ...";
563
+ uint32_t data1_addr = DATA_ADDR;
564
+ uint32_t data2_addr = data1_addr + sizeof(test1_data);
565
+ bool got_tdu;
566
+ uint32_t end_desc_addr;
567
+
568
+ /* Prepare test data buffer. */
569
+ qtest_memwrite(qts, data1_addr, test1_data, sizeof(test1_data));
570
+ qtest_memwrite(qts, data2_addr, test2_data, sizeof(test2_data));
571
+
572
+ init_tx_desc(&desc[0], NUM_TX_DESCRIPTORS, desc_addr);
573
+ desc[0].txbsa = data1_addr;
574
+ desc[0].status_and_length |= sizeof(test1_data);
575
+ desc[1].txbsa = data2_addr;
576
+ desc[1].status_and_length |= sizeof(test2_data);
577
+
578
+ enable_tx(qts, mod, &desc[0], NUM_TX_DESCRIPTORS, desc_addr,
579
+ with_irq ? REG_MIEN_ENTXINTR : 0);
580
+
581
+ /*
582
+ * It's problematic to observe the interrupt for each packet.
583
+ * Instead just wait until all the packets go out.
584
+ */
585
+ got_tdu = false;
586
+ while (!got_tdu) {
587
+ if (with_irq) {
588
+ g_assert_true(emc_wait_irq(qts, mod, TX_STEP_COUNT,
589
+ /*is_tx=*/true));
590
+ } else {
591
+ g_assert_true(emc_wait_mista(qts, mod, TX_STEP_COUNT,
592
+ REG_MISTA_TXINTR));
593
+ }
95
+ }
594
+ got_tdu = !!(emc_read(qts, mod, REG_MISTA) & REG_MISTA_TDU);
595
+ /* If we don't have TDU yet, reset the interrupt. */
596
+ if (!got_tdu) {
597
+ emc_write(qts, mod, REG_MISTA,
598
+ emc_read(qts, mod, REG_MISTA) & 0xffff0000);
599
+ }
600
+ }
601
+
602
+ end_desc_addr = desc_addr + 2 * sizeof(desc[0]);
603
+ g_assert_cmphex(emc_read(qts, mod, REG_CTXDSA), ==, end_desc_addr);
604
+ g_assert_cmphex(emc_read(qts, mod, REG_MISTA), ==,
605
+ REG_MISTA_TXCP | REG_MISTA_TXINTR | REG_MISTA_TDU);
606
+
607
+ emc_send_verify1(qts, mod, fd, with_irq,
608
+ desc_addr, end_desc_addr,
609
+ test1_data, sizeof(test1_data));
610
+ emc_send_verify1(qts, mod, fd, with_irq,
611
+ desc_addr + sizeof(desc[0]), end_desc_addr,
612
+ test2_data, sizeof(test2_data));
613
+}
614
+
615
+/* Initialize *desc (in host endian format). */
616
+static void init_rx_desc(NPCM7xxEMCRxDesc *desc, size_t count,
617
+ uint32_t desc_addr, uint32_t data_addr)
618
+{
619
+ g_assert_true(count >= 2);
620
+ memset(desc, 0, sizeof(*desc) * count);
621
+ desc[0].rxbsa = data_addr;
622
+ desc[0].status_and_length =
623
+ (0b10 << RX_DESC_STATUS_OWNER_SHIFT | /* owner = 10: emc */
624
+ 0 | /* RP = 0 */
625
+ 0 | /* ALIE = 0 */
626
+ 0 | /* RXGD = 0 */
627
+ 0 | /* PTLE = 0 */
628
+ 0 | /* CRCE = 0 */
629
+ 0 | /* RXINTR = 0 */
630
+ 0 /* length (filled in later) */);
631
+ /* Leave the last one alone, owned by the cpu -> stops transmission. */
632
+ desc[0].nrxdsa = desc_addr + sizeof(*desc);
633
+}
634
+
635
+static void enable_rx(QTestState *qts, const EMCModule *mod,
636
+ const NPCM7xxEMCRxDesc *desc, size_t count,
637
+ uint32_t desc_addr, uint32_t mien_flags,
638
+ uint32_t mcmdr_flags)
639
+{
640
+ /*
641
+ * Write the descriptor to guest memory.
642
+ * FWIW, IWBN if the docs said the buffer needs to be at least DMARFC
643
+ * bytes.
644
+ */
645
+ for (size_t i = 0; i < count; ++i) {
646
+ emc_write_rx_desc(qts, desc + i, desc_addr + i * sizeof(*desc));
647
+ }
648
+
649
+ /* Trigger receiving the packet. */
650
+ /* The module must be reset before changing RXDLSA. */
651
+ g_assert(emc_soft_reset(qts, mod));
652
+ emc_write(qts, mod, REG_RXDLSA, desc_addr);
653
+ emc_write(qts, mod, REG_MIEN, REG_MIEN_ENRXGD | mien_flags);
654
+
655
+ /*
656
+ * We don't know what the device's macaddr is, so just accept all
657
+ * unicast packets (AUP).
658
+ */
659
+ emc_write(qts, mod, REG_CAMCMR, REG_CAMCMR_AUP);
660
+ emc_write(qts, mod, REG_CAMEN, 1 << 0);
661
+ {
662
+ uint32_t mcmdr = emc_read(qts, mod, REG_MCMDR);
663
+ mcmdr |= REG_MCMDR_RXON | mcmdr_flags;
664
+ emc_write(qts, mod, REG_MCMDR, mcmdr);
665
+ }
666
+
667
+ /* Prod the device to accept a packet. */
668
+ emc_write(qts, mod, REG_RSDR, 1);
669
+}
670
+
671
+static void emc_recv_verify(QTestState *qts, const EMCModule *mod, int fd,
672
+ bool with_irq)
673
+{
674
+ NPCM7xxEMCRxDesc desc[NUM_RX_DESCRIPTORS];
675
+ uint32_t desc_addr = DESC_ADDR;
676
+ uint32_t data_addr = DATA_ADDR;
677
+ int ret;
678
+ uint32_t expected_mask, expected_value;
679
+ NPCM7xxEMCRxDesc result_desc;
680
+
681
+ /* Prepare test data buffer. */
682
+ const char test[RX_DATA_LEN] = "TEST";
683
+ int len = htonl(sizeof(test));
684
+ const struct iovec iov[] = {
685
+ {
686
+ .iov_base = &len,
687
+ .iov_len = sizeof(len),
688
+ },{
689
+ .iov_base = (char *) test,
690
+ .iov_len = sizeof(test),
691
+ },
692
+ };
693
+
694
+ /*
695
+ * Reset the device BEFORE sending a test packet, otherwise the packet
696
+ * may get swallowed by an active device of an earlier test.
697
+ */
698
+ init_rx_desc(&desc[0], NUM_RX_DESCRIPTORS, desc_addr, data_addr);
699
+ enable_rx(qts, mod, &desc[0], NUM_RX_DESCRIPTORS, desc_addr,
700
+ with_irq ? REG_MIEN_ENRXINTR : 0, 0);
701
+
702
+ /* Send test packet to device's socket. */
703
+ ret = iov_send(fd, iov, 2, 0, sizeof(len) + sizeof(test));
704
+ g_assert_cmpint(ret, == , sizeof(test) + sizeof(len));
705
+
706
+ /* Wait for RX interrupt. */
707
+ if (with_irq) {
708
+ g_assert_true(emc_wait_irq(qts, mod, RX_STEP_COUNT, /*is_tx=*/false));
709
+ } else {
710
+ g_assert_true(emc_wait_mista(qts, mod, RX_STEP_COUNT, REG_MISTA_RXGD));
711
+ }
712
+
713
+ g_assert_cmphex(emc_read(qts, mod, REG_CRXDSA), ==,
714
+ desc_addr + sizeof(desc[0]));
715
+
716
+ expected_mask = 0xffff;
717
+ expected_value = (REG_MISTA_DENI |
718
+ REG_MISTA_RXGD |
719
+ REG_MISTA_RXINTR);
720
+ g_assert_cmphex((emc_read(qts, mod, REG_MISTA) & expected_mask),
721
+ ==, expected_value);
722
+
723
+ /* Read the descriptor back. */
724
+ emc_read_rx_desc(qts, desc_addr, &result_desc);
725
+ /* Descriptor should be owned by cpu now. */
726
+ g_assert((result_desc.status_and_length & RX_DESC_STATUS_OWNER_MASK) == 0);
727
+ /* Test the status bits, ignoring the length field. */
728
+ expected_mask = 0xffff << 16;
729
+ expected_value = RX_DESC_STATUS_RXGD;
730
+ if (with_irq) {
731
+ expected_value |= RX_DESC_STATUS_RXINTR;
732
+ }
733
+ g_assert_cmphex((result_desc.status_and_length & expected_mask), ==,
734
+ expected_value);
735
+ g_assert_cmpint(RX_DESC_PKT_LEN(result_desc.status_and_length), ==,
736
+ RX_DATA_LEN + CRC_LENGTH);
737
+
738
+ {
739
+ char buffer[RX_DATA_LEN];
740
+ qtest_memread(qts, data_addr, buffer, sizeof(buffer));
741
+ g_assert_cmpstr(buffer, == , "TEST");
742
+ }
96
+ }
743
+}
97
+}
744
+
98
+
745
+static void emc_test_ptle(QTestState *qts, const EMCModule *mod, int fd)
99
+void HELPER(sme_addva_s)(void *vzda, void *vzn, void *vpn,
100
+ void *vpm, uint32_t desc)
746
+{
101
+{
747
+ NPCM7xxEMCRxDesc desc[NUM_RX_DESCRIPTORS];
102
+ intptr_t row, col, oprsz = simd_oprsz(desc) / 4;
748
+ uint32_t desc_addr = DESC_ADDR;
103
+ uint64_t *pn = vpn, *pm = vpm;
749
+ uint32_t data_addr = DATA_ADDR;
104
+ uint32_t *zda = vzda, *zn = vzn;
750
+ int ret;
751
+ NPCM7xxEMCRxDesc result_desc;
752
+ uint32_t expected_mask, expected_value;
753
+
105
+
754
+ /* Prepare test data buffer. */
106
+ for (row = 0; row < oprsz; ) {
755
+#define PTLE_DATA_LEN 1600
107
+ uint64_t pa = pn[row >> 4];
756
+ char test_data[PTLE_DATA_LEN];
108
+ do {
757
+ int len = htonl(sizeof(test_data));
109
+ if (pa & 1) {
758
+ const struct iovec iov[] = {
110
+ uint32_t zn_row = zn[H4(row)];
759
+ {
111
+ for (col = 0; col < oprsz; ) {
760
+ .iov_base = &len,
112
+ uint64_t pb = pm[col >> 4];
761
+ .iov_len = sizeof(len),
113
+ do {
762
+ },{
114
+ if (pb & 1) {
763
+ .iov_base = (char *) test_data,
115
+ zda[tile_vslice_index(row) + H4(col)] += zn_row;
764
+ .iov_len = sizeof(test_data),
116
+ }
765
+ },
117
+ pb >>= 4;
766
+ };
118
+ } while (++col & 15);
767
+ memset(test_data, 42, sizeof(test_data));
119
+ }
768
+
120
+ }
769
+ /*
121
+ pa >>= 4;
770
+ * Reset the device BEFORE sending a test packet, otherwise the packet
122
+ } while (++row & 15);
771
+ * may get swallowed by an active device of an earlier test.
772
+ */
773
+ init_rx_desc(&desc[0], NUM_RX_DESCRIPTORS, desc_addr, data_addr);
774
+ enable_rx(qts, mod, &desc[0], NUM_RX_DESCRIPTORS, desc_addr,
775
+ REG_MIEN_ENRXINTR, REG_MCMDR_ALP);
776
+
777
+ /* Send test packet to device's socket. */
778
+ ret = iov_send(fd, iov, 2, 0, sizeof(len) + sizeof(test_data));
779
+ g_assert_cmpint(ret, == , sizeof(test_data) + sizeof(len));
780
+
781
+ /* Wait for RX interrupt. */
782
+ g_assert_true(emc_wait_irq(qts, mod, RX_STEP_COUNT, /*is_tx=*/false));
783
+
784
+ /* Read the descriptor back. */
785
+ emc_read_rx_desc(qts, desc_addr, &result_desc);
786
+ /* Descriptor should be owned by cpu now. */
787
+ g_assert((result_desc.status_and_length & RX_DESC_STATUS_OWNER_MASK) == 0);
788
+ /* Test the status bits, ignoring the length field. */
789
+ expected_mask = 0xffff << 16;
790
+ expected_value = (RX_DESC_STATUS_RXGD |
791
+ RX_DESC_STATUS_PTLE |
792
+ RX_DESC_STATUS_RXINTR);
793
+ g_assert_cmphex((result_desc.status_and_length & expected_mask), ==,
794
+ expected_value);
795
+ g_assert_cmpint(RX_DESC_PKT_LEN(result_desc.status_and_length), ==,
796
+ PTLE_DATA_LEN + CRC_LENGTH);
797
+
798
+ {
799
+ char buffer[PTLE_DATA_LEN];
800
+ qtest_memread(qts, data_addr, buffer, sizeof(buffer));
801
+ g_assert(memcmp(buffer, test_data, PTLE_DATA_LEN) == 0);
802
+ }
123
+ }
803
+}
124
+}
804
+
125
+
805
+static void test_tx(gconstpointer test_data)
126
+void HELPER(sme_addva_d)(void *vzda, void *vzn, void *vpn,
127
+ void *vpm, uint32_t desc)
806
+{
128
+{
807
+ const TestData *td = test_data;
129
+ intptr_t row, col, oprsz = simd_oprsz(desc) / 8;
808
+ GString *cmd_line = g_string_new("-machine quanta-gsj");
130
+ uint8_t *pn = vpn, *pm = vpm;
809
+ int *test_sockets = packet_test_init(emc_module_index(td->module),
131
+ uint64_t *zda = vzda, *zn = vzn;
810
+ cmd_line);
811
+ QTestState *qts = qtest_init(cmd_line->str);
812
+
132
+
813
+ /*
133
+ for (row = 0; row < oprsz; ++row) {
814
+ * TODO: For pedantic correctness test_sockets[0] should be closed after
134
+ if (pn[H1(row)] & 1) {
815
+ * the fork and before the exec, but that will require some harness
135
+ uint64_t zn_row = zn[row];
816
+ * improvements.
136
+ for (col = 0; col < oprsz; ++col) {
817
+ */
137
+ if (pm[H1(col)] & 1) {
818
+ close(test_sockets[1]);
138
+ zda[tile_vslice_index(row) + col] += zn_row;
819
+ /* Defensive programming */
139
+ }
820
+ test_sockets[1] = -1;
140
+ }
141
+ }
142
+ }
143
+}
144
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
145
index XXXXXXX..XXXXXXX 100644
146
--- a/target/arm/translate-sme.c
147
+++ b/target/arm/translate-sme.c
148
@@ -XXX,XX +XXX,XX @@ static bool do_ldst_r(DisasContext *s, arg_ldstr *a, GenLdStR *fn)
149
150
TRANS_FEAT(LDR, aa64_sme, do_ldst_r, a, gen_sve_ldr)
151
TRANS_FEAT(STR, aa64_sme, do_ldst_r, a, gen_sve_str)
821
+
152
+
822
+ qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
153
+static bool do_adda(DisasContext *s, arg_adda *a, MemOp esz,
154
+ gen_helper_gvec_4 *fn)
155
+{
156
+ int svl = streaming_vec_reg_size(s);
157
+ uint32_t desc = simd_desc(svl, svl, 0);
158
+ TCGv_ptr za, zn, pn, pm;
823
+
159
+
824
+ emc_send_verify(qts, td->module, test_sockets[0], /*with_irq=*/false);
160
+ if (!sme_smza_enabled_check(s)) {
825
+ emc_send_verify(qts, td->module, test_sockets[0], /*with_irq=*/true);
161
+ return true;
162
+ }
826
+
163
+
827
+ qtest_quit(qts);
164
+ /* Sum XZR+zad to find ZAd. */
165
+ za = get_tile_rowcol(s, esz, 31, a->zad, false);
166
+ zn = vec_full_reg_ptr(s, a->zn);
167
+ pn = pred_full_reg_ptr(s, a->pn);
168
+ pm = pred_full_reg_ptr(s, a->pm);
169
+
170
+ fn(za, zn, pn, pm, tcg_constant_i32(desc));
171
+
172
+ tcg_temp_free_ptr(za);
173
+ tcg_temp_free_ptr(zn);
174
+ tcg_temp_free_ptr(pn);
175
+ tcg_temp_free_ptr(pm);
176
+ return true;
828
+}
177
+}
829
+
178
+
830
+static void test_rx(gconstpointer test_data)
179
+TRANS_FEAT(ADDHA_s, aa64_sme, do_adda, a, MO_32, gen_helper_sme_addha_s)
831
+{
180
+TRANS_FEAT(ADDVA_s, aa64_sme, do_adda, a, MO_32, gen_helper_sme_addva_s)
832
+ const TestData *td = test_data;
181
+TRANS_FEAT(ADDHA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addha_d)
833
+ GString *cmd_line = g_string_new("-machine quanta-gsj");
182
+TRANS_FEAT(ADDVA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addva_d)
834
+ int *test_sockets = packet_test_init(emc_module_index(td->module),
835
+ cmd_line);
836
+ QTestState *qts = qtest_init(cmd_line->str);
837
+
838
+ /*
839
+ * TODO: For pedantic correctness test_sockets[0] should be closed after
840
+ * the fork and before the exec, but that will require some harness
841
+ * improvements.
842
+ */
843
+ close(test_sockets[1]);
844
+ /* Defensive programming */
845
+ test_sockets[1] = -1;
846
+
847
+ qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
848
+
849
+ emc_recv_verify(qts, td->module, test_sockets[0], /*with_irq=*/false);
850
+ emc_recv_verify(qts, td->module, test_sockets[0], /*with_irq=*/true);
851
+ emc_test_ptle(qts, td->module, test_sockets[0]);
852
+
853
+ qtest_quit(qts);
854
+}
855
+
856
+static void emc_add_test(const char *name, const TestData* td,
857
+ GTestDataFunc fn)
858
+{
859
+ g_autofree char *full_name = g_strdup_printf(
860
+ "npcm7xx_emc/emc[%d]/%s", emc_module_index(td->module), name);
861
+ qtest_add_data_func(full_name, td, fn);
862
+}
863
+#define add_test(name, td) emc_add_test(#name, td, test_##name)
864
+
865
+int main(int argc, char **argv)
866
+{
867
+ TestData test_data_list[ARRAY_SIZE(emc_module_list)];
868
+
869
+ g_test_init(&argc, &argv, NULL);
870
+
871
+ for (int i = 0; i < ARRAY_SIZE(emc_module_list); ++i) {
872
+ TestData *td = &test_data_list[i];
873
+
874
+ td->module = &emc_module_list[i];
875
+
876
+ add_test(init, td);
877
+ add_test(tx, td);
878
+ add_test(rx, td);
879
+ }
880
+
881
+ return g_test_run();
882
+}
883
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
884
index XXXXXXX..XXXXXXX 100644
885
--- a/tests/qtest/meson.build
886
+++ b/tests/qtest/meson.build
887
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
888
'npcm7xx_rng-test',
889
'npcm7xx_smbus-test',
890
'npcm7xx_timer-test',
891
- 'npcm7xx_watchdog_timer-test']
892
+ 'npcm7xx_watchdog_timer-test'] + \
893
+ (slirp.found() ? ['npcm7xx_emc-test'] : [])
894
qtests_arm = \
895
(config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
896
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
897
--
183
--
898
2.20.1
184
2.25.1
899
900
diff view generated by jsdifflib
1
The armv7m_load_kernel() function takes a mem_size argument which it
1
From: Richard Henderson <richard.henderson@linaro.org>
2
expects to be the size of the memory region at guest address 0. (It
3
uses this argument only as a limit on how large a raw image file it
4
can load at address zero).
5
2
6
Instead of hardcoding this value, find the RAMInfo corresponding to
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
the 0 address and extract its size.
4
Message-id: 20220708151540.18136-25-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sme.h | 5 +++
9
target/arm/sme.decode | 9 +++++
10
target/arm/sme_helper.c | 69 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-sme.c | 32 ++++++++++++++++++
12
4 files changed, 115 insertions(+)
8
13
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210215115138.20465-20-peter.maydell@linaro.org
13
---
14
hw/arm/mps2-tz.c | 17 ++++++++++++++++-
15
1 file changed, 16 insertions(+), 1 deletion(-)
16
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/mps2-tz.c
16
--- a/target/arm/helper-sme.h
20
+++ b/hw/arm/mps2-tz.c
17
+++ b/target/arm/helper-sme.h
21
@@ -XXX,XX +XXX,XX @@ static void create_non_mpc_ram(MPS2TZMachineState *mms)
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sme_addha_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
19
DEF_HELPER_FLAGS_5(sme_addva_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_5(sme_addha_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_5(sme_addva_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
22
+
23
+DEF_HELPER_FLAGS_7(sme_fmopa_s, TCG_CALL_NO_RWG,
24
+ void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_7(sme_fmopa_d, TCG_CALL_NO_RWG,
26
+ void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
27
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/sme.decode
30
+++ b/target/arm/sme.decode
31
@@ -XXX,XX +XXX,XX @@ ADDHA_s 11000000 10 01000 0 ... ... ..... 000 .. @adda_32
32
ADDVA_s 11000000 10 01000 1 ... ... ..... 000 .. @adda_32
33
ADDHA_d 11000000 11 01000 0 ... ... ..... 00 ... @adda_64
34
ADDVA_d 11000000 11 01000 1 ... ... ..... 00 ... @adda_64
35
+
36
+### SME Outer Product
37
+
38
+&op zad zn zm pm pn sub:bool
39
+@op_32 ........ ... zm:5 pm:3 pn:3 zn:5 sub:1 .. zad:2 &op
40
+@op_64 ........ ... zm:5 pm:3 pn:3 zn:5 sub:1 . zad:3 &op
41
+
42
+FMOPA_s 10000000 100 ..... ... ... ..... . 00 .. @op_32
43
+FMOPA_d 10000000 110 ..... ... ... ..... . 0 ... @op_64
44
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/sme_helper.c
47
+++ b/target/arm/sme_helper.c
48
@@ -XXX,XX +XXX,XX @@
49
#include "exec/cpu_ldst.h"
50
#include "exec/exec-all.h"
51
#include "qemu/int128.h"
52
+#include "fpu/softfloat.h"
53
#include "vec_internal.h"
54
#include "sve_ldst_internal.h"
55
56
@@ -XXX,XX +XXX,XX @@ void HELPER(sme_addva_d)(void *vzda, void *vzn, void *vpn,
57
}
22
}
58
}
23
}
59
}
24
60
+
25
+static uint32_t boot_ram_size(MPS2TZMachineState *mms)
61
+void HELPER(sme_fmopa_s)(void *vza, void *vzn, void *vzm, void *vpn,
62
+ void *vpm, void *vst, uint32_t desc)
26
+{
63
+{
27
+ /* Return the size of the RAM block at guest address zero */
64
+ intptr_t row, col, oprsz = simd_maxsz(desc);
28
+ const RAMInfo *p;
65
+ uint32_t neg = simd_data(desc) << 31;
29
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
66
+ uint16_t *pn = vpn, *pm = vpm;
67
+ float_status fpst;
30
+
68
+
31
+ for (p = mmc->raminfo; p->name; p++) {
69
+ /*
32
+ if (p->base == 0) {
70
+ * Make a copy of float_status because this operation does not
33
+ return p->size;
71
+ * update the cumulative fp exception status. It also produces
72
+ * default nans.
73
+ */
74
+ fpst = *(float_status *)vst;
75
+ set_default_nan_mode(true, &fpst);
76
+
77
+ for (row = 0; row < oprsz; ) {
78
+ uint16_t pa = pn[H2(row >> 4)];
79
+ do {
80
+ if (pa & 1) {
81
+ void *vza_row = vza + tile_vslice_offset(row);
82
+ uint32_t n = *(uint32_t *)(vzn + H1_4(row)) ^ neg;
83
+
84
+ for (col = 0; col < oprsz; ) {
85
+ uint16_t pb = pm[H2(col >> 4)];
86
+ do {
87
+ if (pb & 1) {
88
+ uint32_t *a = vza_row + H1_4(col);
89
+ uint32_t *m = vzm + H1_4(col);
90
+ *a = float32_muladd(n, *m, *a, 0, vst);
91
+ }
92
+ col += 4;
93
+ pb >>= 4;
94
+ } while (col & 15);
95
+ }
96
+ }
97
+ row += 4;
98
+ pa >>= 4;
99
+ } while (row & 15);
100
+ }
101
+}
102
+
103
+void HELPER(sme_fmopa_d)(void *vza, void *vzn, void *vzm, void *vpn,
104
+ void *vpm, void *vst, uint32_t desc)
105
+{
106
+ intptr_t row, col, oprsz = simd_oprsz(desc) / 8;
107
+ uint64_t neg = (uint64_t)simd_data(desc) << 63;
108
+ uint64_t *za = vza, *zn = vzn, *zm = vzm;
109
+ uint8_t *pn = vpn, *pm = vpm;
110
+ float_status fpst = *(float_status *)vst;
111
+
112
+ set_default_nan_mode(true, &fpst);
113
+
114
+ for (row = 0; row < oprsz; ++row) {
115
+ if (pn[H1(row)] & 1) {
116
+ uint64_t *za_row = &za[tile_vslice_index(row)];
117
+ uint64_t n = zn[row] ^ neg;
118
+
119
+ for (col = 0; col < oprsz; ++col) {
120
+ if (pm[H1(col)] & 1) {
121
+ uint64_t *a = &za_row[col];
122
+ *a = float64_muladd(n, zm[col], *a, 0, &fpst);
123
+ }
124
+ }
34
+ }
125
+ }
35
+ }
126
+ }
36
+ g_assert_not_reached();
127
+}
128
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/target/arm/translate-sme.c
131
+++ b/target/arm/translate-sme.c
132
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(ADDHA_s, aa64_sme, do_adda, a, MO_32, gen_helper_sme_addha_s)
133
TRANS_FEAT(ADDVA_s, aa64_sme, do_adda, a, MO_32, gen_helper_sme_addva_s)
134
TRANS_FEAT(ADDHA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addha_d)
135
TRANS_FEAT(ADDVA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addva_d)
136
+
137
+static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz,
138
+ gen_helper_gvec_5_ptr *fn)
139
+{
140
+ int svl = streaming_vec_reg_size(s);
141
+ uint32_t desc = simd_desc(svl, svl, a->sub);
142
+ TCGv_ptr za, zn, zm, pn, pm, fpst;
143
+
144
+ if (!sme_smza_enabled_check(s)) {
145
+ return true;
146
+ }
147
+
148
+ /* Sum XZR+zad to find ZAd. */
149
+ za = get_tile_rowcol(s, esz, 31, a->zad, false);
150
+ zn = vec_full_reg_ptr(s, a->zn);
151
+ zm = vec_full_reg_ptr(s, a->zm);
152
+ pn = pred_full_reg_ptr(s, a->pn);
153
+ pm = pred_full_reg_ptr(s, a->pm);
154
+ fpst = fpstatus_ptr(FPST_FPCR);
155
+
156
+ fn(za, zn, zm, pn, pm, fpst, tcg_constant_i32(desc));
157
+
158
+ tcg_temp_free_ptr(za);
159
+ tcg_temp_free_ptr(zn);
160
+ tcg_temp_free_ptr(pn);
161
+ tcg_temp_free_ptr(pm);
162
+ tcg_temp_free_ptr(fpst);
163
+ return true;
37
+}
164
+}
38
+
165
+
39
static void mps2tz_common_init(MachineState *machine)
166
+TRANS_FEAT(FMOPA_s, aa64_sme, do_outprod_fpst, a, MO_32, gen_helper_sme_fmopa_s)
40
{
167
+TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst, a, MO_64, gen_helper_sme_fmopa_d)
41
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
42
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
43
44
create_non_mpc_ram(mms);
45
46
- armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
47
+ armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
48
+ boot_ram_size(mms));
49
}
50
51
static void mps2_tz_idau_check(IDAUInterface *ii, uint32_t address,
52
--
168
--
53
2.20.1
169
2.25.1
54
55
diff view generated by jsdifflib
1
The AN505 and AN521 have the same layout of RAM; the AN524 does not.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
Replace the current hard-coding of where the RAM is and which parts
3
of it are behind which MPCs with a data-driven approach.
4
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20220708151540.18136-26-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20210215115138.20465-17-peter.maydell@linaro.org
8
---
7
---
9
hw/arm/mps2-tz.c | 175 +++++++++++++++++++++++++++++++++++++----------
8
target/arm/helper-sme.h | 2 ++
10
1 file changed, 138 insertions(+), 37 deletions(-)
9
target/arm/sme.decode | 2 ++
10
target/arm/sme_helper.c | 56 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-sme.c | 30 ++++++++++++++++++++
12
4 files changed, 90 insertions(+)
11
13
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/mps2-tz.c
16
--- a/target/arm/helper-sme.h
15
+++ b/hw/arm/mps2-tz.c
17
+++ b/target/arm/helper-sme.h
16
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_7(sme_fmopa_s, TCG_CALL_NO_RWG,
17
#include "qom/object.h"
19
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
18
20
DEF_HELPER_FLAGS_7(sme_fmopa_d, TCG_CALL_NO_RWG,
19
#define MPS2TZ_NUMIRQ_MAX 92
21
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
20
+#define MPS2TZ_RAM_MAX 4
22
+DEF_HELPER_FLAGS_6(sme_bfmopa, TCG_CALL_NO_RWG,
21
23
+ void, ptr, ptr, ptr, ptr, ptr, i32)
22
typedef enum MPS2TZFPGAType {
24
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
23
FPGA_AN505,
25
index XXXXXXX..XXXXXXX 100644
24
FPGA_AN521,
26
--- a/target/arm/sme.decode
25
} MPS2TZFPGAType;
27
+++ b/target/arm/sme.decode
26
28
@@ -XXX,XX +XXX,XX @@ ADDVA_d 11000000 11 01000 1 ... ... ..... 00 ... @adda_64
27
+/*
29
28
+ * Define the layout of RAM in a board, including which parts are
30
FMOPA_s 10000000 100 ..... ... ... ..... . 00 .. @op_32
29
+ * behind which MPCs.
31
FMOPA_d 10000000 110 ..... ... ... ..... . 0 ... @op_64
30
+ * mrindex specifies the index into mms->ram[] to use for the backing RAM;
32
+
31
+ * -1 means "use the system RAM".
33
+BFMOPA 10000001 100 ..... ... ... ..... . 00 .. @op_32
32
+ */
34
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
33
+typedef struct RAMInfo {
35
index XXXXXXX..XXXXXXX 100644
34
+ const char *name;
36
--- a/target/arm/sme_helper.c
35
+ uint32_t base;
37
+++ b/target/arm/sme_helper.c
36
+ uint32_t size;
38
@@ -XXX,XX +XXX,XX @@ void HELPER(sme_fmopa_d)(void *vza, void *vzn, void *vzm, void *vpn,
37
+ int mpc; /* MPC number, -1 for "not behind an MPC" */
39
}
38
+ int mrindex;
40
}
39
+ int flags;
41
}
40
+} RAMInfo;
41
+
42
+
42
+/*
43
+/*
43
+ * Flag values:
44
+ * Alter PAIR as needed for controlling predicates being false,
44
+ * IS_ALIAS: this RAM area is an alias to the upstream end of the
45
+ * and for NEG on an enabled row element.
45
+ * MPC specified by its .mpc value
46
+ */
46
+ */
47
+#define IS_ALIAS 1
47
+static inline uint32_t f16mop_adj_pair(uint32_t pair, uint32_t pg, uint32_t neg)
48
+
49
struct MPS2TZMachineClass {
50
MachineClass parent;
51
MPS2TZFPGAType fpga_type;
52
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
53
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
54
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
55
int numirq; /* Number of external interrupts */
56
+ const RAMInfo *raminfo;
57
const char *armsse_type;
58
};
59
60
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
61
MachineState parent;
62
63
ARMSSE iotkit;
64
- MemoryRegion ssram[3];
65
- MemoryRegion ssram1_m;
66
+ MemoryRegion ram[MPS2TZ_RAM_MAX];
67
MPS2SCC scc;
68
MPS2FPGAIO fpgaio;
69
TZPPC ppc[5];
70
- TZMPC ssram_mpc[3];
71
+ TZMPC mpc[3];
72
PL022State spi[5];
73
ArmSbconI2CState i2c[4];
74
UnimplementedDeviceState i2s_audio;
75
@@ -XXX,XX +XXX,XX @@ static const uint32_t an505_oscclk[] = {
76
25000000,
77
};
78
79
+static const RAMInfo an505_raminfo[] = { {
80
+ .name = "ssram-0",
81
+ .base = 0x00000000,
82
+ .size = 0x00400000,
83
+ .mpc = 0,
84
+ .mrindex = 0,
85
+ }, {
86
+ .name = "ssram-1",
87
+ .base = 0x28000000,
88
+ .size = 0x00200000,
89
+ .mpc = 1,
90
+ .mrindex = 1,
91
+ }, {
92
+ .name = "ssram-2",
93
+ .base = 0x28200000,
94
+ .size = 0x00200000,
95
+ .mpc = 2,
96
+ .mrindex = 2,
97
+ }, {
98
+ .name = "ssram-0-alias",
99
+ .base = 0x00400000,
100
+ .size = 0x00400000,
101
+ .mpc = 0,
102
+ .mrindex = 3,
103
+ .flags = IS_ALIAS,
104
+ }, {
105
+ /* Use the largest bit of contiguous RAM as our "system memory" */
106
+ .name = "mps.ram",
107
+ .base = 0x80000000,
108
+ .size = 16 * MiB,
109
+ .mpc = -1,
110
+ .mrindex = -1,
111
+ }, {
112
+ .name = NULL,
113
+ },
114
+};
115
+
116
+static const RAMInfo *find_raminfo_for_mpc(MPS2TZMachineState *mms, int mpc)
117
+{
48
+{
118
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
49
+ /*
119
+ const RAMInfo *p;
50
+ * The pseudocode uses a conditional negate after the conditional zero.
120
+
51
+ * It is simpler here to unconditionally negate before conditional zero.
121
+ for (p = mmc->raminfo; p->name; p++) {
52
+ */
122
+ if (p->mpc == mpc && !(p->flags & IS_ALIAS)) {
53
+ pair ^= neg;
123
+ return p;
54
+ if (!(pg & 1)) {
124
+ }
55
+ pair &= 0xffff0000u;
125
+ }
56
+ }
126
+ /* if raminfo array doesn't have an entry for each MPC this is a bug */
57
+ if (!(pg & 4)) {
127
+ g_assert_not_reached();
58
+ pair &= 0x0000ffffu;
59
+ }
60
+ return pair;
128
+}
61
+}
129
+
62
+
130
+static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
63
+void HELPER(sme_bfmopa)(void *vza, void *vzn, void *vzm, void *vpn,
131
+ const RAMInfo *raminfo)
64
+ void *vpm, uint32_t desc)
132
+{
65
+{
133
+ /* Return an initialized MemoryRegion for the RAMInfo. */
66
+ intptr_t row, col, oprsz = simd_maxsz(desc);
134
+ MemoryRegion *ram;
67
+ uint32_t neg = simd_data(desc) * 0x80008000u;
68
+ uint16_t *pn = vpn, *pm = vpm;
135
+
69
+
136
+ if (raminfo->mrindex < 0) {
70
+ for (row = 0; row < oprsz; ) {
137
+ /* Means this RAMInfo is for QEMU's "system memory" */
71
+ uint16_t prow = pn[H2(row >> 4)];
138
+ MachineState *machine = MACHINE(mms);
72
+ do {
139
+ return machine->ram;
73
+ void *vza_row = vza + tile_vslice_offset(row);
74
+ uint32_t n = *(uint32_t *)(vzn + H1_4(row));
75
+
76
+ n = f16mop_adj_pair(n, prow, neg);
77
+
78
+ for (col = 0; col < oprsz; ) {
79
+ uint16_t pcol = pm[H2(col >> 4)];
80
+ do {
81
+ if (prow & pcol & 0b0101) {
82
+ uint32_t *a = vza_row + H1_4(col);
83
+ uint32_t m = *(uint32_t *)(vzm + H1_4(col));
84
+
85
+ m = f16mop_adj_pair(m, pcol, 0);
86
+ *a = bfdotadd(*a, n, m);
87
+
88
+ col += 4;
89
+ pcol >>= 4;
90
+ }
91
+ } while (col & 15);
92
+ }
93
+ row += 4;
94
+ prow >>= 4;
95
+ } while (row & 15);
96
+ }
97
+}
98
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/translate-sme.c
101
+++ b/target/arm/translate-sme.c
102
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(ADDVA_s, aa64_sme, do_adda, a, MO_32, gen_helper_sme_addva_s)
103
TRANS_FEAT(ADDHA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addha_d)
104
TRANS_FEAT(ADDVA_d, aa64_sme_i16i64, do_adda, a, MO_64, gen_helper_sme_addva_d)
105
106
+static bool do_outprod(DisasContext *s, arg_op *a, MemOp esz,
107
+ gen_helper_gvec_5 *fn)
108
+{
109
+ int svl = streaming_vec_reg_size(s);
110
+ uint32_t desc = simd_desc(svl, svl, a->sub);
111
+ TCGv_ptr za, zn, zm, pn, pm;
112
+
113
+ if (!sme_smza_enabled_check(s)) {
114
+ return true;
140
+ }
115
+ }
141
+
116
+
142
+ assert(raminfo->mrindex < MPS2TZ_RAM_MAX);
117
+ /* Sum XZR+zad to find ZAd. */
143
+ ram = &mms->ram[raminfo->mrindex];
118
+ za = get_tile_rowcol(s, esz, 31, a->zad, false);
119
+ zn = vec_full_reg_ptr(s, a->zn);
120
+ zm = vec_full_reg_ptr(s, a->zm);
121
+ pn = pred_full_reg_ptr(s, a->pn);
122
+ pm = pred_full_reg_ptr(s, a->pm);
144
+
123
+
145
+ memory_region_init_ram(ram, NULL, raminfo->name,
124
+ fn(za, zn, zm, pn, pm, tcg_constant_i32(desc));
146
+ raminfo->size, &error_fatal);
125
+
147
+ return ram;
126
+ tcg_temp_free_ptr(za);
127
+ tcg_temp_free_ptr(zn);
128
+ tcg_temp_free_ptr(pn);
129
+ tcg_temp_free_ptr(pm);
130
+ return true;
148
+}
131
+}
149
+
132
+
150
/* Create an alias of an entire original MemoryRegion @orig
133
static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz,
151
* located at @base in the memory map.
134
gen_helper_gvec_5_ptr *fn)
152
*/
153
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
154
const int *irqs)
155
{
135
{
156
TZMPC *mpc = opaque;
136
@@ -XXX,XX +XXX,XX @@ static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz,
157
- int i = mpc - &mms->ssram_mpc[0];
137
158
- MemoryRegion *ssram = &mms->ssram[i];
138
TRANS_FEAT(FMOPA_s, aa64_sme, do_outprod_fpst, a, MO_32, gen_helper_sme_fmopa_s)
159
+ int i = mpc - &mms->mpc[0];
139
TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst, a, MO_64, gen_helper_sme_fmopa_d)
160
MemoryRegion *upstream;
161
- char *mpcname = g_strdup_printf("%s-mpc", name);
162
- static uint32_t ramsize[] = { 0x00400000, 0x00200000, 0x00200000 };
163
- static uint32_t rambase[] = { 0x00000000, 0x28000000, 0x28200000 };
164
+ const RAMInfo *raminfo = find_raminfo_for_mpc(mms, i);
165
+ MemoryRegion *ram = mr_for_raminfo(mms, raminfo);
166
167
- memory_region_init_ram(ssram, NULL, name, ramsize[i], &error_fatal);
168
-
169
- object_initialize_child(OBJECT(mms), mpcname, mpc, TYPE_TZ_MPC);
170
- object_property_set_link(OBJECT(mpc), "downstream", OBJECT(ssram),
171
+ object_initialize_child(OBJECT(mms), name, mpc, TYPE_TZ_MPC);
172
+ object_property_set_link(OBJECT(mpc), "downstream", OBJECT(ram),
173
&error_fatal);
174
sysbus_realize(SYS_BUS_DEVICE(mpc), &error_fatal);
175
/* Map the upstream end of the MPC into system memory */
176
upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 1);
177
- memory_region_add_subregion(get_system_memory(), rambase[i], upstream);
178
+ memory_region_add_subregion(get_system_memory(), raminfo->base, upstream);
179
/* and connect its interrupt to the IoTKit */
180
qdev_connect_gpio_out_named(DEVICE(mpc), "irq", 0,
181
qdev_get_gpio_in_named(DEVICE(&mms->iotkit),
182
"mpcexp_status", i));
183
184
- /* The first SSRAM is a special case as it has an alias; accesses to
185
- * the alias region at 0x00400000 must also go to the MPC upstream.
186
- */
187
- if (i == 0) {
188
- make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", upstream, 0x00400000);
189
- }
190
-
191
- g_free(mpcname);
192
/* Return the register interface MR for our caller to map behind the PPC */
193
return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
194
}
195
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
196
return sysbus_mmio_get_region(s, 0);
197
}
198
199
+static void create_non_mpc_ram(MPS2TZMachineState *mms)
200
+{
201
+ /*
202
+ * Handle the RAMs which are either not behind MPCs or which are
203
+ * aliases to another MPC.
204
+ */
205
+ const RAMInfo *p;
206
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
207
+
140
+
208
+ for (p = mmc->raminfo; p->name; p++) {
141
+/* TODO: FEAT_EBF16 */
209
+ if (p->flags & IS_ALIAS) {
142
+TRANS_FEAT(BFMOPA, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_bfmopa)
210
+ SysBusDevice *mpc_sbd = SYS_BUS_DEVICE(&mms->mpc[p->mpc]);
211
+ MemoryRegion *upstream = sysbus_mmio_get_region(mpc_sbd, 1);
212
+ make_ram_alias(&mms->ram[p->mrindex], p->name, upstream, p->base);
213
+ } else if (p->mpc == -1) {
214
+ /* RAM not behind an MPC */
215
+ MemoryRegion *mr = mr_for_raminfo(mms, p);
216
+ memory_region_add_subregion(get_system_memory(), p->base, mr);
217
+ }
218
+ }
219
+}
220
+
221
static void mps2tz_common_init(MachineState *machine)
222
{
223
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
224
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
225
qdev_connect_gpio_out_named(iotkitdev, "sec_resp_cfg", 0,
226
qdev_get_gpio_in(dev_splitter, 0));
227
228
- /* The IoTKit sets up much of the memory layout, including
229
+ /*
230
+ * The IoTKit sets up much of the memory layout, including
231
* the aliases between secure and non-secure regions in the
232
- * address space. The FPGA itself contains:
233
- *
234
- * 0x00000000..0x003fffff SSRAM1
235
- * 0x00400000..0x007fffff alias of SSRAM1
236
- * 0x28000000..0x283fffff 4MB SSRAM2 + SSRAM3
237
- * 0x40100000..0x4fffffff AHB Master Expansion 1 interface devices
238
- * 0x80000000..0x80ffffff 16MB PSRAM
239
- */
240
-
241
- /* The FPGA images have an odd combination of different RAMs,
242
+ * address space, and also most of the devices in the system.
243
+ * The FPGA itself contains various RAMs and some additional devices.
244
+ * The FPGA images have an odd combination of different RAMs,
245
* because in hardware they are different implementations and
246
* connected to different buses, giving varying performance/size
247
* tradeoffs. For QEMU they're all just RAM, though. We arbitrarily
248
- * call the 16MB our "system memory", as it's the largest lump.
249
+ * call the largest lump our "system memory".
250
*/
251
- memory_region_add_subregion(system_memory, 0x80000000, machine->ram);
252
253
/*
254
* The overflow IRQs for all UARTs are ORed together.
255
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
256
const PPCInfo an505_ppcs[] = { {
257
.name = "apb_ppcexp0",
258
.ports = {
259
- { "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
260
- { "ssram-1", make_mpc, &mms->ssram_mpc[1], 0x58008000, 0x1000 },
261
- { "ssram-2", make_mpc, &mms->ssram_mpc[2], 0x58009000, 0x1000 },
262
+ { "ssram-0-mpc", make_mpc, &mms->mpc[0], 0x58007000, 0x1000 },
263
+ { "ssram-1-mpc", make_mpc, &mms->mpc[1], 0x58008000, 0x1000 },
264
+ { "ssram-2-mpc", make_mpc, &mms->mpc[2], 0x58009000, 0x1000 },
265
},
266
}, {
267
.name = "apb_ppcexp1",
268
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
269
270
create_unimplemented_device("FPGA NS PC", 0x48007000, 0x1000);
271
272
+ create_non_mpc_ram(mms);
273
+
274
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
275
}
276
277
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
278
mmc->fpgaio_num_leds = 2;
279
mmc->fpgaio_has_switches = false;
280
mmc->numirq = 92;
281
+ mmc->raminfo = an505_raminfo;
282
mmc->armsse_type = TYPE_IOTKIT;
283
}
284
285
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
286
mmc->fpgaio_num_leds = 2;
287
mmc->fpgaio_has_switches = false;
288
mmc->numirq = 92;
289
+ mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
290
mmc->armsse_type = TYPE_SSE200;
291
}
292
293
--
143
--
294
2.20.1
144
2.25.1
295
296
diff view generated by jsdifflib
1
Currently the MPS2 SCC device implements a fixed number of OSCCLK
1
From: Richard Henderson <richard.henderson@linaro.org>
2
values (3). The variant of this device in the MPS3 AN524 board has 6
3
OSCCLK values. Switch to using a PROP_ARRAY, which allows board code
4
to specify how large the OSCCLK array should be as well as its
5
values.
6
2
7
With a variable-length property array, the SCC no longer specifies
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
default values for the OSCCLKs, so we must set them explicitly in the
4
Message-id: 20220708151540.18136-27-richard.henderson@linaro.org
9
board code. This defaults are actually incorrect for the an521 and
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
an505; we will correct this bug in a following patch.
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sme.h | 2 ++
9
target/arm/sme.decode | 1 +
10
target/arm/sme_helper.c | 74 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-sme.c | 1 +
12
4 files changed, 78 insertions(+)
11
13
12
This is a migration compatibility break for all the mps boards.
14
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
13
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20210215115138.20465-3-peter.maydell@linaro.org
18
---
19
include/hw/misc/mps2-scc.h | 7 +++----
20
hw/arm/mps2-tz.c | 5 +++++
21
hw/arm/mps2.c | 5 +++++
22
hw/misc/mps2-scc.c | 24 +++++++++++++-----------
23
4 files changed, 26 insertions(+), 15 deletions(-)
24
25
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
26
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/misc/mps2-scc.h
16
--- a/target/arm/helper-sme.h
28
+++ b/include/hw/misc/mps2-scc.h
17
+++ b/target/arm/helper-sme.h
29
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sme_addva_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
30
#define TYPE_MPS2_SCC "mps2-scc"
19
DEF_HELPER_FLAGS_5(sme_addha_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
31
OBJECT_DECLARE_SIMPLE_TYPE(MPS2SCC, MPS2_SCC)
20
DEF_HELPER_FLAGS_5(sme_addva_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
32
21
33
-#define NUM_OSCCLK 3
22
+DEF_HELPER_FLAGS_7(sme_fmopa_h, TCG_CALL_NO_RWG,
34
-
23
+ void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
35
struct MPS2SCC {
24
DEF_HELPER_FLAGS_7(sme_fmopa_s, TCG_CALL_NO_RWG,
36
/*< private >*/
25
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
37
SysBusDevice parent_obj;
26
DEF_HELPER_FLAGS_7(sme_fmopa_d, TCG_CALL_NO_RWG,
38
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
27
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
39
uint32_t dll;
40
uint32_t aid;
41
uint32_t id;
42
- uint32_t oscclk[NUM_OSCCLK];
43
- uint32_t oscclk_reset[NUM_OSCCLK];
44
+ uint32_t num_oscclk;
45
+ uint32_t *oscclk;
46
+ uint32_t *oscclk_reset;
47
};
48
49
#endif
50
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
51
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/arm/mps2-tz.c
29
--- a/target/arm/sme.decode
53
+++ b/hw/arm/mps2-tz.c
30
+++ b/target/arm/sme.decode
54
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
31
@@ -XXX,XX +XXX,XX @@ FMOPA_s 10000000 100 ..... ... ... ..... . 00 .. @op_32
55
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
32
FMOPA_d 10000000 110 ..... ... ... ..... . 0 ... @op_64
56
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
33
57
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
34
BFMOPA 10000001 100 ..... ... ... ..... . 00 .. @op_32
58
+ /* This will need to be per-FPGA image eventually */
35
+FMOPA_h 10000001 101 ..... ... ... ..... . 00 .. @op_32
59
+ qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
36
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
60
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
37
index XXXXXXX..XXXXXXX 100644
61
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
38
--- a/target/arm/sme_helper.c
62
+ qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
39
+++ b/target/arm/sme_helper.c
63
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
40
@@ -XXX,XX +XXX,XX @@ static inline uint32_t f16mop_adj_pair(uint32_t pair, uint32_t pg, uint32_t neg)
64
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
41
return pair;
65
}
42
}
66
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
43
44
+static float32 f16_dotadd(float32 sum, uint32_t e1, uint32_t e2,
45
+ float_status *s_std, float_status *s_odd)
46
+{
47
+ float64 e1r = float16_to_float64(e1 & 0xffff, true, s_std);
48
+ float64 e1c = float16_to_float64(e1 >> 16, true, s_std);
49
+ float64 e2r = float16_to_float64(e2 & 0xffff, true, s_std);
50
+ float64 e2c = float16_to_float64(e2 >> 16, true, s_std);
51
+ float64 t64;
52
+ float32 t32;
53
+
54
+ /*
55
+ * The ARM pseudocode function FPDot performs both multiplies
56
+ * and the add with a single rounding operation. Emulate this
57
+ * by performing the first multiply in round-to-odd, then doing
58
+ * the second multiply as fused multiply-add, and rounding to
59
+ * float32 all in one step.
60
+ */
61
+ t64 = float64_mul(e1r, e2r, s_odd);
62
+ t64 = float64r32_muladd(e1c, e2c, t64, 0, s_std);
63
+
64
+ /* This conversion is exact, because we've already rounded. */
65
+ t32 = float64_to_float32(t64, s_std);
66
+
67
+ /* The final accumulation step is not fused. */
68
+ return float32_add(sum, t32, s_std);
69
+}
70
+
71
+void HELPER(sme_fmopa_h)(void *vza, void *vzn, void *vzm, void *vpn,
72
+ void *vpm, void *vst, uint32_t desc)
73
+{
74
+ intptr_t row, col, oprsz = simd_maxsz(desc);
75
+ uint32_t neg = simd_data(desc) * 0x80008000u;
76
+ uint16_t *pn = vpn, *pm = vpm;
77
+ float_status fpst_odd, fpst_std;
78
+
79
+ /*
80
+ * Make a copy of float_status because this operation does not
81
+ * update the cumulative fp exception status. It also produces
82
+ * default nans. Make a second copy with round-to-odd -- see above.
83
+ */
84
+ fpst_std = *(float_status *)vst;
85
+ set_default_nan_mode(true, &fpst_std);
86
+ fpst_odd = fpst_std;
87
+ set_float_rounding_mode(float_round_to_odd, &fpst_odd);
88
+
89
+ for (row = 0; row < oprsz; ) {
90
+ uint16_t prow = pn[H2(row >> 4)];
91
+ do {
92
+ void *vza_row = vza + tile_vslice_offset(row);
93
+ uint32_t n = *(uint32_t *)(vzn + H1_4(row));
94
+
95
+ n = f16mop_adj_pair(n, prow, neg);
96
+
97
+ for (col = 0; col < oprsz; ) {
98
+ uint16_t pcol = pm[H2(col >> 4)];
99
+ do {
100
+ if (prow & pcol & 0b0101) {
101
+ uint32_t *a = vza_row + H1_4(col);
102
+ uint32_t m = *(uint32_t *)(vzm + H1_4(col));
103
+
104
+ m = f16mop_adj_pair(m, pcol, 0);
105
+ *a = f16_dotadd(*a, n, m, &fpst_std, &fpst_odd);
106
+
107
+ col += 4;
108
+ pcol >>= 4;
109
+ }
110
+ } while (col & 15);
111
+ }
112
+ row += 4;
113
+ prow >>= 4;
114
+ } while (row & 15);
115
+ }
116
+}
117
+
118
void HELPER(sme_bfmopa)(void *vza, void *vzn, void *vzm, void *vpn,
119
void *vpm, uint32_t desc)
120
{
121
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
67
index XXXXXXX..XXXXXXX 100644
122
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/mps2.c
123
--- a/target/arm/translate-sme.c
69
+++ b/hw/arm/mps2.c
124
+++ b/target/arm/translate-sme.c
70
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
125
@@ -XXX,XX +XXX,XX @@ static bool do_outprod_fpst(DisasContext *s, arg_op *a, MemOp esz,
71
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
126
return true;
72
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
73
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
74
+ /* All these FPGA images have the same OSCCLK configuration */
75
+ qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
76
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
77
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
78
+ qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
79
sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
80
sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
81
object_initialize_child(OBJECT(mms), "fpgaio",
82
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/misc/mps2-scc.c
85
+++ b/hw/misc/mps2-scc.c
86
@@ -XXX,XX +XXX,XX @@ static bool scc_cfg_write(MPS2SCC *s, unsigned function,
87
{
88
trace_mps2_scc_cfg_write(function, device, value);
89
90
- if (function != 1 || device >= NUM_OSCCLK) {
91
+ if (function != 1 || device >= s->num_oscclk) {
92
qemu_log_mask(LOG_GUEST_ERROR,
93
"MPS2 SCC config write: bad function %d device %d\n",
94
function, device);
95
@@ -XXX,XX +XXX,XX @@ static bool scc_cfg_write(MPS2SCC *s, unsigned function,
96
static bool scc_cfg_read(MPS2SCC *s, unsigned function,
97
unsigned device, uint32_t *value)
98
{
99
- if (function != 1 || device >= NUM_OSCCLK) {
100
+ if (function != 1 || device >= s->num_oscclk) {
101
qemu_log_mask(LOG_GUEST_ERROR,
102
"MPS2 SCC config read: bad function %d device %d\n",
103
function, device);
104
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_reset(DeviceState *dev)
105
s->cfgctrl = 0x100000;
106
s->cfgstat = 0;
107
s->dll = 0xffff0001;
108
- for (i = 0; i < NUM_OSCCLK; i++) {
109
+ for (i = 0; i < s->num_oscclk; i++) {
110
s->oscclk[i] = s->oscclk_reset[i];
111
}
112
for (i = 0; i < ARRAY_SIZE(s->led); i++) {
113
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_realize(DeviceState *dev, Error **errp)
114
LED_COLOR_GREEN, name);
115
g_free(name);
116
}
117
+
118
+ s->oscclk = g_new0(uint32_t, s->num_oscclk);
119
}
127
}
120
128
121
static const VMStateDescription mps2_scc_vmstate = {
129
+TRANS_FEAT(FMOPA_h, aa64_sme, do_outprod_fpst, a, MO_32, gen_helper_sme_fmopa_h)
122
.name = "mps2-scc",
130
TRANS_FEAT(FMOPA_s, aa64_sme, do_outprod_fpst, a, MO_32, gen_helper_sme_fmopa_s)
123
- .version_id = 1,
131
TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst, a, MO_64, gen_helper_sme_fmopa_d)
124
- .minimum_version_id = 1,
125
+ .version_id = 2,
126
+ .minimum_version_id = 2,
127
.fields = (VMStateField[]) {
128
VMSTATE_UINT32(cfg0, MPS2SCC),
129
VMSTATE_UINT32(cfg1, MPS2SCC),
130
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_scc_vmstate = {
131
VMSTATE_UINT32(cfgctrl, MPS2SCC),
132
VMSTATE_UINT32(cfgstat, MPS2SCC),
133
VMSTATE_UINT32(dll, MPS2SCC),
134
- VMSTATE_UINT32_ARRAY(oscclk, MPS2SCC, NUM_OSCCLK),
135
+ VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
136
+ 0, vmstate_info_uint32, uint32_t),
137
VMSTATE_END_OF_LIST()
138
}
139
};
140
@@ -XXX,XX +XXX,XX @@ static Property mps2_scc_properties[] = {
141
DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, cfg4, 0),
142
DEFINE_PROP_UINT32("scc-aid", MPS2SCC, aid, 0),
143
DEFINE_PROP_UINT32("scc-id", MPS2SCC, id, 0),
144
- /* These are the initial settings for the source clocks on the board.
145
+ /*
146
+ * These are the initial settings for the source clocks on the board.
147
* In hardware they can be configured via a config file read by the
148
* motherboard configuration controller to suit the FPGA image.
149
- * These default values are used by most of the standard FPGA images.
150
*/
151
- DEFINE_PROP_UINT32("oscclk0", MPS2SCC, oscclk_reset[0], 50000000),
152
- DEFINE_PROP_UINT32("oscclk1", MPS2SCC, oscclk_reset[1], 24576000),
153
- DEFINE_PROP_UINT32("oscclk2", MPS2SCC, oscclk_reset[2], 25000000),
154
+ DEFINE_PROP_ARRAY("oscclk", MPS2SCC, num_oscclk, oscclk_reset,
155
+ qdev_prop_uint32, uint32_t),
156
DEFINE_PROP_END_OF_LIST(),
157
};
158
132
159
--
133
--
160
2.20.1
134
2.25.1
161
162
diff view generated by jsdifflib
1
We only include the template header once, so just inline it into the
1
From: Richard Henderson <richard.henderson@linaro.org>
2
source file for the device.
3
2
3
This is SMOPA, SUMOPA, USMOPA_s, UMOPA, for both Int8 and Int16.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220708151540.18136-28-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210215103215.4944-9-peter.maydell@linaro.org
8
---
9
---
9
hw/display/omap_lcd_template.h | 154 ---------------------------------
10
target/arm/helper-sme.h | 16 ++++++++
10
hw/display/omap_lcdc.c | 127 ++++++++++++++++++++++++++-
11
target/arm/sme.decode | 10 +++++
11
2 files changed, 125 insertions(+), 156 deletions(-)
12
target/arm/sme_helper.c | 82 ++++++++++++++++++++++++++++++++++++++
12
delete mode 100644 hw/display/omap_lcd_template.h
13
target/arm/translate-sme.c | 10 +++++
14
4 files changed, 118 insertions(+)
13
15
14
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
16
diff --git a/target/arm/helper-sme.h b/target/arm/helper-sme.h
15
deleted file mode 100644
16
index XXXXXXX..XXXXXXX
17
--- a/hw/display/omap_lcd_template.h
18
+++ /dev/null
19
@@ -XXX,XX +XXX,XX @@
20
-/*
21
- * QEMU OMAP LCD Emulator templates
22
- *
23
- * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
24
- *
25
- * Redistribution and use in source and binary forms, with or without
26
- * modification, are permitted provided that the following conditions
27
- * are met:
28
- *
29
- * 1. Redistributions of source code must retain the above copyright
30
- * notice, this list of conditions and the following disclaimer.
31
- * 2. Redistributions in binary form must reproduce the above copyright
32
- * notice, this list of conditions and the following disclaimer in
33
- * the documentation and/or other materials provided with the
34
- * distribution.
35
- *
36
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
37
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
38
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
39
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
40
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
41
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
42
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
43
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
44
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
- */
48
-
49
-/*
50
- * 2-bit colour
51
- */
52
-static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
53
- int width, int deststep)
54
-{
55
- uint16_t *pal = opaque;
56
- uint8_t v, r, g, b;
57
-
58
- do {
59
- v = ldub_p((void *) s);
60
- r = (pal[v & 3] >> 4) & 0xf0;
61
- g = pal[v & 3] & 0xf0;
62
- b = (pal[v & 3] << 4) & 0xf0;
63
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
64
- d += 4;
65
- v >>= 2;
66
- r = (pal[v & 3] >> 4) & 0xf0;
67
- g = pal[v & 3] & 0xf0;
68
- b = (pal[v & 3] << 4) & 0xf0;
69
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
70
- d += 4;
71
- v >>= 2;
72
- r = (pal[v & 3] >> 4) & 0xf0;
73
- g = pal[v & 3] & 0xf0;
74
- b = (pal[v & 3] << 4) & 0xf0;
75
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
76
- d += 4;
77
- v >>= 2;
78
- r = (pal[v & 3] >> 4) & 0xf0;
79
- g = pal[v & 3] & 0xf0;
80
- b = (pal[v & 3] << 4) & 0xf0;
81
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
82
- d += 4;
83
- s++;
84
- width -= 4;
85
- } while (width > 0);
86
-}
87
-
88
-/*
89
- * 4-bit colour
90
- */
91
-static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
92
- int width, int deststep)
93
-{
94
- uint16_t *pal = opaque;
95
- uint8_t v, r, g, b;
96
-
97
- do {
98
- v = ldub_p((void *) s);
99
- r = (pal[v & 0xf] >> 4) & 0xf0;
100
- g = pal[v & 0xf] & 0xf0;
101
- b = (pal[v & 0xf] << 4) & 0xf0;
102
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
103
- d += 4;
104
- v >>= 4;
105
- r = (pal[v & 0xf] >> 4) & 0xf0;
106
- g = pal[v & 0xf] & 0xf0;
107
- b = (pal[v & 0xf] << 4) & 0xf0;
108
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
109
- d += 4;
110
- s++;
111
- width -= 2;
112
- } while (width > 0);
113
-}
114
-
115
-/*
116
- * 8-bit colour
117
- */
118
-static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
119
- int width, int deststep)
120
-{
121
- uint16_t *pal = opaque;
122
- uint8_t v, r, g, b;
123
-
124
- do {
125
- v = ldub_p((void *) s);
126
- r = (pal[v] >> 4) & 0xf0;
127
- g = pal[v] & 0xf0;
128
- b = (pal[v] << 4) & 0xf0;
129
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
130
- s++;
131
- d += 4;
132
- } while (-- width != 0);
133
-}
134
-
135
-/*
136
- * 12-bit colour
137
- */
138
-static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
139
- int width, int deststep)
140
-{
141
- uint16_t v;
142
- uint8_t r, g, b;
143
-
144
- do {
145
- v = lduw_le_p((void *) s);
146
- r = (v >> 4) & 0xf0;
147
- g = v & 0xf0;
148
- b = (v << 4) & 0xf0;
149
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
150
- s += 2;
151
- d += 4;
152
- } while (-- width != 0);
153
-}
154
-
155
-/*
156
- * 16-bit colour
157
- */
158
-static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
159
- int width, int deststep)
160
-{
161
- uint16_t v;
162
- uint8_t r, g, b;
163
-
164
- do {
165
- v = lduw_le_p((void *) s);
166
- r = (v >> 8) & 0xf8;
167
- g = (v >> 3) & 0xfc;
168
- b = (v << 3) & 0xf8;
169
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
170
- s += 2;
171
- d += 4;
172
- } while (-- width != 0);
173
-}
174
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
175
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
176
--- a/hw/display/omap_lcdc.c
18
--- a/target/arm/helper-sme.h
177
+++ b/hw/display/omap_lcdc.c
19
+++ b/target/arm/helper-sme.h
178
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_7(sme_fmopa_d, TCG_CALL_NO_RWG,
179
21
void, ptr, ptr, ptr, ptr, ptr, ptr, i32)
180
#define draw_line_func drawfn
22
DEF_HELPER_FLAGS_6(sme_bfmopa, TCG_CALL_NO_RWG,
181
23
void, ptr, ptr, ptr, ptr, ptr, i32)
182
-#define DEPTH 32
24
+DEF_HELPER_FLAGS_6(sme_smopa_s, TCG_CALL_NO_RWG,
183
-#include "omap_lcd_template.h"
25
+ void, ptr, ptr, ptr, ptr, ptr, i32)
184
+/*
26
+DEF_HELPER_FLAGS_6(sme_umopa_s, TCG_CALL_NO_RWG,
185
+ * 2-bit colour
27
+ void, ptr, ptr, ptr, ptr, ptr, i32)
186
+ */
28
+DEF_HELPER_FLAGS_6(sme_sumopa_s, TCG_CALL_NO_RWG,
187
+static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
29
+ void, ptr, ptr, ptr, ptr, ptr, i32)
188
+ int width, int deststep)
30
+DEF_HELPER_FLAGS_6(sme_usmopa_s, TCG_CALL_NO_RWG,
31
+ void, ptr, ptr, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_6(sme_smopa_d, TCG_CALL_NO_RWG,
33
+ void, ptr, ptr, ptr, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_6(sme_umopa_d, TCG_CALL_NO_RWG,
35
+ void, ptr, ptr, ptr, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_6(sme_sumopa_d, TCG_CALL_NO_RWG,
37
+ void, ptr, ptr, ptr, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_6(sme_usmopa_d, TCG_CALL_NO_RWG,
39
+ void, ptr, ptr, ptr, ptr, ptr, i32)
40
diff --git a/target/arm/sme.decode b/target/arm/sme.decode
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/sme.decode
43
+++ b/target/arm/sme.decode
44
@@ -XXX,XX +XXX,XX @@ FMOPA_d 10000000 110 ..... ... ... ..... . 0 ... @op_64
45
46
BFMOPA 10000001 100 ..... ... ... ..... . 00 .. @op_32
47
FMOPA_h 10000001 101 ..... ... ... ..... . 00 .. @op_32
48
+
49
+SMOPA_s 1010000 0 10 0 ..... ... ... ..... . 00 .. @op_32
50
+SUMOPA_s 1010000 0 10 1 ..... ... ... ..... . 00 .. @op_32
51
+USMOPA_s 1010000 1 10 0 ..... ... ... ..... . 00 .. @op_32
52
+UMOPA_s 1010000 1 10 1 ..... ... ... ..... . 00 .. @op_32
53
+
54
+SMOPA_d 1010000 0 11 0 ..... ... ... ..... . 0 ... @op_64
55
+SUMOPA_d 1010000 0 11 1 ..... ... ... ..... . 0 ... @op_64
56
+USMOPA_d 1010000 1 11 0 ..... ... ... ..... . 0 ... @op_64
57
+UMOPA_d 1010000 1 11 1 ..... ... ... ..... . 0 ... @op_64
58
diff --git a/target/arm/sme_helper.c b/target/arm/sme_helper.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/sme_helper.c
61
+++ b/target/arm/sme_helper.c
62
@@ -XXX,XX +XXX,XX @@ void HELPER(sme_bfmopa)(void *vza, void *vzn, void *vzm, void *vpn,
63
} while (row & 15);
64
}
65
}
66
+
67
+typedef uint64_t IMOPFn(uint64_t, uint64_t, uint64_t, uint8_t, bool);
68
+
69
+static inline void do_imopa(uint64_t *za, uint64_t *zn, uint64_t *zm,
70
+ uint8_t *pn, uint8_t *pm,
71
+ uint32_t desc, IMOPFn *fn)
189
+{
72
+{
190
+ uint16_t *pal = opaque;
73
+ intptr_t row, col, oprsz = simd_oprsz(desc) / 8;
191
+ uint8_t v, r, g, b;
74
+ bool neg = simd_data(desc);
192
+
75
+
193
+ do {
76
+ for (row = 0; row < oprsz; ++row) {
194
+ v = ldub_p((void *) s);
77
+ uint8_t pa = pn[H1(row)];
195
+ r = (pal[v & 3] >> 4) & 0xf0;
78
+ uint64_t *za_row = &za[tile_vslice_index(row)];
196
+ g = pal[v & 3] & 0xf0;
79
+ uint64_t n = zn[row];
197
+ b = (pal[v & 3] << 4) & 0xf0;
80
+
198
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
81
+ for (col = 0; col < oprsz; ++col) {
199
+ d += 4;
82
+ uint8_t pb = pm[H1(col)];
200
+ v >>= 2;
83
+ uint64_t *a = &za_row[col];
201
+ r = (pal[v & 3] >> 4) & 0xf0;
84
+
202
+ g = pal[v & 3] & 0xf0;
85
+ *a = fn(n, zm[col], *a, pa & pb, neg);
203
+ b = (pal[v & 3] << 4) & 0xf0;
86
+ }
204
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
87
+ }
205
+ d += 4;
206
+ v >>= 2;
207
+ r = (pal[v & 3] >> 4) & 0xf0;
208
+ g = pal[v & 3] & 0xf0;
209
+ b = (pal[v & 3] << 4) & 0xf0;
210
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
211
+ d += 4;
212
+ v >>= 2;
213
+ r = (pal[v & 3] >> 4) & 0xf0;
214
+ g = pal[v & 3] & 0xf0;
215
+ b = (pal[v & 3] << 4) & 0xf0;
216
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
217
+ d += 4;
218
+ s++;
219
+ width -= 4;
220
+ } while (width > 0);
221
+}
88
+}
222
+
89
+
223
+/*
90
+#define DEF_IMOP_32(NAME, NTYPE, MTYPE) \
224
+ * 4-bit colour
91
+static uint64_t NAME(uint64_t n, uint64_t m, uint64_t a, uint8_t p, bool neg) \
225
+ */
92
+{ \
226
+static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
93
+ uint32_t sum0 = 0, sum1 = 0; \
227
+ int width, int deststep)
94
+ /* Apply P to N as a mask, making the inactive elements 0. */ \
228
+{
95
+ n &= expand_pred_b(p); \
229
+ uint16_t *pal = opaque;
96
+ sum0 += (NTYPE)(n >> 0) * (MTYPE)(m >> 0); \
230
+ uint8_t v, r, g, b;
97
+ sum0 += (NTYPE)(n >> 8) * (MTYPE)(m >> 8); \
231
+
98
+ sum0 += (NTYPE)(n >> 16) * (MTYPE)(m >> 16); \
232
+ do {
99
+ sum0 += (NTYPE)(n >> 24) * (MTYPE)(m >> 24); \
233
+ v = ldub_p((void *) s);
100
+ sum1 += (NTYPE)(n >> 32) * (MTYPE)(m >> 32); \
234
+ r = (pal[v & 0xf] >> 4) & 0xf0;
101
+ sum1 += (NTYPE)(n >> 40) * (MTYPE)(m >> 40); \
235
+ g = pal[v & 0xf] & 0xf0;
102
+ sum1 += (NTYPE)(n >> 48) * (MTYPE)(m >> 48); \
236
+ b = (pal[v & 0xf] << 4) & 0xf0;
103
+ sum1 += (NTYPE)(n >> 56) * (MTYPE)(m >> 56); \
237
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
104
+ if (neg) { \
238
+ d += 4;
105
+ sum0 = (uint32_t)a - sum0, sum1 = (uint32_t)(a >> 32) - sum1; \
239
+ v >>= 4;
106
+ } else { \
240
+ r = (pal[v & 0xf] >> 4) & 0xf0;
107
+ sum0 = (uint32_t)a + sum0, sum1 = (uint32_t)(a >> 32) + sum1; \
241
+ g = pal[v & 0xf] & 0xf0;
108
+ } \
242
+ b = (pal[v & 0xf] << 4) & 0xf0;
109
+ return ((uint64_t)sum1 << 32) | sum0; \
243
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
244
+ d += 4;
245
+ s++;
246
+ width -= 2;
247
+ } while (width > 0);
248
+}
110
+}
249
+
111
+
250
+/*
112
+#define DEF_IMOP_64(NAME, NTYPE, MTYPE) \
251
+ * 8-bit colour
113
+static uint64_t NAME(uint64_t n, uint64_t m, uint64_t a, uint8_t p, bool neg) \
252
+ */
114
+{ \
253
+static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
115
+ uint64_t sum = 0; \
254
+ int width, int deststep)
116
+ /* Apply P to N as a mask, making the inactive elements 0. */ \
255
+{
117
+ n &= expand_pred_h(p); \
256
+ uint16_t *pal = opaque;
118
+ sum += (NTYPE)(n >> 0) * (MTYPE)(m >> 0); \
257
+ uint8_t v, r, g, b;
119
+ sum += (NTYPE)(n >> 16) * (MTYPE)(m >> 16); \
258
+
120
+ sum += (NTYPE)(n >> 32) * (MTYPE)(m >> 32); \
259
+ do {
121
+ sum += (NTYPE)(n >> 48) * (MTYPE)(m >> 48); \
260
+ v = ldub_p((void *) s);
122
+ return neg ? a - sum : a + sum; \
261
+ r = (pal[v] >> 4) & 0xf0;
262
+ g = pal[v] & 0xf0;
263
+ b = (pal[v] << 4) & 0xf0;
264
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
265
+ s++;
266
+ d += 4;
267
+ } while (-- width != 0);
268
+}
123
+}
269
+
124
+
270
+/*
125
+DEF_IMOP_32(smopa_s, int8_t, int8_t)
271
+ * 12-bit colour
126
+DEF_IMOP_32(umopa_s, uint8_t, uint8_t)
272
+ */
127
+DEF_IMOP_32(sumopa_s, int8_t, uint8_t)
273
+static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
128
+DEF_IMOP_32(usmopa_s, uint8_t, int8_t)
274
+ int width, int deststep)
275
+{
276
+ uint16_t v;
277
+ uint8_t r, g, b;
278
+
129
+
279
+ do {
130
+DEF_IMOP_64(smopa_d, int16_t, int16_t)
280
+ v = lduw_le_p((void *) s);
131
+DEF_IMOP_64(umopa_d, uint16_t, uint16_t)
281
+ r = (v >> 4) & 0xf0;
132
+DEF_IMOP_64(sumopa_d, int16_t, uint16_t)
282
+ g = v & 0xf0;
133
+DEF_IMOP_64(usmopa_d, uint16_t, int16_t)
283
+ b = (v << 4) & 0xf0;
284
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
285
+ s += 2;
286
+ d += 4;
287
+ } while (-- width != 0);
288
+}
289
+
134
+
290
+/*
135
+#define DEF_IMOPH(NAME) \
291
+ * 16-bit colour
136
+ void HELPER(sme_##NAME)(void *vza, void *vzn, void *vzm, void *vpn, \
292
+ */
137
+ void *vpm, uint32_t desc) \
293
+static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
138
+ { do_imopa(vza, vzn, vzm, vpn, vpm, desc, NAME); }
294
+ int width, int deststep)
295
+{
296
+ uint16_t v;
297
+ uint8_t r, g, b;
298
+
139
+
299
+ do {
140
+DEF_IMOPH(smopa_s)
300
+ v = lduw_le_p((void *) s);
141
+DEF_IMOPH(umopa_s)
301
+ r = (v >> 8) & 0xf8;
142
+DEF_IMOPH(sumopa_s)
302
+ g = (v >> 3) & 0xfc;
143
+DEF_IMOPH(usmopa_s)
303
+ b = (v << 3) & 0xf8;
144
+DEF_IMOPH(smopa_d)
304
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
145
+DEF_IMOPH(umopa_d)
305
+ s += 2;
146
+DEF_IMOPH(sumopa_d)
306
+ d += 4;
147
+DEF_IMOPH(usmopa_d)
307
+ } while (-- width != 0);
148
diff --git a/target/arm/translate-sme.c b/target/arm/translate-sme.c
308
+}
149
index XXXXXXX..XXXXXXX 100644
309
150
--- a/target/arm/translate-sme.c
310
static void omap_update_display(void *opaque)
151
+++ b/target/arm/translate-sme.c
311
{
152
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst, a, MO_64, gen_helper_sme_f
153
154
/* TODO: FEAT_EBF16 */
155
TRANS_FEAT(BFMOPA, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_bfmopa)
156
+
157
+TRANS_FEAT(SMOPA_s, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_smopa_s)
158
+TRANS_FEAT(UMOPA_s, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_umopa_s)
159
+TRANS_FEAT(SUMOPA_s, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_sumopa_s)
160
+TRANS_FEAT(USMOPA_s, aa64_sme, do_outprod, a, MO_32, gen_helper_sme_usmopa_s)
161
+
162
+TRANS_FEAT(SMOPA_d, aa64_sme_i16i64, do_outprod, a, MO_64, gen_helper_sme_smopa_d)
163
+TRANS_FEAT(UMOPA_d, aa64_sme_i16i64, do_outprod, a, MO_64, gen_helper_sme_umopa_d)
164
+TRANS_FEAT(SUMOPA_d, aa64_sme_i16i64, do_outprod, a, MO_64, gen_helper_sme_sumopa_d)
165
+TRANS_FEAT(USMOPA_d, aa64_sme_i16i64, do_outprod, a, MO_64, gen_helper_sme_usmopa_d)
312
--
166
--
313
2.20.1
167
2.25.1
314
315
diff view generated by jsdifflib
1
From: Doug Evans <dje@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is a 10/100 ethernet device that has several features.
3
This is an SVE instruction that operates using the SVE vector
4
Only the ones needed by the Linux driver have been implemented.
4
length but that it is present only if SME is implemented.
5
See npcm7xx_emc.c for a list of unimplemented features.
6
5
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
8
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Doug Evans <dje@google.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210218212453.831406-3-dje@google.com
8
Message-id: 20220708151540.18136-29-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
docs/system/arm/nuvoton.rst | 3 ++-
11
target/arm/sve.decode | 20 +++++++++++++
15
include/hw/arm/npcm7xx.h | 2 ++
12
target/arm/translate-sve.c | 57 ++++++++++++++++++++++++++++++++++++++
16
hw/arm/npcm7xx.c | 50 +++++++++++++++++++++++++++++++++++--
13
2 files changed, 77 insertions(+)
17
3 files changed, 52 insertions(+), 3 deletions(-)
18
14
19
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
15
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/docs/system/arm/nuvoton.rst
17
--- a/target/arm/sve.decode
22
+++ b/docs/system/arm/nuvoton.rst
18
+++ b/target/arm/sve.decode
23
@@ -XXX,XX +XXX,XX @@ Supported devices
19
@@ -XXX,XX +XXX,XX @@ BFMLALT_zzxw 01100100 11 1 ..... 0100.1 ..... ..... @rrxr_3a esz=2
24
* Analog to Digital Converter (ADC)
20
25
* Pulse Width Modulation (PWM)
21
### SVE2 floating-point bfloat16 dot-product (indexed)
26
* SMBus controller (SMBF)
22
BFDOT_zzxz 01100100 01 1 ..... 010000 ..... ..... @rrxr_2 esz=2
27
+ * Ethernet controller (EMC)
23
+
28
24
+### SVE broadcast predicate element
29
Missing devices
25
+
30
---------------
26
+&psel esz pd pn pm rv imm
31
@@ -XXX,XX +XXX,XX @@ Missing devices
27
+%psel_rv 16:2 !function=plus_12
32
* Shared memory (SHM)
28
+%psel_imm_b 22:2 19:2
33
* eSPI slave interface
29
+%psel_imm_h 22:2 20:1
34
30
+%psel_imm_s 22:2
35
- * Ethernet controllers (GMAC and EMC)
31
+%psel_imm_d 23:1
36
+ * Ethernet controller (GMAC)
32
+@psel ........ .. . ... .. .. pn:4 . pm:4 . pd:4 \
37
* USB device (USBD)
33
+ &psel rv=%psel_rv
38
* Peripheral SPI controller (PSPI)
34
+
39
* SD/MMC host
35
+PSEL 00100101 .. 1 ..1 .. 01 .... 0 .... 0 .... \
40
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
36
+ @psel esz=0 imm=%psel_imm_b
37
+PSEL 00100101 .. 1 .10 .. 01 .... 0 .... 0 .... \
38
+ @psel esz=1 imm=%psel_imm_h
39
+PSEL 00100101 .. 1 100 .. 01 .... 0 .... 0 .... \
40
+ @psel esz=2 imm=%psel_imm_s
41
+PSEL 00100101 .1 1 000 .. 01 .... 0 .... 0 .... \
42
+ @psel esz=3 imm=%psel_imm_d
43
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
41
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
42
--- a/include/hw/arm/npcm7xx.h
45
--- a/target/arm/translate-sve.c
43
+++ b/include/hw/arm/npcm7xx.h
46
+++ b/target/arm/translate-sve.c
44
@@ -XXX,XX +XXX,XX @@
47
@@ -XXX,XX +XXX,XX @@ static bool do_BFMLAL_zzxw(DisasContext *s, arg_rrxr_esz *a, bool sel)
45
#include "hw/misc/npcm7xx_gcr.h"
48
46
#include "hw/misc/npcm7xx_pwm.h"
49
TRANS_FEAT(BFMLALB_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, false)
47
#include "hw/misc/npcm7xx_rng.h"
50
TRANS_FEAT(BFMLALT_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, true)
48
+#include "hw/net/npcm7xx_emc.h"
49
#include "hw/nvram/npcm7xx_otp.h"
50
#include "hw/timer/npcm7xx_timer.h"
51
#include "hw/ssi/npcm7xx_fiu.h"
52
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxState {
53
EHCISysBusState ehci;
54
OHCISysBusState ohci;
55
NPCM7xxFIUState fiu[2];
56
+ NPCM7xxEMCState emc[2];
57
} NPCM7xxState;
58
59
#define TYPE_NPCM7XX "npcm7xx"
60
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/arm/npcm7xx.c
63
+++ b/hw/arm/npcm7xx.c
64
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
65
NPCM7XX_UART1_IRQ,
66
NPCM7XX_UART2_IRQ,
67
NPCM7XX_UART3_IRQ,
68
+ NPCM7XX_EMC1RX_IRQ = 15,
69
+ NPCM7XX_EMC1TX_IRQ,
70
NPCM7XX_TIMER0_IRQ = 32, /* Timer Module 0 */
71
NPCM7XX_TIMER1_IRQ,
72
NPCM7XX_TIMER2_IRQ,
73
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
74
NPCM7XX_SMBUS15_IRQ,
75
NPCM7XX_PWM0_IRQ = 93, /* PWM module 0 */
76
NPCM7XX_PWM1_IRQ, /* PWM module 1 */
77
+ NPCM7XX_EMC2RX_IRQ = 114,
78
+ NPCM7XX_EMC2TX_IRQ,
79
NPCM7XX_GPIO0_IRQ = 116,
80
NPCM7XX_GPIO1_IRQ,
81
NPCM7XX_GPIO2_IRQ,
82
@@ -XXX,XX +XXX,XX @@ static const hwaddr npcm7xx_smbus_addr[] = {
83
0xf008f000,
84
};
85
86
+/* Register base address for each EMC Module */
87
+static const hwaddr npcm7xx_emc_addr[] = {
88
+ 0xf0825000,
89
+ 0xf0826000,
90
+};
91
+
51
+
92
static const struct {
52
+static bool trans_PSEL(DisasContext *s, arg_psel *a)
93
hwaddr regs_addr;
53
+{
94
uint32_t unconnected_pins;
54
+ int vl = vec_full_reg_size(s);
95
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init(Object *obj)
55
+ int pl = pred_gvec_reg_size(s);
96
for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
56
+ int elements = vl >> a->esz;
97
object_initialize_child(obj, "pwm[*]", &s->pwm[i], TYPE_NPCM7XX_PWM);
57
+ TCGv_i64 tmp, didx, dbit;
98
}
58
+ TCGv_ptr ptr;
99
+
59
+
100
+ for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
60
+ if (!dc_isar_feature(aa64_sme, s)) {
101
+ object_initialize_child(obj, "emc[*]", &s->emc[i], TYPE_NPCM7XX_EMC);
61
+ return false;
102
+ }
62
+ }
103
}
63
+ if (!sve_access_check(s)) {
104
64
+ return true;
105
static void npcm7xx_realize(DeviceState *dev, Error **errp)
106
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
107
sysbus_connect_irq(sbd, i, npcm7xx_irq(s, NPCM7XX_PWM0_IRQ + i));
108
}
109
110
+ /*
111
+ * EMC Modules. Cannot fail.
112
+ * The mapping of the device to its netdev backend works as follows:
113
+ * emc[i] = nd_table[i]
114
+ * This works around the inability to specify the netdev property for the
115
+ * emc device: it's not pluggable and thus the -device option can't be
116
+ * used.
117
+ */
118
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_emc_addr) != ARRAY_SIZE(s->emc));
119
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->emc) != 2);
120
+ for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
121
+ s->emc[i].emc_num = i;
122
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->emc[i]);
123
+ if (nd_table[i].used) {
124
+ qemu_check_nic_model(&nd_table[i], TYPE_NPCM7XX_EMC);
125
+ qdev_set_nic_properties(DEVICE(sbd), &nd_table[i]);
126
+ }
127
+ /*
128
+ * The device exists regardless of whether it's connected to a QEMU
129
+ * netdev backend. So always instantiate it even if there is no
130
+ * backend.
131
+ */
132
+ sysbus_realize(sbd, &error_abort);
133
+ sysbus_mmio_map(sbd, 0, npcm7xx_emc_addr[i]);
134
+ int tx_irq = i == 0 ? NPCM7XX_EMC1TX_IRQ : NPCM7XX_EMC2TX_IRQ;
135
+ int rx_irq = i == 0 ? NPCM7XX_EMC1RX_IRQ : NPCM7XX_EMC2RX_IRQ;
136
+ /*
137
+ * N.B. The values for the second argument sysbus_connect_irq are
138
+ * chosen to match the registration order in npcm7xx_emc_realize.
139
+ */
140
+ sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, tx_irq));
141
+ sysbus_connect_irq(sbd, 1, npcm7xx_irq(s, rx_irq));
142
+ }
65
+ }
143
+
66
+
144
/*
67
+ tmp = tcg_temp_new_i64();
145
* Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
68
+ dbit = tcg_temp_new_i64();
146
* specified, but this is a programming error.
69
+ didx = tcg_temp_new_i64();
147
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
70
+ ptr = tcg_temp_new_ptr();
148
create_unimplemented_device("npcm7xx.vcd", 0xf0810000, 64 * KiB);
71
+
149
create_unimplemented_device("npcm7xx.ece", 0xf0820000, 8 * KiB);
72
+ /* Compute the predicate element. */
150
create_unimplemented_device("npcm7xx.vdma", 0xf0822000, 8 * KiB);
73
+ tcg_gen_addi_i64(tmp, cpu_reg(s, a->rv), a->imm);
151
- create_unimplemented_device("npcm7xx.emc1", 0xf0825000, 4 * KiB);
74
+ if (is_power_of_2(elements)) {
152
- create_unimplemented_device("npcm7xx.emc2", 0xf0826000, 4 * KiB);
75
+ tcg_gen_andi_i64(tmp, tmp, elements - 1);
153
create_unimplemented_device("npcm7xx.usbd[0]", 0xf0830000, 4 * KiB);
76
+ } else {
154
create_unimplemented_device("npcm7xx.usbd[1]", 0xf0831000, 4 * KiB);
77
+ tcg_gen_remu_i64(tmp, tmp, tcg_constant_i64(elements));
155
create_unimplemented_device("npcm7xx.usbd[2]", 0xf0832000, 4 * KiB);
78
+ }
79
+
80
+ /* Extract the predicate byte and bit indices. */
81
+ tcg_gen_shli_i64(tmp, tmp, a->esz);
82
+ tcg_gen_andi_i64(dbit, tmp, 7);
83
+ tcg_gen_shri_i64(didx, tmp, 3);
84
+ if (HOST_BIG_ENDIAN) {
85
+ tcg_gen_xori_i64(didx, didx, 7);
86
+ }
87
+
88
+ /* Load the predicate word. */
89
+ tcg_gen_trunc_i64_ptr(ptr, didx);
90
+ tcg_gen_add_ptr(ptr, ptr, cpu_env);
91
+ tcg_gen_ld8u_i64(tmp, ptr, pred_full_reg_offset(s, a->pm));
92
+
93
+ /* Extract the predicate bit and replicate to MO_64. */
94
+ tcg_gen_shr_i64(tmp, tmp, dbit);
95
+ tcg_gen_andi_i64(tmp, tmp, 1);
96
+ tcg_gen_neg_i64(tmp, tmp);
97
+
98
+ /* Apply to either copy the source, or write zeros. */
99
+ tcg_gen_gvec_ands(MO_64, pred_full_reg_offset(s, a->pd),
100
+ pred_full_reg_offset(s, a->pn), tmp, pl, pl);
101
+
102
+ tcg_temp_free_i64(tmp);
103
+ tcg_temp_free_i64(dbit);
104
+ tcg_temp_free_i64(didx);
105
+ tcg_temp_free_ptr(ptr);
106
+ return true;
107
+}
156
--
108
--
157
2.20.1
109
2.25.1
158
159
diff view generated by jsdifflib
1
The function tc6393xb_draw_graphic32() is called in exactly one place,
1
From: Richard Henderson <richard.henderson@linaro.org>
2
so just inline the function body at its callsite. This allows us to
3
drop the template header entirely.
4
2
5
The code move includes a single added space after 'for' to fix
3
This is an SVE instruction that operates using the SVE vector
6
the coding style.
4
length but that it is present only if SME is implemented.
7
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-30-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20210215103215.4944-5-peter.maydell@linaro.org
12
---
10
---
13
hw/display/tc6393xb_template.h | 45 ----------------------------------
11
target/arm/helper-sve.h | 2 ++
14
hw/display/tc6393xb.c | 23 ++++++++++++++---
12
target/arm/sve.decode | 1 +
15
2 files changed, 19 insertions(+), 49 deletions(-)
13
target/arm/sve_helper.c | 16 ++++++++++++++++
16
delete mode 100644 hw/display/tc6393xb_template.h
14
target/arm/translate-sve.c | 2 ++
15
4 files changed, 21 insertions(+)
17
16
18
diff --git a/hw/display/tc6393xb_template.h b/hw/display/tc6393xb_template.h
17
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
19
deleted file mode 100644
20
index XXXXXXX..XXXXXXX
21
--- a/hw/display/tc6393xb_template.h
22
+++ /dev/null
23
@@ -XXX,XX +XXX,XX @@
24
-/*
25
- * Toshiba TC6393XB I/O Controller.
26
- * Found in Sharp Zaurus SL-6000 (tosa) or some
27
- * Toshiba e-Series PDAs.
28
- *
29
- * FB support code. Based on G364 fb emulator
30
- *
31
- * Copyright (c) 2007 Hervé Poussineau
32
- *
33
- * This program is free software; you can redistribute it and/or
34
- * modify it under the terms of the GNU General Public License as
35
- * published by the Free Software Foundation; either version 2 of
36
- * the License, or (at your option) any later version.
37
- *
38
- * This program is distributed in the hope that it will be useful,
39
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
40
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41
- * GNU General Public License for more details.
42
- *
43
- * You should have received a copy of the GNU General Public License along
44
- * with this program; if not, see <http://www.gnu.org/licenses/>.
45
- */
46
-
47
-static void tc6393xb_draw_graphic32(TC6393xbState *s)
48
-{
49
- DisplaySurface *surface = qemu_console_surface(s->con);
50
- int i;
51
- uint16_t *data_buffer;
52
- uint8_t *data_display;
53
-
54
- data_buffer = s->vram_ptr;
55
- data_display = surface_data(surface);
56
- for(i = 0; i < s->scr_height; i++) {
57
- int j;
58
- for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
59
- uint16_t color = *data_buffer;
60
- uint32_t dest_color = rgb_to_pixel32(
61
- ((color & 0xf800) * 0x108) >> 11,
62
- ((color & 0x7e0) * 0x41) >> 9,
63
- ((color & 0x1f) * 0x21) >> 2
64
- );
65
- *(uint32_t *)data_display = dest_color;
66
- }
67
- }
68
-}
69
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
70
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/display/tc6393xb.c
19
--- a/target/arm/helper-sve.h
72
+++ b/hw/display/tc6393xb.c
20
+++ b/target/arm/helper-sve.h
73
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_revh_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
74
(uint32_t) addr, value & 0xff);
22
75
}
23
DEF_HELPER_FLAGS_4(sve_revw_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
76
24
77
-#define BITS 32
25
+DEF_HELPER_FLAGS_4(sme_revd_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
78
-#include "tc6393xb_template.h"
79
-
80
static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
81
{
82
- tc6393xb_draw_graphic32(s);
83
+ DisplaySurface *surface = qemu_console_surface(s->con);
84
+ int i;
85
+ uint16_t *data_buffer;
86
+ uint8_t *data_display;
87
+
26
+
88
+ data_buffer = s->vram_ptr;
27
DEF_HELPER_FLAGS_4(sve_rbit_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
89
+ data_display = surface_data(surface);
28
DEF_HELPER_FLAGS_4(sve_rbit_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
90
+ for (i = 0; i < s->scr_height; i++) {
29
DEF_HELPER_FLAGS_4(sve_rbit_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
91
+ int j;
30
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
92
+ for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
31
index XXXXXXX..XXXXXXX 100644
93
+ uint16_t color = *data_buffer;
32
--- a/target/arm/sve.decode
94
+ uint32_t dest_color = rgb_to_pixel32(
33
+++ b/target/arm/sve.decode
95
+ ((color & 0xf800) * 0x108) >> 11,
34
@@ -XXX,XX +XXX,XX @@ REVB 00000101 .. 1001 00 100 ... ..... ..... @rd_pg_rn
96
+ ((color & 0x7e0) * 0x41) >> 9,
35
REVH 00000101 .. 1001 01 100 ... ..... ..... @rd_pg_rn
97
+ ((color & 0x1f) * 0x21) >> 2
36
REVW 00000101 .. 1001 10 100 ... ..... ..... @rd_pg_rn
98
+ );
37
RBIT 00000101 .. 1001 11 100 ... ..... ..... @rd_pg_rn
99
+ *(uint32_t *)data_display = dest_color;
38
+REVD 00000101 00 1011 10 100 ... ..... ..... @rd_pg_rn_e0
39
40
# SVE vector splice (predicated, destructive)
41
SPLICE 00000101 .. 101 100 100 ... ..... ..... @rdn_pg_rm
42
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/sve_helper.c
45
+++ b/target/arm/sve_helper.c
46
@@ -XXX,XX +XXX,XX @@ DO_ZPZ_D(sve_revh_d, uint64_t, hswap64)
47
48
DO_ZPZ_D(sve_revw_d, uint64_t, wswap64)
49
50
+void HELPER(sme_revd_q)(void *vd, void *vn, void *vg, uint32_t desc)
51
+{
52
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
53
+ uint64_t *d = vd, *n = vn;
54
+ uint8_t *pg = vg;
55
+
56
+ for (i = 0; i < opr_sz; i += 2) {
57
+ if (pg[H1(i)] & 1) {
58
+ uint64_t n0 = n[i + 0];
59
+ uint64_t n1 = n[i + 1];
60
+ d[i + 0] = n1;
61
+ d[i + 1] = n0;
100
+ }
62
+ }
101
+ }
63
+ }
102
dpy_gfx_update_full(s->con);
64
+}
103
}
65
+
66
DO_ZPZ(sve_rbit_b, uint8_t, H1, revbit8)
67
DO_ZPZ(sve_rbit_h, uint16_t, H1_2, revbit16)
68
DO_ZPZ(sve_rbit_s, uint32_t, H1_4, revbit32)
69
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/translate-sve.c
72
+++ b/target/arm/translate-sve.c
73
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(REVH, aa64_sve, gen_gvec_ool_arg_zpz, revh_fns[a->esz], a, 0)
74
TRANS_FEAT(REVW, aa64_sve, gen_gvec_ool_arg_zpz,
75
a->esz == 3 ? gen_helper_sve_revw_d : NULL, a, 0)
76
77
+TRANS_FEAT(REVD, aa64_sme, gen_gvec_ool_arg_zpz, gen_helper_sme_revd_q, a, 0)
78
+
79
TRANS_FEAT(SPLICE, aa64_sve, gen_gvec_ool_arg_zpzz,
80
gen_helper_sve_splice, a, a->esz)
104
81
105
--
82
--
106
2.20.1
83
2.25.1
107
108
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Always perform one call instead of two for 16-byte operands.
3
This is an SVE instruction that operates using the SVE vector
4
Use byte loads/stores directly into the vector register file
4
length but that it is present only if SME is implemented.
5
instead of extractions and deposits to a 64-bit local variable.
6
5
7
In order to easily receive pointers into the vector register file,
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
convert the helper to the gvec out-of-line signature. Move the
9
helper into vec_helper.c, where it can make use of H1 and clear_tail.
10
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20220708151540.18136-31-richard.henderson@linaro.org
13
Tested-by: Alex Bennée <alex.bennee@linaro.org>
14
Message-id: 20210224230532.276878-1-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
10
---
17
target/arm/helper-a64.h | 2 +-
11
target/arm/helper.h | 18 +++++++
18
target/arm/helper-a64.c | 32 ---------------------
12
target/arm/sve.decode | 5 ++
19
target/arm/translate-a64.c | 58 +++++---------------------------------
13
target/arm/translate-sve.c | 102 +++++++++++++++++++++++++++++++++++++
20
target/arm/vec_helper.c | 48 +++++++++++++++++++++++++++++++
14
target/arm/vec_helper.c | 24 +++++++++
21
4 files changed, 56 insertions(+), 84 deletions(-)
15
4 files changed, 149 insertions(+)
22
16
23
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
24
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper-a64.h
19
--- a/target/arm/helper.h
26
+++ b/target/arm/helper-a64.h
20
+++ b/target/arm/helper.h
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr)
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(gvec_bfmlal, TCG_CALL_NO_RWG,
28
DEF_HELPER_3(vfp_cmpes_a64, i64, f32, f32, ptr)
22
DEF_HELPER_FLAGS_6(gvec_bfmlal_idx, TCG_CALL_NO_RWG,
29
DEF_HELPER_3(vfp_cmpd_a64, i64, f64, f64, ptr)
23
void, ptr, ptr, ptr, ptr, ptr, i32)
30
DEF_HELPER_3(vfp_cmped_a64, i64, f64, f64, ptr)
24
31
-DEF_HELPER_FLAGS_5(simd_tbl, TCG_CALL_NO_RWG_SE, i64, env, i64, i64, i32, i32)
25
+DEF_HELPER_FLAGS_5(gvec_sclamp_b, TCG_CALL_NO_RWG,
32
+DEF_HELPER_FLAGS_4(simd_tblx, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
+ void, ptr, ptr, ptr, ptr, i32)
33
DEF_HELPER_FLAGS_3(vfp_mulxs, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
27
+DEF_HELPER_FLAGS_5(gvec_sclamp_h, TCG_CALL_NO_RWG,
34
DEF_HELPER_FLAGS_3(vfp_mulxd, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
28
+ void, ptr, ptr, ptr, ptr, i32)
35
DEF_HELPER_FLAGS_3(neon_ceq_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
29
+DEF_HELPER_FLAGS_5(gvec_sclamp_s, TCG_CALL_NO_RWG,
36
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
30
+ void, ptr, ptr, ptr, ptr, i32)
37
index XXXXXXX..XXXXXXX 100644
31
+DEF_HELPER_FLAGS_5(gvec_sclamp_d, TCG_CALL_NO_RWG,
38
--- a/target/arm/helper-a64.c
32
+ void, ptr, ptr, ptr, ptr, i32)
39
+++ b/target/arm/helper-a64.c
33
+
40
@@ -XXX,XX +XXX,XX @@ float64 HELPER(vfp_mulxd)(float64 a, float64 b, void *fpstp)
34
+DEF_HELPER_FLAGS_5(gvec_uclamp_b, TCG_CALL_NO_RWG,
41
return float64_mul(a, b, fpst);
35
+ void, ptr, ptr, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_5(gvec_uclamp_h, TCG_CALL_NO_RWG,
37
+ void, ptr, ptr, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_5(gvec_uclamp_s, TCG_CALL_NO_RWG,
39
+ void, ptr, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_5(gvec_uclamp_d, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, ptr, i32)
42
+
43
#ifdef TARGET_AARCH64
44
#include "helper-a64.h"
45
#include "helper-sve.h"
46
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/sve.decode
49
+++ b/target/arm/sve.decode
50
@@ -XXX,XX +XXX,XX @@ PSEL 00100101 .. 1 100 .. 01 .... 0 .... 0 .... \
51
@psel esz=2 imm=%psel_imm_s
52
PSEL 00100101 .1 1 000 .. 01 .... 0 .... 0 .... \
53
@psel esz=3 imm=%psel_imm_d
54
+
55
+### SVE clamp
56
+
57
+SCLAMP 01000100 .. 0 ..... 110000 ..... ..... @rda_rn_rm
58
+UCLAMP 01000100 .. 0 ..... 110001 ..... ..... @rda_rn_rm
59
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/arm/translate-sve.c
62
+++ b/target/arm/translate-sve.c
63
@@ -XXX,XX +XXX,XX @@ static bool trans_PSEL(DisasContext *s, arg_psel *a)
64
tcg_temp_free_ptr(ptr);
65
return true;
42
}
66
}
43
67
+
44
-uint64_t HELPER(simd_tbl)(CPUARMState *env, uint64_t result, uint64_t indices,
68
+static void gen_sclamp_i32(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, TCGv_i32 a)
45
- uint32_t rn, uint32_t numregs)
69
+{
46
-{
70
+ tcg_gen_smax_i32(d, a, n);
47
- /* Helper function for SIMD TBL and TBX. We have to do the table
71
+ tcg_gen_smin_i32(d, d, m);
48
- * lookup part for the 64 bits worth of indices we're passed in.
72
+}
49
- * result is the initial results vector (either zeroes for TBL
73
+
50
- * or some guest values for TBX), rn the register number where
74
+static void gen_sclamp_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 a)
51
- * the table starts, and numregs the number of registers in the table.
75
+{
52
- * We return the results of the lookups.
76
+ tcg_gen_smax_i64(d, a, n);
53
- */
77
+ tcg_gen_smin_i64(d, d, m);
54
- int shift;
78
+}
55
-
79
+
56
- for (shift = 0; shift < 64; shift += 8) {
80
+static void gen_sclamp_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
57
- int index = extract64(indices, shift, 8);
81
+ TCGv_vec m, TCGv_vec a)
58
- if (index < 16 * numregs) {
82
+{
59
- /* Convert index (a byte offset into the virtual table
83
+ tcg_gen_smax_vec(vece, d, a, n);
60
- * which is a series of 128-bit vectors concatenated)
84
+ tcg_gen_smin_vec(vece, d, d, m);
61
- * into the correct register element plus a bit offset
85
+}
62
- * into that element, bearing in mind that the table
86
+
63
- * can wrap around from V31 to V0.
87
+static void gen_sclamp(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
64
- */
88
+ uint32_t a, uint32_t oprsz, uint32_t maxsz)
65
- int elt = (rn * 2 + (index >> 3)) % 64;
89
+{
66
- int bitidx = (index & 7) * 8;
90
+ static const TCGOpcode vecop[] = {
67
- uint64_t *q = aa64_vfp_qreg(env, elt >> 1);
91
+ INDEX_op_smin_vec, INDEX_op_smax_vec, 0
68
- uint64_t val = extract64(q[elt & 1], bitidx, 8);
92
+ };
69
-
93
+ static const GVecGen4 ops[4] = {
70
- result = deposit64(result, shift, 8, val);
94
+ { .fniv = gen_sclamp_vec,
71
- }
95
+ .fno = gen_helper_gvec_sclamp_b,
72
- }
96
+ .opt_opc = vecop,
73
- return result;
97
+ .vece = MO_8 },
74
-}
98
+ { .fniv = gen_sclamp_vec,
75
-
99
+ .fno = gen_helper_gvec_sclamp_h,
76
/* 64bit/double versions of the neon float compare functions */
100
+ .opt_opc = vecop,
77
uint64_t HELPER(neon_ceq_f64)(float64 a, float64 b, void *fpstp)
101
+ .vece = MO_16 },
78
{
102
+ { .fni4 = gen_sclamp_i32,
79
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
103
+ .fniv = gen_sclamp_vec,
80
index XXXXXXX..XXXXXXX 100644
104
+ .fno = gen_helper_gvec_sclamp_s,
81
--- a/target/arm/translate-a64.c
105
+ .opt_opc = vecop,
82
+++ b/target/arm/translate-a64.c
106
+ .vece = MO_32 },
83
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
107
+ { .fni8 = gen_sclamp_i64,
84
int rm = extract32(insn, 16, 5);
108
+ .fniv = gen_sclamp_vec,
85
int rn = extract32(insn, 5, 5);
109
+ .fno = gen_helper_gvec_sclamp_d,
86
int rd = extract32(insn, 0, 5);
110
+ .opt_opc = vecop,
87
- int is_tblx = extract32(insn, 12, 1);
111
+ .vece = MO_64,
88
- int len = extract32(insn, 13, 2);
112
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64 }
89
- TCGv_i64 tcg_resl, tcg_resh, tcg_idx;
113
+ };
90
- TCGv_i32 tcg_regno, tcg_numregs;
114
+ tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &ops[vece]);
91
+ int is_tbx = extract32(insn, 12, 1);
115
+}
92
+ int len = (extract32(insn, 13, 2) + 1) * 16;
116
+
93
117
+TRANS_FEAT(SCLAMP, aa64_sme, gen_gvec_fn_arg_zzzz, gen_sclamp, a)
94
if (op2 != 0) {
118
+
95
unallocated_encoding(s);
119
+static void gen_uclamp_i32(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, TCGv_i32 a)
96
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
120
+{
97
return;
121
+ tcg_gen_umax_i32(d, a, n);
98
}
122
+ tcg_gen_umin_i32(d, d, m);
99
123
+}
100
- /* This does a table lookup: for every byte element in the input
124
+
101
- * we index into a table formed from up to four vector registers,
125
+static void gen_uclamp_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 a)
102
- * and then the output is the result of the lookups. Our helper
126
+{
103
- * function does the lookup operation for a single 64 bit part of
127
+ tcg_gen_umax_i64(d, a, n);
104
- * the input.
128
+ tcg_gen_umin_i64(d, d, m);
105
- */
129
+}
106
- tcg_resl = tcg_temp_new_i64();
130
+
107
- tcg_resh = NULL;
131
+static void gen_uclamp_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
108
-
132
+ TCGv_vec m, TCGv_vec a)
109
- if (is_tblx) {
133
+{
110
- read_vec_element(s, tcg_resl, rd, 0, MO_64);
134
+ tcg_gen_umax_vec(vece, d, a, n);
111
- } else {
135
+ tcg_gen_umin_vec(vece, d, d, m);
112
- tcg_gen_movi_i64(tcg_resl, 0);
136
+}
113
- }
137
+
114
-
138
+static void gen_uclamp(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
115
- if (is_q) {
139
+ uint32_t a, uint32_t oprsz, uint32_t maxsz)
116
- tcg_resh = tcg_temp_new_i64();
140
+{
117
- if (is_tblx) {
141
+ static const TCGOpcode vecop[] = {
118
- read_vec_element(s, tcg_resh, rd, 1, MO_64);
142
+ INDEX_op_umin_vec, INDEX_op_umax_vec, 0
119
- } else {
143
+ };
120
- tcg_gen_movi_i64(tcg_resh, 0);
144
+ static const GVecGen4 ops[4] = {
121
- }
145
+ { .fniv = gen_uclamp_vec,
122
- }
146
+ .fno = gen_helper_gvec_uclamp_b,
123
-
147
+ .opt_opc = vecop,
124
- tcg_idx = tcg_temp_new_i64();
148
+ .vece = MO_8 },
125
- tcg_regno = tcg_const_i32(rn);
149
+ { .fniv = gen_uclamp_vec,
126
- tcg_numregs = tcg_const_i32(len + 1);
150
+ .fno = gen_helper_gvec_uclamp_h,
127
- read_vec_element(s, tcg_idx, rm, 0, MO_64);
151
+ .opt_opc = vecop,
128
- gen_helper_simd_tbl(tcg_resl, cpu_env, tcg_resl, tcg_idx,
152
+ .vece = MO_16 },
129
- tcg_regno, tcg_numregs);
153
+ { .fni4 = gen_uclamp_i32,
130
- if (is_q) {
154
+ .fniv = gen_uclamp_vec,
131
- read_vec_element(s, tcg_idx, rm, 1, MO_64);
155
+ .fno = gen_helper_gvec_uclamp_s,
132
- gen_helper_simd_tbl(tcg_resh, cpu_env, tcg_resh, tcg_idx,
156
+ .opt_opc = vecop,
133
- tcg_regno, tcg_numregs);
157
+ .vece = MO_32 },
134
- }
158
+ { .fni8 = gen_uclamp_i64,
135
- tcg_temp_free_i64(tcg_idx);
159
+ .fniv = gen_uclamp_vec,
136
- tcg_temp_free_i32(tcg_regno);
160
+ .fno = gen_helper_gvec_uclamp_d,
137
- tcg_temp_free_i32(tcg_numregs);
161
+ .opt_opc = vecop,
138
-
162
+ .vece = MO_64,
139
- write_vec_element(s, tcg_resl, rd, 0, MO_64);
163
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64 }
140
- tcg_temp_free_i64(tcg_resl);
164
+ };
141
-
165
+ tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &ops[vece]);
142
- if (is_q) {
166
+}
143
- write_vec_element(s, tcg_resh, rd, 1, MO_64);
167
+
144
- tcg_temp_free_i64(tcg_resh);
168
+TRANS_FEAT(UCLAMP, aa64_sme, gen_gvec_fn_arg_zzzz, gen_uclamp, a)
145
- }
146
- clear_vec_high(s, is_q, rd);
147
+ tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, rd),
148
+ vec_full_reg_offset(s, rm), cpu_env,
149
+ is_q ? 16 : 8, vec_full_reg_size(s),
150
+ (len << 6) | (is_tbx << 5) | rn,
151
+ gen_helper_simd_tblx);
152
}
153
154
/* ZIP/UZP/TRN
155
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
169
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
156
index XXXXXXX..XXXXXXX 100644
170
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/vec_helper.c
171
--- a/target/arm/vec_helper.c
158
+++ b/target/arm/vec_helper.c
172
+++ b/target/arm/vec_helper.c
159
@@ -XXX,XX +XXX,XX @@ DO_VRINT_RMODE(gvec_vrint_rm_h, helper_rinth, uint16_t)
173
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_bfmlal_idx)(void *vd, void *vn, void *vm,
160
DO_VRINT_RMODE(gvec_vrint_rm_s, helper_rints, uint32_t)
174
}
161
175
clear_tail(d, opr_sz, simd_maxsz(desc));
162
#undef DO_VRINT_RMODE
176
}
163
+
177
+
164
+#ifdef TARGET_AARCH64
178
+#define DO_CLAMP(NAME, TYPE) \
165
+void HELPER(simd_tblx)(void *vd, void *vm, void *venv, uint32_t desc)
179
+void HELPER(NAME)(void *d, void *n, void *m, void *a, uint32_t desc) \
166
+{
180
+{ \
167
+ const uint8_t *indices = vm;
181
+ intptr_t i, opr_sz = simd_oprsz(desc); \
168
+ CPUARMState *env = venv;
182
+ for (i = 0; i < opr_sz; i += sizeof(TYPE)) { \
169
+ size_t oprsz = simd_oprsz(desc);
183
+ TYPE aa = *(TYPE *)(a + i); \
170
+ uint32_t rn = extract32(desc, SIMD_DATA_SHIFT, 5);
184
+ TYPE nn = *(TYPE *)(n + i); \
171
+ bool is_tbx = extract32(desc, SIMD_DATA_SHIFT + 5, 1);
185
+ TYPE mm = *(TYPE *)(m + i); \
172
+ uint32_t table_len = desc >> (SIMD_DATA_SHIFT + 6);
186
+ TYPE dd = MIN(MAX(aa, nn), mm); \
173
+ union {
187
+ *(TYPE *)(d + i) = dd; \
174
+ uint8_t b[16];
188
+ } \
175
+ uint64_t d[2];
189
+ clear_tail(d, opr_sz, simd_maxsz(desc)); \
176
+ } result;
190
+}
177
+
191
+
178
+ /*
192
+DO_CLAMP(gvec_sclamp_b, int8_t)
179
+ * We must construct the final result in a temp, lest the output
193
+DO_CLAMP(gvec_sclamp_h, int16_t)
180
+ * overlaps the input table. For TBL, begin with zero; for TBX,
194
+DO_CLAMP(gvec_sclamp_s, int32_t)
181
+ * begin with the original register contents. Note that we always
195
+DO_CLAMP(gvec_sclamp_d, int64_t)
182
+ * copy 16 bytes here to avoid an extra branch; clearing the high
196
+
183
+ * bits of the register for oprsz == 8 is handled below.
197
+DO_CLAMP(gvec_uclamp_b, uint8_t)
184
+ */
198
+DO_CLAMP(gvec_uclamp_h, uint16_t)
185
+ if (is_tbx) {
199
+DO_CLAMP(gvec_uclamp_s, uint32_t)
186
+ memcpy(&result, vd, 16);
200
+DO_CLAMP(gvec_uclamp_d, uint64_t)
187
+ } else {
188
+ memset(&result, 0, 16);
189
+ }
190
+
191
+ for (size_t i = 0; i < oprsz; ++i) {
192
+ uint32_t index = indices[H1(i)];
193
+
194
+ if (index < table_len) {
195
+ /*
196
+ * Convert index (a byte offset into the virtual table
197
+ * which is a series of 128-bit vectors concatenated)
198
+ * into the correct register element, bearing in mind
199
+ * that the table can wrap around from V31 to V0.
200
+ */
201
+ const uint8_t *table = (const uint8_t *)
202
+ aa64_vfp_qreg(env, (rn + (index >> 4)) % 32);
203
+ result.b[H1(i)] = table[H1(index % 16)];
204
+ }
205
+ }
206
+
207
+ memcpy(vd, &result, 16);
208
+ clear_tail(vd, oprsz, simd_maxsz(desc));
209
+}
210
+#endif
211
--
201
--
212
2.20.1
202
2.25.1
213
214
diff view generated by jsdifflib
1
From: Peter Collingbourne <pcc@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Section D6.7 of the ARM ARM states:
3
We can handle both exception entry and exception return by
4
hooking into aarch64_sve_change_el.
4
5
5
For the purpose of determining Tag Check Fault handling, unprivileged
6
load and store instructions are treated as if executed at EL0 when
7
executed at either:
8
- EL1, when the Effective value of PSTATE.UAO is 0.
9
- EL2, when both the Effective value of HCR_EL2.{E2H, TGE} is {1, 1}
10
and the Effective value of PSTATE.UAO is 0.
11
12
ARM has confirmed a defect in the pseudocode function
13
AArch64.TagCheckFault that makes it inconsistent with the above
14
wording. The remedy is to adjust references to PSTATE.EL in that
15
function to instead refer to AArch64.AccessUsesEL(acctype), so
16
that unprivileged instructions use SCTLR_EL1.TCF0 and TFSRE0_EL1.
17
The exception type for synchronous tag check faults remains unchanged.
18
19
This patch implements the described change by partially reverting
20
commits 50244cc76abc and cc97b0019bb5.
21
22
Signed-off-by: Peter Collingbourne <pcc@google.com>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Message-id: 20210219201820.2672077-1-pcc@google.com
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-32-richard.henderson@linaro.org
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
---
10
---
28
target/arm/helper.c | 2 +-
11
target/arm/helper.c | 15 +++++++++++++--
29
target/arm/mte_helper.c | 13 +++++++++----
12
1 file changed, 13 insertions(+), 2 deletions(-)
30
2 files changed, 10 insertions(+), 5 deletions(-)
31
13
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
33
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.c
16
--- a/target/arm/helper.c
35
+++ b/target/arm/helper.c
17
+++ b/target/arm/helper.c
36
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
18
@@ -XXX,XX +XXX,XX @@ void aarch64_sve_change_el(CPUARMState *env, int old_el,
37
if (FIELD_EX32(flags, TBFLAG_A64, UNPRIV)
19
return;
38
&& tbid
39
&& !(env->pstate & PSTATE_TCO)
40
- && (sctlr & SCTLR_TCF)
41
+ && (sctlr & SCTLR_TCF0)
42
&& allocation_tag_access_enabled(env, 0, sctlr)) {
43
flags = FIELD_DP32(flags, TBFLAG_A64, MTE0_ACTIVE, 1);
44
}
45
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/mte_helper.c
48
+++ b/target/arm/mte_helper.c
49
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
50
reg_el = regime_el(env, arm_mmu_idx);
51
sctlr = env->cp15.sctlr_el[reg_el];
52
53
- el = arm_current_el(env);
54
- if (el == 0) {
55
+ switch (arm_mmu_idx) {
56
+ case ARMMMUIdx_E10_0:
57
+ case ARMMMUIdx_E20_0:
58
+ el = 0;
59
tcf = extract64(sctlr, 38, 2);
60
- } else {
61
+ break;
62
+ default:
63
+ el = reg_el;
64
tcf = extract64(sctlr, 40, 2);
65
}
20
}
66
21
67
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
22
+ old_a64 = old_el ? arm_el_is_aa64(env, old_el) : el0_a64;
68
env->exception.vaddress = dirty_ptr;
23
+ new_a64 = new_el ? arm_el_is_aa64(env, new_el) : el0_a64;
69
24
+
70
is_write = FIELD_EX32(desc, MTEDESC, WRITE);
25
+ /*
71
- syn = syn_data_abort_no_iss(el != 0, 0, 0, 0, 0, is_write, 0x11);
26
+ * Both AArch64.TakeException and AArch64.ExceptionReturn
72
+ syn = syn_data_abort_no_iss(arm_current_el(env) != 0, 0, 0, 0, 0,
27
+ * invoke ResetSVEState when taking an exception from, or
73
+ is_write, 0x11);
28
+ * returning to, AArch32 state when PSTATE.SM is enabled.
74
raise_exception(env, EXCP_DATA_ABORT, syn, exception_target_el(env));
29
+ */
75
/* noreturn, but fall through to the assert anyway */
30
+ if (old_a64 != new_a64 && FIELD_EX64(env->svcr, SVCR, SM)) {
31
+ arm_reset_sve_state(env);
32
+ return;
33
+ }
34
+
35
/*
36
* DDI0584A.d sec 3.2: "If SVE instructions are disabled or trapped
37
* at ELx, or not available because the EL is in AArch32 state, then
38
@@ -XXX,XX +XXX,XX @@ void aarch64_sve_change_el(CPUARMState *env, int old_el,
39
* we already have the correct register contents when encountering the
40
* vq0->vq0 transition between EL0->EL1.
41
*/
42
- old_a64 = old_el ? arm_el_is_aa64(env, old_el) : el0_a64;
43
old_len = (old_a64 && !sve_exception_el(env, old_el)
44
? sve_vqm1_for_el(env, old_el) : 0);
45
- new_a64 = new_el ? arm_el_is_aa64(env, new_el) : el0_a64;
46
new_len = (new_a64 && !sve_exception_el(env, new_el)
47
? sve_vqm1_for_el(env, new_el) : 0);
76
48
77
--
49
--
78
2.20.1
50
2.25.1
79
80
diff view generated by jsdifflib
1
From: Rebecca Cran <rebecca@nuviainc.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Set ID_AA64PFR1_EL1.SSBS to 2 and ID_PFR2.SSBS to 1.
3
Note that SME remains effectively disabled for user-only,
4
because we do not yet set CPACR_EL1.SMEN. This needs to
5
wait until the kernel ABI is implemented.
4
6
5
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210216224543.16142-3-rebecca@nuviainc.com
9
Message-id: 20220708151540.18136-33-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
target/arm/cpu64.c | 5 +++++
12
docs/system/arm/emulation.rst | 4 ++++
11
1 file changed, 5 insertions(+)
13
target/arm/cpu64.c | 11 +++++++++++
14
2 files changed, 15 insertions(+)
12
15
16
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
17
index XXXXXXX..XXXXXXX 100644
18
--- a/docs/system/arm/emulation.rst
19
+++ b/docs/system/arm/emulation.rst
20
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
21
- FEAT_SHA512 (Advanced SIMD SHA512 instructions)
22
- FEAT_SM3 (Advanced SIMD SM3 instructions)
23
- FEAT_SM4 (Advanced SIMD SM4 instructions)
24
+- FEAT_SME (Scalable Matrix Extension)
25
+- FEAT_SME_FA64 (Full A64 instruction set in Streaming SVE mode)
26
+- FEAT_SME_F64F64 (Double-precision floating-point outer product instructions)
27
+- FEAT_SME_I16I64 (16-bit to 64-bit integer widening outer product instructions)
28
- FEAT_SPECRES (Speculation restriction instructions)
29
- FEAT_SSBS (Speculative Store Bypass Safe)
30
- FEAT_TLBIOS (TLB invalidate instructions in Outer Shareable domain)
13
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
31
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
14
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu64.c
33
--- a/target/arm/cpu64.c
16
+++ b/target/arm/cpu64.c
34
+++ b/target/arm/cpu64.c
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
35
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
18
36
*/
19
t = cpu->isar.id_aa64pfr1;
37
t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3); /* FEAT_MTE3 */
20
t = FIELD_DP64(t, ID_AA64PFR1, BT, 1);
38
t = FIELD_DP64(t, ID_AA64PFR1, RAS_FRAC, 0); /* FEAT_RASv1p1 + FEAT_DoubleFault */
21
+ t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2);
39
+ t = FIELD_DP64(t, ID_AA64PFR1, SME, 1); /* FEAT_SME */
22
/*
40
t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0); /* FEAT_CSV2_2 */
23
* Begin with full support for MTE. This will be downgraded to MTE=0
41
cpu->isar.id_aa64pfr1 = t;
24
* during realize if the board provides no tag memory, much like
42
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
43
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
26
u = FIELD_DP32(u, ID_PFR0, DIT, 1);
44
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* FEAT_PMUv3p4 */
27
cpu->isar.id_pfr0 = u;
45
cpu->isar.id_aa64dfr0 = t;
28
46
29
+ u = cpu->isar.id_pfr2;
47
+ t = cpu->isar.id_aa64smfr0;
30
+ u = FIELD_DP32(u, ID_PFR2, SSBS, 1);
48
+ t = FIELD_DP64(t, ID_AA64SMFR0, F32F32, 1); /* FEAT_SME */
31
+ cpu->isar.id_pfr2 = u;
49
+ t = FIELD_DP64(t, ID_AA64SMFR0, B16F32, 1); /* FEAT_SME */
50
+ t = FIELD_DP64(t, ID_AA64SMFR0, F16F32, 1); /* FEAT_SME */
51
+ t = FIELD_DP64(t, ID_AA64SMFR0, I8I32, 0xf); /* FEAT_SME */
52
+ t = FIELD_DP64(t, ID_AA64SMFR0, F64F64, 1); /* FEAT_SME_F64F64 */
53
+ t = FIELD_DP64(t, ID_AA64SMFR0, I16I64, 0xf); /* FEAT_SME_I16I64 */
54
+ t = FIELD_DP64(t, ID_AA64SMFR0, FA64, 1); /* FEAT_SME_FA64 */
55
+ cpu->isar.id_aa64smfr0 = t;
32
+
56
+
33
u = cpu->isar.id_mmfr3;
57
/* Replicate the same data to the 32-bit id registers. */
34
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
58
aa32_max_features(cpu);
35
cpu->isar.id_mmfr3 = u;
59
36
--
60
--
37
2.20.1
61
2.25.1
38
39
diff view generated by jsdifflib
1
The macro draw_line_func is used only once; just expand it.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220708151540.18136-34-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20210215103215.4944-10-peter.maydell@linaro.org
7
---
7
---
8
hw/display/omap_lcdc.c | 4 +---
8
linux-user/aarch64/target_cpu.h | 5 ++++-
9
1 file changed, 1 insertion(+), 3 deletions(-)
9
1 file changed, 4 insertions(+), 1 deletion(-)
10
10
11
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
11
diff --git a/linux-user/aarch64/target_cpu.h b/linux-user/aarch64/target_cpu.h
12
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/display/omap_lcdc.c
13
--- a/linux-user/aarch64/target_cpu.h
14
+++ b/hw/display/omap_lcdc.c
14
+++ b/linux-user/aarch64/target_cpu.h
15
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
15
@@ -XXX,XX +XXX,XX @@ static inline void cpu_clone_regs_parent(CPUARMState *env, unsigned flags)
16
qemu_irq_lower(s->irq);
16
17
static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls)
18
{
19
- /* Note that AArch64 Linux keeps the TLS pointer in TPIDR; this is
20
+ /*
21
+ * Note that AArch64 Linux keeps the TLS pointer in TPIDR; this is
22
* different from AArch32 Linux, which uses TPIDRRO.
23
*/
24
env->cp15.tpidr_el[0] = newtls;
25
+ /* TPIDR2_EL0 is cleared with CLONE_SETTLS. */
26
+ env->cp15.tpidr2_el0 = 0;
17
}
27
}
18
28
19
-#define draw_line_func drawfn
29
static inline abi_ulong get_sp_from_cpustate(CPUARMState *state)
20
-
21
/*
22
* 2-bit colour
23
*/
24
@@ -XXX,XX +XXX,XX @@ static void omap_update_display(void *opaque)
25
{
26
struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
27
DisplaySurface *surface;
28
- draw_line_func draw_line;
29
+ drawfn draw_line;
30
int size, height, first, last;
31
int width, linesize, step, bpp, frame_offset;
32
hwaddr frame_base;
33
--
30
--
34
2.20.1
31
2.25.1
35
36
diff view generated by jsdifflib
1
Set the FPGAIO num-leds and have-switches properties explicitly
1
From: Richard Henderson <richard.henderson@linaro.org>
2
per-board, rather than relying on the defaults. The AN505 and AN521
3
both have the same settings as the default values, but the AN524 will
4
be different.
5
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220708151540.18136-35-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210215115138.20465-8-peter.maydell@linaro.org
10
---
7
---
11
hw/arm/mps2-tz.c | 9 +++++++++
8
linux-user/aarch64/cpu_loop.c | 9 +++++++++
12
1 file changed, 9 insertions(+)
9
1 file changed, 9 insertions(+)
13
10
14
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
11
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/mps2-tz.c
13
--- a/linux-user/aarch64/cpu_loop.c
17
+++ b/hw/arm/mps2-tz.c
14
+++ b/linux-user/aarch64/cpu_loop.c
18
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
15
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
19
uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
16
20
uint32_t len_oscclk;
17
switch (trapnr) {
21
const uint32_t *oscclk;
18
case EXCP_SWI:
22
+ uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
19
+ /*
23
+ bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
20
+ * On syscall, PSTATE.ZA is preserved, along with the ZA matrix.
24
const char *armsse_type;
21
+ * PSTATE.SM is cleared, per SMSTOP, which does ResetSVEState.
25
};
22
+ */
26
23
+ if (FIELD_EX64(env->svcr, SVCR, SM)) {
27
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
24
+ env->svcr = FIELD_DP64(env->svcr, SVCR, SM, 0);
28
const char *name, hwaddr size)
25
+ arm_rebuild_hflags(env);
29
{
26
+ arm_reset_sve_state(env);
30
MPS2FPGAIO *fpgaio = opaque;
27
+ }
31
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
28
ret = do_syscall(env,
32
29
env->xregs[8],
33
object_initialize_child(OBJECT(mms), "fpgaio", fpgaio, TYPE_MPS2_FPGAIO);
30
env->xregs[0],
34
+ qdev_prop_set_uint32(DEVICE(fpgaio), "num-leds", mmc->fpgaio_num_leds);
35
+ qdev_prop_set_bit(DEVICE(fpgaio), "has-switches", mmc->fpgaio_has_switches);
36
sysbus_realize(SYS_BUS_DEVICE(fpgaio), &error_fatal);
37
return sysbus_mmio_get_region(SYS_BUS_DEVICE(fpgaio), 0);
38
}
39
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
40
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
41
mmc->oscclk = an505_oscclk;
42
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
43
+ mmc->fpgaio_num_leds = 2;
44
+ mmc->fpgaio_has_switches = false;
45
mmc->armsse_type = TYPE_IOTKIT;
46
}
47
48
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
49
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
50
mmc->oscclk = an505_oscclk; /* AN521 is the same as AN505 here */
51
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
52
+ mmc->fpgaio_num_leds = 2;
53
+ mmc->fpgaio_has_switches = false;
54
mmc->armsse_type = TYPE_SSE200;
55
}
56
57
--
31
--
58
2.20.1
32
2.25.1
59
60
diff view generated by jsdifflib
1
From: schspa <schspa@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
At the moment the following QEMU command line triggers an assertion
3
Make sure to zero the currently reserved fields.
4
failure On xlnx-versal SOC:
5
qemu-system-aarch64 \
6
-machine xlnx-versal-virt -nographic -smp 2 -m 128 \
7
-fsdev local,id=shareid,path=${HOME}/work,security_model=none \
8
-device virtio-9p-device,fsdev=shareid,mount_tag=share \
9
-fsdev local,id=shareid1,path=${HOME}/Music,security_model=none \
10
-device virtio-9p-device,fsdev=shareid1,mount_tag=share1
11
4
12
qemu-system-aarch64: ../migration/savevm.c:860:
13
vmstate_register_with_alias_id:
14
Assertion `!se->compat || se->instance_id == 0' failed.
15
16
This problem was fixed on arm virt platform in commit f58b39d2d5b
17
("virtio-mmio: format transport base address in BusClass.get_dev_path")
18
19
It works perfectly on arm virt platform. but there is still there on
20
xlnx-versal SOC.
21
22
The main difference between arm virt and xlnx-versal is they use
23
different way to create virtio-mmio qdev. on arm virt, it calls
24
sysbus_create_simple("virtio-mmio", base, pic[irq]); which will call
25
sysbus_mmio_map internally and assign base address to subsys device
26
mmio correctly. but xlnx-versal's implements won't do this.
27
28
However, xlnx-versal can't switch to sysbus_create_simple() to create
29
virtio-mmio device. It's because xlnx-versal's cpu use
30
VersalVirt.soc.fpd.apu.mr as it's memory. which is subregion of
31
system_memory. sysbus_create_simple will add virtio to system_memory,
32
which can't be accessed by cpu.
33
34
Besides, xlnx-versal can't add sysbus_mmio_map api call too, because
35
this will add memory region to system_memory, and it can't be added
36
to VersalVirt.soc.fpd.apu.mr again.
37
38
We can solve this by assign correct base address offset on dev_path.
39
40
This path was test on aarch64 virt & xlnx-versal platform.
41
42
Signed-off-by: schspa <schspa@gmail.com>
43
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220708151540.18136-36-richard.henderson@linaro.org
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
45
---
9
---
46
hw/virtio/virtio-mmio.c | 13 +++++++------
10
linux-user/aarch64/signal.c | 9 ++++++++-
47
1 file changed, 7 insertions(+), 6 deletions(-)
11
1 file changed, 8 insertions(+), 1 deletion(-)
48
12
49
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
13
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
50
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/virtio/virtio-mmio.c
15
--- a/linux-user/aarch64/signal.c
52
+++ b/hw/virtio/virtio-mmio.c
16
+++ b/linux-user/aarch64/signal.c
53
@@ -XXX,XX +XXX,XX @@ static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
17
@@ -XXX,XX +XXX,XX @@ struct target_extra_context {
54
BusState *virtio_mmio_bus;
18
struct target_sve_context {
55
VirtIOMMIOProxy *virtio_mmio_proxy;
19
struct target_aarch64_ctx head;
56
char *proxy_path;
20
uint16_t vl;
57
- SysBusDevice *proxy_sbd;
21
- uint16_t reserved[3];
58
char *path;
22
+ uint16_t flags;
59
+ MemoryRegionSection section;
23
+ uint16_t reserved[2];
60
24
/* The actual SVE data immediately follows. It is laid out
61
virtio_mmio_bus = qdev_get_parent_bus(dev);
25
* according to TARGET_SVE_SIG_{Z,P}REG_OFFSET, based off of
62
virtio_mmio_proxy = VIRTIO_MMIO(virtio_mmio_bus->parent);
26
* the original struct pointer.
63
@@ -XXX,XX +XXX,XX @@ static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
27
@@ -XXX,XX +XXX,XX @@ struct target_sve_context {
64
}
28
#define TARGET_SVE_SIG_CONTEXT_SIZE(VQ) \
65
29
(TARGET_SVE_SIG_PREG_OFFSET(VQ, 17))
66
/* Otherwise, we append the base address of the transport. */
30
67
- proxy_sbd = SYS_BUS_DEVICE(virtio_mmio_proxy);
31
+#define TARGET_SVE_SIG_FLAG_SM 1
68
- assert(proxy_sbd->num_mmio == 1);
69
- assert(proxy_sbd->mmio[0].memory == &virtio_mmio_proxy->iomem);
70
+ section = memory_region_find(&virtio_mmio_proxy->iomem, 0, 0x200);
71
+ assert(section.mr);
72
73
if (proxy_path) {
74
path = g_strdup_printf("%s/virtio-mmio@" TARGET_FMT_plx, proxy_path,
75
- proxy_sbd->mmio[0].addr);
76
+ section.offset_within_address_space);
77
} else {
78
path = g_strdup_printf("virtio-mmio@" TARGET_FMT_plx,
79
- proxy_sbd->mmio[0].addr);
80
+ section.offset_within_address_space);
81
}
82
+ memory_region_unref(section.mr);
83
+
32
+
84
g_free(proxy_path);
33
struct target_rt_sigframe {
85
return path;
34
struct target_siginfo info;
86
}
35
struct target_ucontext uc;
36
@@ -XXX,XX +XXX,XX @@ static void target_setup_sve_record(struct target_sve_context *sve,
37
{
38
int i, j;
39
40
+ memset(sve, 0, sizeof(*sve));
41
__put_user(TARGET_SVE_MAGIC, &sve->head.magic);
42
__put_user(size, &sve->head.size);
43
__put_user(vq * TARGET_SVE_VQ_BYTES, &sve->vl);
44
+ if (FIELD_EX64(env->svcr, SVCR, SM)) {
45
+ __put_user(TARGET_SVE_SIG_FLAG_SM, &sve->flags);
46
+ }
47
48
/* Note that SVE regs are stored as a byte stream, with each byte element
49
* at a subsequent address. This corresponds to a little-endian store
87
--
50
--
88
2.20.1
51
2.25.1
89
90
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The STATUS register will be reset to IDLE in
3
Fold the return value setting into the goto, so each
4
cnpcm7xx_smbus_enter_reset(), no need to preset
4
point of failure need not do both.
5
it in instance_init().
6
5
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Hao Wu <wuhaotsh@google.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210228224813.312532-1-f4bug@amsat.org
8
Message-id: 20220708151540.18136-37-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
hw/i2c/npcm7xx_smbus.c | 1 -
11
linux-user/aarch64/signal.c | 26 +++++++++++---------------
13
1 file changed, 1 deletion(-)
12
1 file changed, 11 insertions(+), 15 deletions(-)
14
13
15
diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
14
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/i2c/npcm7xx_smbus.c
16
--- a/linux-user/aarch64/signal.c
18
+++ b/hw/i2c/npcm7xx_smbus.c
17
+++ b/linux-user/aarch64/signal.c
19
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_init(Object *obj)
18
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
20
sysbus_init_mmio(sbd, &s->iomem);
19
struct target_sve_context *sve = NULL;
21
20
uint64_t extra_datap = 0;
22
s->bus = i2c_init_bus(DEVICE(s), "i2c-bus");
21
bool used_extra = false;
23
- s->status = NPCM7XX_SMBUS_STATUS_IDLE;
22
- bool err = false;
23
int vq = 0, sve_size = 0;
24
25
target_restore_general_frame(env, sf);
26
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
27
switch (magic) {
28
case 0:
29
if (size != 0) {
30
- err = true;
31
- goto exit;
32
+ goto err;
33
}
34
if (used_extra) {
35
ctx = NULL;
36
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
37
38
case TARGET_FPSIMD_MAGIC:
39
if (fpsimd || size != sizeof(struct target_fpsimd_context)) {
40
- err = true;
41
- goto exit;
42
+ goto err;
43
}
44
fpsimd = (struct target_fpsimd_context *)ctx;
45
break;
46
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
47
break;
48
}
49
}
50
- err = true;
51
- goto exit;
52
+ goto err;
53
54
case TARGET_EXTRA_MAGIC:
55
if (extra || size != sizeof(struct target_extra_context)) {
56
- err = true;
57
- goto exit;
58
+ goto err;
59
}
60
__get_user(extra_datap,
61
&((struct target_extra_context *)ctx)->datap);
62
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
63
/* Unknown record -- we certainly didn't generate it.
64
* Did we in fact get out of sync?
65
*/
66
- err = true;
67
- goto exit;
68
+ goto err;
69
}
70
ctx = (void *)ctx + size;
71
}
72
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
73
if (fpsimd) {
74
target_restore_fpsimd_record(env, fpsimd);
75
} else {
76
- err = true;
77
+ goto err;
78
}
79
80
/* SVE data, if present, overwrites FPSIMD data. */
81
if (sve) {
82
target_restore_sve_record(env, sve, vq);
83
}
84
-
85
- exit:
86
unlock_user(extra, extra_datap, 0);
87
- return err;
88
+ return 0;
89
+
90
+ err:
91
+ unlock_user(extra, extra_datap, 0);
92
+ return 1;
24
}
93
}
25
94
26
static const VMStateDescription vmstate_npcm7xx_smbus = {
95
static abi_ulong get_sigframe(struct target_sigaction *ka,
27
--
96
--
28
2.20.1
97
2.25.1
29
30
diff view generated by jsdifflib
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Cortex-A53 supports 40bits of address space. sbsa-ref's memory starts
3
In parse_user_sigframe, the kernel rejects duplicate sve records,
4
above this limit.
4
or records that are smaller than the header. We were silently
5
allowing these cases to pass, dropping the record.
5
6
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Acked-by: Leif Lindholm <leif@nuviainc.com>
9
Message-id: 20220708151540.18136-38-richard.henderson@linaro.org
9
Message-id: 20210216150122.3830863-2-marcin.juszkiewicz@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
hw/arm/sbsa-ref.c | 1 -
12
linux-user/aarch64/signal.c | 5 ++++-
13
1 file changed, 1 deletion(-)
13
1 file changed, 4 insertions(+), 1 deletion(-)
14
14
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
15
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/sbsa-ref.c
17
--- a/linux-user/aarch64/signal.c
18
+++ b/hw/arm/sbsa-ref.c
18
+++ b/linux-user/aarch64/signal.c
19
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
19
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
20
};
20
break;
21
21
22
static const char * const valid_cpus[] = {
22
case TARGET_SVE_MAGIC:
23
- ARM_CPU_TYPE_NAME("cortex-a53"),
23
+ if (sve || size < sizeof(struct target_sve_context)) {
24
ARM_CPU_TYPE_NAME("cortex-a57"),
24
+ goto err;
25
ARM_CPU_TYPE_NAME("cortex-a72"),
25
+ }
26
};
26
if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
27
vq = sve_vq(env);
28
sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
29
- if (!sve && size == sve_size) {
30
+ if (size == sve_size) {
31
sve = (struct target_sve_context *)ctx;
32
break;
33
}
27
--
34
--
28
2.20.1
35
2.25.1
29
30
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
We hint the 'has_rpu' property is no longer required since commit
4
6908ec448b4 ("xlnx-zynqmp: Properly support the smp command line
5
option") which was released in QEMU v2.11.0.
6
7
Beside, this device is marked 'user_creatable = false', so the
8
only thing that could be setting the property is the board code
9
that creates the device.
10
11
Since the property is not user-facing, we can remove it without
12
going through the deprecation process.
13
2
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20210219144350.1979905-1-f4bug@amsat.org
5
Message-id: 20220708151540.18136-39-richard.henderson@linaro.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
7
---
19
include/hw/arm/xlnx-zynqmp.h | 2 --
8
linux-user/aarch64/signal.c | 3 +++
20
hw/arm/xlnx-zynqmp.c | 6 ------
9
1 file changed, 3 insertions(+)
21
2 files changed, 8 deletions(-)
22
10
23
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
11
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
24
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/xlnx-zynqmp.h
13
--- a/linux-user/aarch64/signal.c
26
+++ b/include/hw/arm/xlnx-zynqmp.h
14
+++ b/linux-user/aarch64/signal.c
27
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
15
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
28
bool secure;
16
__get_user(extra_size,
29
/* Has the ARM Virtualization extensions? */
17
&((struct target_extra_context *)ctx)->size);
30
bool virt;
18
extra = lock_user(VERIFY_READ, extra_datap, extra_size, 0);
31
- /* Has the RPU subsystem? */
19
+ if (!extra) {
32
- bool has_rpu;
20
+ return 1;
33
21
+ }
34
/* CAN bus. */
22
break;
35
CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
23
36
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
24
default:
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/xlnx-zynqmp.c
39
+++ b/hw/arm/xlnx-zynqmp.c
40
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
41
}
42
}
43
44
- if (s->has_rpu) {
45
- info_report("The 'has_rpu' property is no longer required, to use the "
46
- "RPUs just use -smp 6.");
47
- }
48
-
49
xlnx_zynqmp_create_rpu(ms, s, boot_cpu, &err);
50
if (err) {
51
error_propagate(errp, err);
52
@@ -XXX,XX +XXX,XX @@ static Property xlnx_zynqmp_props[] = {
53
DEFINE_PROP_STRING("boot-cpu", XlnxZynqMPState, boot_cpu),
54
DEFINE_PROP_BOOL("secure", XlnxZynqMPState, secure, false),
55
DEFINE_PROP_BOOL("virtualization", XlnxZynqMPState, virt, false),
56
- DEFINE_PROP_BOOL("has_rpu", XlnxZynqMPState, has_rpu, false),
57
DEFINE_PROP_LINK("ddr-ram", XlnxZynqMPState, ddr_ram, TYPE_MEMORY_REGION,
58
MemoryRegion *),
59
DEFINE_PROP_LINK("canbus0", XlnxZynqMPState, canbus[0], TYPE_CAN_BUS,
60
--
25
--
61
2.20.1
26
2.25.1
62
63
diff view generated by jsdifflib
1
In the mps2-tz board code, we handle devices whose interrupt lines
1
From: Richard Henderson <richard.henderson@linaro.org>
2
must be wired to all CPUs by creating IRQ splitter devices for the
3
AN521, because it has 2 CPUs, but wiring the device IRQ directly to
4
the SSE/IoTKit input for the AN505, which has only 1 CPU.
5
2
6
We can avoid making an explicit check on the board type constant by
3
Move the checks out of the parsing loop and into the
7
instead creating and using the IRQ splitters for any board with more
4
restore function. This more closely mirrors the code
8
than 1 CPU. This avoids having to add extra cases to the
5
structure in the kernel, and is slightly clearer.
9
conditionals every time we add new boards.
10
6
7
Reject rather than silently skip incorrect VL and SVE record sizes,
8
bringing our checks in to line with those the kernel does.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20220708151540.18136-40-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210215115138.20465-9-peter.maydell@linaro.org
15
---
14
---
16
hw/arm/mps2-tz.c | 19 +++++++++----------
15
linux-user/aarch64/signal.c | 51 +++++++++++++++++++++++++------------
17
1 file changed, 9 insertions(+), 10 deletions(-)
16
1 file changed, 35 insertions(+), 16 deletions(-)
18
17
19
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
18
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
20
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/mps2-tz.c
20
--- a/linux-user/aarch64/signal.c
22
+++ b/hw/arm/mps2-tz.c
21
+++ b/linux-user/aarch64/signal.c
23
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
22
@@ -XXX,XX +XXX,XX @@ static void target_restore_fpsimd_record(CPUARMState *env,
24
static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
25
{
26
/* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
27
- MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
28
+ MachineClass *mc = MACHINE_GET_CLASS(mms);
29
30
assert(irqno < MPS2TZ_NUMIRQ);
31
32
- switch (mmc->fpga_type) {
33
- case FPGA_AN505:
34
- return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
35
- case FPGA_AN521:
36
+ if (mc->max_cpus > 1) {
37
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
38
- default:
39
- g_assert_not_reached();
40
+ } else {
41
+ return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
42
}
23
}
43
}
24
}
44
25
45
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
26
-static void target_restore_sve_record(CPUARMState *env,
46
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
27
- struct target_sve_context *sve, int vq)
47
28
+static bool target_restore_sve_record(CPUARMState *env,
48
/*
29
+ struct target_sve_context *sve,
49
- * The AN521 needs us to create splitters to feed the IRQ inputs
30
+ int size)
50
- * for each CPU in the SSE-200 from each device in the board.
31
{
51
+ * If this board has more than one CPU, then we need to create splitters
32
- int i, j;
52
+ * to feed the IRQ inputs for each CPU in the SSE from each device in the
33
+ int i, j, vl, vq;
53
+ * board. If there is only one CPU, we can just wire the device IRQ
34
54
+ * directly to the SSE's IRQ input.
35
- /* Note that SVE regs are stored as a byte stream, with each byte element
36
+ if (!cpu_isar_feature(aa64_sve, env_archcpu(env))) {
37
+ return false;
38
+ }
39
+
40
+ __get_user(vl, &sve->vl);
41
+ vq = sve_vq(env);
42
+
43
+ /* Reject mismatched VL. */
44
+ if (vl != vq * TARGET_SVE_VQ_BYTES) {
45
+ return false;
46
+ }
47
+
48
+ /* Accept empty record -- used to clear PSTATE.SM. */
49
+ if (size <= sizeof(*sve)) {
50
+ return true;
51
+ }
52
+
53
+ /* Reject non-empty but incomplete record. */
54
+ if (size < TARGET_SVE_SIG_CONTEXT_SIZE(vq)) {
55
+ return false;
56
+ }
57
+
58
+ /*
59
+ * Note that SVE regs are stored as a byte stream, with each byte element
60
* at a subsequent address. This corresponds to a little-endian load
61
* of our 64-bit hunks.
55
*/
62
*/
56
- if (mmc->fpga_type == FPGA_AN521) {
63
@@ -XXX,XX +XXX,XX @@ static void target_restore_sve_record(CPUARMState *env,
57
+ if (mc->max_cpus > 1) {
64
}
58
for (i = 0; i < MPS2TZ_NUMIRQ; i++) {
65
}
59
char *name = g_strdup_printf("mps2-irq-splitter%d", i);
66
}
60
SplitIRQ *splitter = &mms->cpu_irq_splitter[i];
67
+ return true;
68
}
69
70
static int target_restore_sigframe(CPUARMState *env,
71
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
72
struct target_sve_context *sve = NULL;
73
uint64_t extra_datap = 0;
74
bool used_extra = false;
75
- int vq = 0, sve_size = 0;
76
+ int sve_size = 0;
77
78
target_restore_general_frame(env, sf);
79
80
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
81
if (sve || size < sizeof(struct target_sve_context)) {
82
goto err;
83
}
84
- if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
85
- vq = sve_vq(env);
86
- sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
87
- if (size == sve_size) {
88
- sve = (struct target_sve_context *)ctx;
89
- break;
90
- }
91
- }
92
- goto err;
93
+ sve = (struct target_sve_context *)ctx;
94
+ sve_size = size;
95
+ break;
96
97
case TARGET_EXTRA_MAGIC:
98
if (extra || size != sizeof(struct target_extra_context)) {
99
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
100
}
101
102
/* SVE data, if present, overwrites FPSIMD data. */
103
- if (sve) {
104
- target_restore_sve_record(env, sve, vq);
105
+ if (sve && !target_restore_sve_record(env, sve, sve_size)) {
106
+ goto err;
107
}
108
unlock_user(extra, extra_datap, 0);
109
return 0;
61
--
110
--
62
2.20.1
111
2.25.1
63
64
diff view generated by jsdifflib
1
The AN505 and AN511 happen to share the same OSCCLK values, but the
1
From: Richard Henderson <richard.henderson@linaro.org>
2
AN524 will have a different set (and more of them), so split the
3
settings out to be per-board.
4
2
3
Set the SM bit in the SVE record on signal delivery, create the ZA record.
4
Restore SM and ZA state according to the records present on return.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-41-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-5-peter.maydell@linaro.org
9
---
10
---
10
hw/arm/mps2-tz.c | 23 ++++++++++++++++++-----
11
linux-user/aarch64/signal.c | 167 +++++++++++++++++++++++++++++++++---
11
1 file changed, 18 insertions(+), 5 deletions(-)
12
1 file changed, 154 insertions(+), 13 deletions(-)
12
13
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
16
--- a/linux-user/aarch64/signal.c
16
+++ b/hw/arm/mps2-tz.c
17
+++ b/linux-user/aarch64/signal.c
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
18
@@ -XXX,XX +XXX,XX @@ struct target_sve_context {
18
MPS2TZFPGAType fpga_type;
19
19
uint32_t scc_id;
20
#define TARGET_SVE_SIG_FLAG_SM 1
20
uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
21
21
+ uint32_t len_oscclk;
22
+#define TARGET_ZA_MAGIC 0x54366345
22
+ const uint32_t *oscclk;
23
+
23
const char *armsse_type;
24
+struct target_za_context {
24
};
25
+ struct target_aarch64_ctx head;
25
26
+ uint16_t vl;
26
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
27
+ uint16_t reserved[3];
27
/* Slow 32Khz S32KCLK frequency in Hz */
28
+ /* The actual ZA data immediately follows. */
28
#define S32KCLK_FRQ (32 * 1000)
29
30
+static const uint32_t an505_oscclk[] = {
31
+ 40000000,
32
+ 24580000,
33
+ 25000000,
34
+};
29
+};
35
+
30
+
36
/* Create an alias of an entire original MemoryRegion @orig
31
+#define TARGET_ZA_SIG_REGS_OFFSET \
37
* located at @base in the memory map.
32
+ QEMU_ALIGN_UP(sizeof(struct target_za_context), TARGET_SVE_VQ_BYTES)
38
*/
33
+#define TARGET_ZA_SIG_ZAV_OFFSET(VQ, N) \
39
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
34
+ (TARGET_ZA_SIG_REGS_OFFSET + (VQ) * TARGET_SVE_VQ_BYTES * (N))
40
MPS2SCC *scc = opaque;
35
+#define TARGET_ZA_SIG_CONTEXT_SIZE(VQ) \
41
DeviceState *sccdev;
36
+ TARGET_ZA_SIG_ZAV_OFFSET(VQ, VQ * TARGET_SVE_VQ_BYTES)
42
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
37
+
43
+ uint32_t i;
38
struct target_rt_sigframe {
44
39
struct target_siginfo info;
45
object_initialize_child(OBJECT(mms), "scc", scc, TYPE_MPS2_SCC);
40
struct target_ucontext uc;
46
sccdev = DEVICE(scc);
41
@@ -XXX,XX +XXX,XX @@ static void target_setup_end_record(struct target_aarch64_ctx *end)
47
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
48
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
49
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
50
- /* This will need to be per-FPGA image eventually */
51
- qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
52
- qdev_prop_set_uint32(sccdev, "oscclk[0]", 40000000);
53
- qdev_prop_set_uint32(sccdev, "oscclk[1]", 24580000);
54
- qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
55
+ qdev_prop_set_uint32(sccdev, "len-oscclk", mmc->len_oscclk);
56
+ for (i = 0; i < mmc->len_oscclk; i++) {
57
+ g_autofree char *propname = g_strdup_printf("oscclk[%u]", i);
58
+ qdev_prop_set_uint32(sccdev, propname, mmc->oscclk[i]);
59
+ }
60
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
61
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
62
}
42
}
63
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
43
64
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
44
static void target_setup_sve_record(struct target_sve_context *sve,
65
mmc->scc_id = 0x41045050;
45
- CPUARMState *env, int vq, int size)
66
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
46
+ CPUARMState *env, int size)
67
+ mmc->oscclk = an505_oscclk;
47
{
68
+ mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
48
- int i, j;
69
mmc->armsse_type = TYPE_IOTKIT;
49
+ int i, j, vq = sve_vq(env);
50
51
memset(sve, 0, sizeof(*sve));
52
__put_user(TARGET_SVE_MAGIC, &sve->head.magic);
53
@@ -XXX,XX +XXX,XX @@ static void target_setup_sve_record(struct target_sve_context *sve,
54
}
70
}
55
}
71
56
72
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
57
+static void target_setup_za_record(struct target_za_context *za,
73
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
58
+ CPUARMState *env, int size)
74
mmc->scc_id = 0x41045210;
59
+{
75
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
60
+ int vq = sme_vq(env);
76
+ mmc->oscclk = an505_oscclk; /* AN521 is the same as AN505 here */
61
+ int vl = vq * TARGET_SVE_VQ_BYTES;
77
+ mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
62
+ int i, j;
78
mmc->armsse_type = TYPE_SSE200;
63
+
64
+ memset(za, 0, sizeof(*za));
65
+ __put_user(TARGET_ZA_MAGIC, &za->head.magic);
66
+ __put_user(size, &za->head.size);
67
+ __put_user(vl, &za->vl);
68
+
69
+ if (size == TARGET_ZA_SIG_CONTEXT_SIZE(0)) {
70
+ return;
71
+ }
72
+ assert(size == TARGET_ZA_SIG_CONTEXT_SIZE(vq));
73
+
74
+ /*
75
+ * Note that ZA vectors are stored as a byte stream,
76
+ * with each byte element at a subsequent address.
77
+ */
78
+ for (i = 0; i < vl; ++i) {
79
+ uint64_t *z = (void *)za + TARGET_ZA_SIG_ZAV_OFFSET(vq, i);
80
+ for (j = 0; j < vq * 2; ++j) {
81
+ __put_user_e(env->zarray[i].d[j], z + j, le);
82
+ }
83
+ }
84
+}
85
+
86
static void target_restore_general_frame(CPUARMState *env,
87
struct target_rt_sigframe *sf)
88
{
89
@@ -XXX,XX +XXX,XX @@ static void target_restore_fpsimd_record(CPUARMState *env,
90
91
static bool target_restore_sve_record(CPUARMState *env,
92
struct target_sve_context *sve,
93
- int size)
94
+ int size, int *svcr)
95
{
96
- int i, j, vl, vq;
97
+ int i, j, vl, vq, flags;
98
+ bool sm;
99
100
- if (!cpu_isar_feature(aa64_sve, env_archcpu(env))) {
101
+ __get_user(vl, &sve->vl);
102
+ __get_user(flags, &sve->flags);
103
+
104
+ sm = flags & TARGET_SVE_SIG_FLAG_SM;
105
+
106
+ /* The cpu must support Streaming or Non-streaming SVE. */
107
+ if (sm
108
+ ? !cpu_isar_feature(aa64_sme, env_archcpu(env))
109
+ : !cpu_isar_feature(aa64_sve, env_archcpu(env))) {
110
return false;
111
}
112
113
- __get_user(vl, &sve->vl);
114
- vq = sve_vq(env);
115
+ /*
116
+ * Note that we cannot use sve_vq() because that depends on the
117
+ * current setting of PSTATE.SM, not the state to be restored.
118
+ */
119
+ vq = sve_vqm1_for_el_sm(env, 0, sm) + 1;
120
121
/* Reject mismatched VL. */
122
if (vl != vq * TARGET_SVE_VQ_BYTES) {
123
@@ -XXX,XX +XXX,XX @@ static bool target_restore_sve_record(CPUARMState *env,
124
return false;
125
}
126
127
+ *svcr = FIELD_DP64(*svcr, SVCR, SM, sm);
128
+
129
/*
130
* Note that SVE regs are stored as a byte stream, with each byte element
131
* at a subsequent address. This corresponds to a little-endian load
132
@@ -XXX,XX +XXX,XX @@ static bool target_restore_sve_record(CPUARMState *env,
133
return true;
79
}
134
}
80
135
136
+static bool target_restore_za_record(CPUARMState *env,
137
+ struct target_za_context *za,
138
+ int size, int *svcr)
139
+{
140
+ int i, j, vl, vq;
141
+
142
+ if (!cpu_isar_feature(aa64_sme, env_archcpu(env))) {
143
+ return false;
144
+ }
145
+
146
+ __get_user(vl, &za->vl);
147
+ vq = sme_vq(env);
148
+
149
+ /* Reject mismatched VL. */
150
+ if (vl != vq * TARGET_SVE_VQ_BYTES) {
151
+ return false;
152
+ }
153
+
154
+ /* Accept empty record -- used to clear PSTATE.ZA. */
155
+ if (size <= TARGET_ZA_SIG_CONTEXT_SIZE(0)) {
156
+ return true;
157
+ }
158
+
159
+ /* Reject non-empty but incomplete record. */
160
+ if (size < TARGET_ZA_SIG_CONTEXT_SIZE(vq)) {
161
+ return false;
162
+ }
163
+
164
+ *svcr = FIELD_DP64(*svcr, SVCR, ZA, 1);
165
+
166
+ for (i = 0; i < vl; ++i) {
167
+ uint64_t *z = (void *)za + TARGET_ZA_SIG_ZAV_OFFSET(vq, i);
168
+ for (j = 0; j < vq * 2; ++j) {
169
+ __get_user_e(env->zarray[i].d[j], z + j, le);
170
+ }
171
+ }
172
+ return true;
173
+}
174
+
175
static int target_restore_sigframe(CPUARMState *env,
176
struct target_rt_sigframe *sf)
177
{
178
struct target_aarch64_ctx *ctx, *extra = NULL;
179
struct target_fpsimd_context *fpsimd = NULL;
180
struct target_sve_context *sve = NULL;
181
+ struct target_za_context *za = NULL;
182
uint64_t extra_datap = 0;
183
bool used_extra = false;
184
int sve_size = 0;
185
+ int za_size = 0;
186
+ int svcr = 0;
187
188
target_restore_general_frame(env, sf);
189
190
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
191
sve_size = size;
192
break;
193
194
+ case TARGET_ZA_MAGIC:
195
+ if (za || size < sizeof(struct target_za_context)) {
196
+ goto err;
197
+ }
198
+ za = (struct target_za_context *)ctx;
199
+ za_size = size;
200
+ break;
201
+
202
case TARGET_EXTRA_MAGIC:
203
if (extra || size != sizeof(struct target_extra_context)) {
204
goto err;
205
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
206
}
207
208
/* SVE data, if present, overwrites FPSIMD data. */
209
- if (sve && !target_restore_sve_record(env, sve, sve_size)) {
210
+ if (sve && !target_restore_sve_record(env, sve, sve_size, &svcr)) {
211
goto err;
212
}
213
+ if (za && !target_restore_za_record(env, za, za_size, &svcr)) {
214
+ goto err;
215
+ }
216
+ if (env->svcr != svcr) {
217
+ env->svcr = svcr;
218
+ arm_rebuild_hflags(env);
219
+ }
220
unlock_user(extra, extra_datap, 0);
221
return 0;
222
223
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
224
.total_size = offsetof(struct target_rt_sigframe,
225
uc.tuc_mcontext.__reserved),
226
};
227
- int fpsimd_ofs, fr_ofs, sve_ofs = 0, vq = 0, sve_size = 0;
228
+ int fpsimd_ofs, fr_ofs, sve_ofs = 0, za_ofs = 0;
229
+ int sve_size = 0, za_size = 0;
230
struct target_rt_sigframe *frame;
231
struct target_rt_frame_record *fr;
232
abi_ulong frame_addr, return_addr;
233
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
234
&layout);
235
236
/* SVE state needs saving only if it exists. */
237
- if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
238
- vq = sve_vq(env);
239
- sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(vq), 16);
240
+ if (cpu_isar_feature(aa64_sve, env_archcpu(env)) ||
241
+ cpu_isar_feature(aa64_sme, env_archcpu(env))) {
242
+ sve_size = QEMU_ALIGN_UP(TARGET_SVE_SIG_CONTEXT_SIZE(sve_vq(env)), 16);
243
sve_ofs = alloc_sigframe_space(sve_size, &layout);
244
}
245
+ if (cpu_isar_feature(aa64_sme, env_archcpu(env))) {
246
+ /* ZA state needs saving only if it is enabled. */
247
+ if (FIELD_EX64(env->svcr, SVCR, ZA)) {
248
+ za_size = TARGET_ZA_SIG_CONTEXT_SIZE(sme_vq(env));
249
+ } else {
250
+ za_size = TARGET_ZA_SIG_CONTEXT_SIZE(0);
251
+ }
252
+ za_ofs = alloc_sigframe_space(za_size, &layout);
253
+ }
254
255
if (layout.extra_ofs) {
256
/* Reserve space for the extra end marker. The standard end marker
257
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
258
target_setup_end_record((void *)frame + layout.extra_end_ofs);
259
}
260
if (sve_ofs) {
261
- target_setup_sve_record((void *)frame + sve_ofs, env, vq, sve_size);
262
+ target_setup_sve_record((void *)frame + sve_ofs, env, sve_size);
263
+ }
264
+ if (za_ofs) {
265
+ target_setup_za_record((void *)frame + za_ofs, env, za_size);
266
}
267
268
/* Set up the stack frame for unwinding. */
269
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
270
env->btype = 2;
271
}
272
273
+ /*
274
+ * Invoke the signal handler with both SM and ZA disabled.
275
+ * When clearing SM, ResetSVEState, per SMSTOP.
276
+ */
277
+ if (FIELD_EX64(env->svcr, SVCR, SM)) {
278
+ arm_reset_sve_state(env);
279
+ }
280
+ if (env->svcr) {
281
+ env->svcr = 0;
282
+ arm_rebuild_hflags(env);
283
+ }
284
+
285
if (info) {
286
tswap_siginfo(&frame->info, info);
287
env->xregs[1] = frame_addr + offsetof(struct target_rt_sigframe, info);
81
--
288
--
82
2.20.1
289
2.25.1
83
84
diff view generated by jsdifflib
1
The mps2-tz code uses PPCPortInfo data structures to define what
1
From: Richard Henderson <richard.henderson@linaro.org>
2
devices are present and how they are wired up. Currently we use
3
these to specify device types and addresses, but hard-code the
4
interrupt line wiring in each make_* helper function. This works for
5
the two boards we have at the moment, but the AN524 has some devices
6
with different interrupt assignments.
7
2
8
This commit adds the framework to allow PPCPortInfo structures to
3
Add "sve" to the sve prctl functions, to distinguish
9
specify interrupt numbers. We add an array of interrupt numbers to
4
them from the coming "sme" prctls with similar names.
10
the PPCPortInfo struct, and pass it through to the make_* helpers.
11
The following commit will change the make_* helpers over to using the
12
framework.
13
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-42-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20210215115138.20465-13-peter.maydell@linaro.org
17
---
10
---
18
hw/arm/mps2-tz.c | 36 ++++++++++++++++++++++++------------
11
linux-user/aarch64/target_prctl.h | 8 ++++----
19
1 file changed, 24 insertions(+), 12 deletions(-)
12
linux-user/syscall.c | 12 ++++++------
13
2 files changed, 10 insertions(+), 10 deletions(-)
20
14
21
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
22
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/mps2-tz.c
17
--- a/linux-user/aarch64/target_prctl.h
24
+++ b/hw/arm/mps2-tz.c
18
+++ b/linux-user/aarch64/target_prctl.h
25
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
19
@@ -XXX,XX +XXX,XX @@
26
* needs to be plugged into the downstream end of the PPC port.
20
#ifndef AARCH64_TARGET_PRCTL_H
27
*/
21
#define AARCH64_TARGET_PRCTL_H
28
typedef MemoryRegion *MakeDevFn(MPS2TZMachineState *mms, void *opaque,
22
29
- const char *name, hwaddr size);
23
-static abi_long do_prctl_get_vl(CPUArchState *env)
30
+ const char *name, hwaddr size,
24
+static abi_long do_prctl_sve_get_vl(CPUArchState *env)
31
+ const int *irqs);
32
33
typedef struct PPCPortInfo {
34
const char *name;
35
@@ -XXX,XX +XXX,XX @@ typedef struct PPCPortInfo {
36
void *opaque;
37
hwaddr addr;
38
hwaddr size;
39
+ int irqs[3]; /* currently no device needs more IRQ lines than this */
40
} PPCPortInfo;
41
42
typedef struct PPCInfo {
43
@@ -XXX,XX +XXX,XX @@ typedef struct PPCInfo {
44
} PPCInfo;
45
46
static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
47
- void *opaque,
48
- const char *name, hwaddr size)
49
+ void *opaque,
50
+ const char *name, hwaddr size,
51
+ const int *irqs)
52
{
25
{
53
/* Initialize, configure and realize a TYPE_UNIMPLEMENTED_DEVICE,
26
ARMCPU *cpu = env_archcpu(env);
54
* and return a pointer to its MemoryRegion.
27
if (cpu_isar_feature(aa64_sve, cpu)) {
55
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
28
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_get_vl(CPUArchState *env)
29
}
30
return -TARGET_EINVAL;
56
}
31
}
57
32
-#define do_prctl_get_vl do_prctl_get_vl
58
static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
33
+#define do_prctl_sve_get_vl do_prctl_sve_get_vl
59
- const char *name, hwaddr size)
34
60
+ const char *name, hwaddr size,
35
-static abi_long do_prctl_set_vl(CPUArchState *env, abi_long arg2)
61
+ const int *irqs)
36
+static abi_long do_prctl_sve_set_vl(CPUArchState *env, abi_long arg2)
62
{
63
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
64
CMSDKAPBUART *uart = opaque;
65
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
66
}
67
68
static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
69
- const char *name, hwaddr size)
70
+ const char *name, hwaddr size,
71
+ const int *irqs)
72
{
73
MPS2SCC *scc = opaque;
74
DeviceState *sccdev;
75
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
76
}
77
78
static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
79
- const char *name, hwaddr size)
80
+ const char *name, hwaddr size,
81
+ const int *irqs)
82
{
83
MPS2FPGAIO *fpgaio = opaque;
84
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
85
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
86
}
87
88
static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
89
- const char *name, hwaddr size)
90
+ const char *name, hwaddr size,
91
+ const int *irqs)
92
{
93
SysBusDevice *s;
94
NICInfo *nd = &nd_table[0];
95
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
96
}
97
98
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
99
- const char *name, hwaddr size)
100
+ const char *name, hwaddr size,
101
+ const int *irqs)
102
{
103
TZMPC *mpc = opaque;
104
int i = mpc - &mms->ssram_mpc[0];
105
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
106
}
107
108
static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
109
- const char *name, hwaddr size)
110
+ const char *name, hwaddr size,
111
+ const int *irqs)
112
{
113
PL080State *dma = opaque;
114
int i = dma - &mms->dma[0];
115
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
116
}
117
118
static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
119
- const char *name, hwaddr size)
120
+ const char *name, hwaddr size,
121
+ const int *irqs)
122
{
37
{
123
/*
38
/*
124
* The AN505 has five PL022 SPI controllers.
39
* We cannot support either PR_SVE_SET_VL_ONEXEC or PR_SVE_VL_INHERIT.
125
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
40
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_set_vl(CPUArchState *env, abi_long arg2)
41
}
42
return -TARGET_EINVAL;
126
}
43
}
127
44
-#define do_prctl_set_vl do_prctl_set_vl
128
static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
45
+#define do_prctl_sve_set_vl do_prctl_sve_set_vl
129
- const char *name, hwaddr size)
46
130
+ const char *name, hwaddr size,
47
static abi_long do_prctl_reset_keys(CPUArchState *env, abi_long arg2)
131
+ const int *irqs)
132
{
48
{
133
ArmSbconI2CState *i2c = opaque;
49
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
134
SysBusDevice *s;
50
index XXXXXXX..XXXXXXX 100644
135
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
51
--- a/linux-user/syscall.c
136
continue;
52
+++ b/linux-user/syscall.c
137
}
53
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_inval1(CPUArchState *env, abi_long arg2)
138
54
#ifndef do_prctl_set_fp_mode
139
- mr = pinfo->devfn(mms, pinfo->opaque, pinfo->name, pinfo->size);
55
#define do_prctl_set_fp_mode do_prctl_inval1
140
+ mr = pinfo->devfn(mms, pinfo->opaque, pinfo->name, pinfo->size,
56
#endif
141
+ pinfo->irqs);
57
-#ifndef do_prctl_get_vl
142
portname = g_strdup_printf("port[%d]", port);
58
-#define do_prctl_get_vl do_prctl_inval0
143
object_property_set_link(OBJECT(ppc), portname, OBJECT(mr),
59
+#ifndef do_prctl_sve_get_vl
144
&error_fatal);
60
+#define do_prctl_sve_get_vl do_prctl_inval0
61
#endif
62
-#ifndef do_prctl_set_vl
63
-#define do_prctl_set_vl do_prctl_inval1
64
+#ifndef do_prctl_sve_set_vl
65
+#define do_prctl_sve_set_vl do_prctl_inval1
66
#endif
67
#ifndef do_prctl_reset_keys
68
#define do_prctl_reset_keys do_prctl_inval1
69
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl(CPUArchState *env, abi_long option, abi_long arg2,
70
case PR_SET_FP_MODE:
71
return do_prctl_set_fp_mode(env, arg2);
72
case PR_SVE_GET_VL:
73
- return do_prctl_get_vl(env);
74
+ return do_prctl_sve_get_vl(env);
75
case PR_SVE_SET_VL:
76
- return do_prctl_set_vl(env, arg2);
77
+ return do_prctl_sve_set_vl(env, arg2);
78
case PR_PAC_RESET_KEYS:
79
if (arg3 || arg4 || arg5) {
80
return -TARGET_EINVAL;
145
--
81
--
146
2.20.1
82
2.25.1
147
148
diff view generated by jsdifflib
1
Instead of hardcoding the MachineClass default_ram_size and
1
From: Richard Henderson <richard.henderson@linaro.org>
2
default_ram_id fields, set them on class creation by finding the
3
entry in the RAMInfo array which is marked as being the QEMU system
4
RAM.
5
2
3
These prctl set the Streaming SVE vector length, which may
4
be completely different from the Normal SVE vector length.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220708151540.18136-43-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-18-peter.maydell@linaro.org
9
---
10
---
10
hw/arm/mps2-tz.c | 24 ++++++++++++++++++++++--
11
linux-user/aarch64/target_prctl.h | 54 +++++++++++++++++++++++++++++++
11
1 file changed, 22 insertions(+), 2 deletions(-)
12
linux-user/syscall.c | 16 +++++++++
13
2 files changed, 70 insertions(+)
12
14
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
17
--- a/linux-user/aarch64/target_prctl.h
16
+++ b/hw/arm/mps2-tz.c
18
+++ b/linux-user/aarch64/target_prctl.h
17
@@ -XXX,XX +XXX,XX @@ static void mps2tz_class_init(ObjectClass *oc, void *data)
19
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_sve_get_vl(CPUArchState *env)
18
20
{
19
mc->init = mps2tz_common_init;
21
ARMCPU *cpu = env_archcpu(env);
20
iic->check = mps2_tz_idau_check;
22
if (cpu_isar_feature(aa64_sve, cpu)) {
21
- mc->default_ram_size = 16 * MiB;
23
+ /* PSTATE.SM is always unset on syscall entry. */
22
- mc->default_ram_id = "mps.ram";
24
return sve_vq(env) * 16;
25
}
26
return -TARGET_EINVAL;
27
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_sve_set_vl(CPUArchState *env, abi_long arg2)
28
&& arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
29
uint32_t vq, old_vq;
30
31
+ /* PSTATE.SM is always unset on syscall entry. */
32
old_vq = sve_vq(env);
33
34
/*
35
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_sve_set_vl(CPUArchState *env, abi_long arg2)
36
}
37
#define do_prctl_sve_set_vl do_prctl_sve_set_vl
38
39
+static abi_long do_prctl_sme_get_vl(CPUArchState *env)
40
+{
41
+ ARMCPU *cpu = env_archcpu(env);
42
+ if (cpu_isar_feature(aa64_sme, cpu)) {
43
+ return sme_vq(env) * 16;
44
+ }
45
+ return -TARGET_EINVAL;
23
+}
46
+}
47
+#define do_prctl_sme_get_vl do_prctl_sme_get_vl
24
+
48
+
25
+static void mps2tz_set_default_ram_info(MPS2TZMachineClass *mmc)
49
+static abi_long do_prctl_sme_set_vl(CPUArchState *env, abi_long arg2)
26
+{
50
+{
27
+ /*
51
+ /*
28
+ * Set mc->default_ram_size and default_ram_id from the
52
+ * We cannot support either PR_SME_SET_VL_ONEXEC or PR_SME_VL_INHERIT.
29
+ * information in mmc->raminfo.
53
+ * Note the kernel definition of sve_vl_valid allows for VQ=512,
54
+ * i.e. VL=8192, even though the architectural maximum is VQ=16.
30
+ */
55
+ */
31
+ MachineClass *mc = MACHINE_CLASS(mmc);
56
+ if (cpu_isar_feature(aa64_sme, env_archcpu(env))
32
+ const RAMInfo *p;
57
+ && arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
58
+ int vq, old_vq;
33
+
59
+
34
+ for (p = mmc->raminfo; p->name; p++) {
60
+ old_vq = sme_vq(env);
35
+ if (p->mrindex < 0) {
61
+
36
+ /* Found the entry for "system memory" */
62
+ /*
37
+ mc->default_ram_size = p->size;
63
+ * Bound the value of vq, so that we know that it fits into
38
+ mc->default_ram_id = p->name;
64
+ * the 4-bit field in SMCR_EL1. Because PSTATE.SM is cleared
39
+ return;
65
+ * on syscall entry, we are not modifying the current SVE
66
+ * vector length.
67
+ */
68
+ vq = MAX(arg2 / 16, 1);
69
+ vq = MIN(vq, 16);
70
+ env->vfp.smcr_el[1] =
71
+ FIELD_DP64(env->vfp.smcr_el[1], SMCR, LEN, vq - 1);
72
+
73
+ /* Delay rebuilding hflags until we know if ZA must change. */
74
+ vq = sve_vqm1_for_el_sm(env, 0, true) + 1;
75
+
76
+ if (vq != old_vq) {
77
+ /*
78
+ * PSTATE.ZA state is cleared on any change to SVL.
79
+ * We need not call arm_rebuild_hflags because PSTATE.SM was
80
+ * cleared on syscall entry, so this hasn't changed VL.
81
+ */
82
+ env->svcr = FIELD_DP64(env->svcr, SVCR, ZA, 0);
83
+ arm_rebuild_hflags(env);
40
+ }
84
+ }
85
+ return vq * 16;
41
+ }
86
+ }
42
+ g_assert_not_reached();
87
+ return -TARGET_EINVAL;
43
}
88
+}
44
89
+#define do_prctl_sme_set_vl do_prctl_sme_set_vl
45
static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
90
+
46
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
91
static abi_long do_prctl_reset_keys(CPUArchState *env, abi_long arg2)
47
mmc->numirq = 92;
92
{
48
mmc->raminfo = an505_raminfo;
93
ARMCPU *cpu = env_archcpu(env);
49
mmc->armsse_type = TYPE_IOTKIT;
94
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
50
+ mps2tz_set_default_ram_info(mmc);
95
index XXXXXXX..XXXXXXX 100644
51
}
96
--- a/linux-user/syscall.c
52
97
+++ b/linux-user/syscall.c
53
static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
98
@@ -XXX,XX +XXX,XX @@ abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
54
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
99
#ifndef PR_SET_SYSCALL_USER_DISPATCH
55
mmc->numirq = 92;
100
# define PR_SET_SYSCALL_USER_DISPATCH 59
56
mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
101
#endif
57
mmc->armsse_type = TYPE_SSE200;
102
+#ifndef PR_SME_SET_VL
58
+ mps2tz_set_default_ram_info(mmc);
103
+# define PR_SME_SET_VL 63
59
}
104
+# define PR_SME_GET_VL 64
60
105
+# define PR_SME_VL_LEN_MASK 0xffff
61
static const TypeInfo mps2tz_info = {
106
+# define PR_SME_VL_INHERIT (1 << 17)
107
+#endif
108
109
#include "target_prctl.h"
110
111
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_inval1(CPUArchState *env, abi_long arg2)
112
#ifndef do_prctl_set_unalign
113
#define do_prctl_set_unalign do_prctl_inval1
114
#endif
115
+#ifndef do_prctl_sme_get_vl
116
+#define do_prctl_sme_get_vl do_prctl_inval0
117
+#endif
118
+#ifndef do_prctl_sme_set_vl
119
+#define do_prctl_sme_set_vl do_prctl_inval1
120
+#endif
121
122
static abi_long do_prctl(CPUArchState *env, abi_long option, abi_long arg2,
123
abi_long arg3, abi_long arg4, abi_long arg5)
124
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl(CPUArchState *env, abi_long option, abi_long arg2,
125
return do_prctl_sve_get_vl(env);
126
case PR_SVE_SET_VL:
127
return do_prctl_sve_set_vl(env, arg2);
128
+ case PR_SME_GET_VL:
129
+ return do_prctl_sme_get_vl(env);
130
+ case PR_SME_SET_VL:
131
+ return do_prctl_sme_set_vl(env, arg2);
132
case PR_PAC_RESET_KEYS:
133
if (arg3 || arg4 || arg5) {
134
return -TARGET_EINVAL;
62
--
135
--
63
2.20.1
136
2.25.1
64
65
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
IDAU is specific to M-profile. KVM only supports A-profile.
3
There's no reason to set CPACR_EL1.ZEN if SVE disabled.
4
Restrict this interface to TCG, as it is pointless (and
5
confusing) on a KVM-only build.
6
4
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210221222617.2579610-2-f4bug@amsat.org
7
Message-id: 20220708151540.18136-44-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
9
---
13
target/arm/cpu.c | 7 -------
10
target/arm/cpu.c | 7 +++----
14
target/arm/cpu_tcg.c | 8 ++++++++
11
1 file changed, 3 insertions(+), 4 deletions(-)
15
2 files changed, 8 insertions(+), 7 deletions(-)
16
12
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
13
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.c
15
--- a/target/arm/cpu.c
20
+++ b/target/arm/cpu.c
16
+++ b/target/arm/cpu.c
21
@@ -XXX,XX +XXX,XX @@ static const TypeInfo arm_cpu_type_info = {
17
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
22
.class_init = arm_cpu_class_init,
18
/* and to the FP/Neon instructions */
23
};
19
env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
24
20
CPACR_EL1, FPEN, 3);
25
-static const TypeInfo idau_interface_type_info = {
21
- /* and to the SVE instructions */
26
- .name = TYPE_IDAU_INTERFACE,
22
- env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
27
- .parent = TYPE_INTERFACE,
23
- CPACR_EL1, ZEN, 3);
28
- .class_size = sizeof(IDAUInterfaceClass),
24
- /* with reasonable vector length */
29
-};
25
+ /* and to the SVE instructions, with default vector length */
30
-
26
if (cpu_isar_feature(aa64_sve, cpu)) {
31
static void arm_cpu_register_types(void)
27
+ env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
32
{
28
+ CPACR_EL1, ZEN, 3);
33
const size_t cpu_count = ARRAY_SIZE(arm_cpus);
29
env->vfp.zcr_el[1] = cpu->sve_default_vq - 1;
34
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_register_types(void)
35
if (cpu_count) {
36
size_t i;
37
38
- type_register_static(&idau_interface_type_info);
39
for (i = 0; i < cpu_count; ++i) {
40
arm_cpu_register(&arm_cpus[i]);
41
}
30
}
42
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
31
/*
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/cpu_tcg.c
45
+++ b/target/arm/cpu_tcg.c
46
@@ -XXX,XX +XXX,XX @@
47
#include "hw/core/tcg-cpu-ops.h"
48
#endif /* CONFIG_TCG */
49
#include "internals.h"
50
+#include "target/arm/idau.h"
51
52
/* CPU models. These are not needed for the AArch64 linux-user build. */
53
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
54
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = {
55
{ .name = "pxa270-c5", .initfn = pxa270c5_initfn },
56
};
57
58
+static const TypeInfo idau_interface_type_info = {
59
+ .name = TYPE_IDAU_INTERFACE,
60
+ .parent = TYPE_INTERFACE,
61
+ .class_size = sizeof(IDAUInterfaceClass),
62
+};
63
+
64
static void arm_tcg_cpu_register_types(void)
65
{
66
size_t i;
67
68
+ type_register_static(&idau_interface_type_info);
69
for (i = 0; i < ARRAY_SIZE(arm_tcg_cpus); ++i) {
70
arm_cpu_register(&arm_tcg_cpus[i]);
71
}
72
--
32
--
73
2.20.1
33
2.25.1
74
75
diff view generated by jsdifflib
1
From: Rebecca Cran <rebecca@nuviainc.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Enable FEAT_SSBS for the "max" 32-bit CPU.
3
Enable SME, TPIDR2_EL0, and FA64 if supported by the cpu.
4
4
5
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210216224543.16142-4-rebecca@nuviainc.com
7
Message-id: 20220708151540.18136-45-richard.henderson@linaro.org
8
[PMM: fix typo causing compilation failure]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
target/arm/cpu.c | 4 ++++
10
target/arm/cpu.c | 11 +++++++++++
12
1 file changed, 4 insertions(+)
11
1 file changed, 11 insertions(+)
13
12
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
13
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.c
15
--- a/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
16
+++ b/target/arm/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
17
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
19
t = cpu->isar.id_pfr0;
18
CPACR_EL1, ZEN, 3);
20
t = FIELD_DP32(t, ID_PFR0, DIT, 1);
19
env->vfp.zcr_el[1] = cpu->sve_default_vq - 1;
21
cpu->isar.id_pfr0 = t;
20
}
22
+
21
+ /* and for SME instructions, with default vector length, and TPIDR2 */
23
+ t = cpu->isar.id_pfr2;
22
+ if (cpu_isar_feature(aa64_sme, cpu)) {
24
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
23
+ env->cp15.sctlr_el[1] |= SCTLR_EnTP2;
25
+ cpu->isar.id_pfr2 = t;
24
+ env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
26
}
25
+ CPACR_EL1, SMEN, 3);
27
#endif
26
+ env->vfp.smcr_el[1] = cpu->sme_default_vq - 1;
28
}
27
+ if (cpu_isar_feature(aa64_sme_fa64, cpu)) {
28
+ env->vfp.smcr_el[1] = FIELD_DP64(env->vfp.smcr_el[1],
29
+ SMCR, FA64, 1);
30
+ }
31
+ }
32
/*
33
* Enable 48-bit address space (TODO: take reserved_va into account).
34
* Enable TBI0 but not TBI1.
29
--
35
--
30
2.20.1
36
2.25.1
31
32
diff view generated by jsdifflib
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Let add 'max' cpu while work goes on adding newer CPU types than
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Cortex-A72. This allows us to check SVE etc support.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
5
Message-id: 20220708151540.18136-46-richard.henderson@linaro.org
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
7
Acked-by: Leif Lindholm <leif@nuviainc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210216150122.3830863-3-marcin.juszkiewicz@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
7
---
12
hw/arm/sbsa-ref.c | 1 +
8
linux-user/elfload.c | 20 ++++++++++++++++++++
13
1 file changed, 1 insertion(+)
9
1 file changed, 20 insertions(+)
14
10
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
11
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/sbsa-ref.c
13
--- a/linux-user/elfload.c
18
+++ b/hw/arm/sbsa-ref.c
14
+++ b/linux-user/elfload.c
19
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
15
@@ -XXX,XX +XXX,XX @@ enum {
20
static const char * const valid_cpus[] = {
16
ARM_HWCAP2_A64_RNG = 1 << 16,
21
ARM_CPU_TYPE_NAME("cortex-a57"),
17
ARM_HWCAP2_A64_BTI = 1 << 17,
22
ARM_CPU_TYPE_NAME("cortex-a72"),
18
ARM_HWCAP2_A64_MTE = 1 << 18,
23
+ ARM_CPU_TYPE_NAME("max"),
19
+ ARM_HWCAP2_A64_ECV = 1 << 19,
20
+ ARM_HWCAP2_A64_AFP = 1 << 20,
21
+ ARM_HWCAP2_A64_RPRES = 1 << 21,
22
+ ARM_HWCAP2_A64_MTE3 = 1 << 22,
23
+ ARM_HWCAP2_A64_SME = 1 << 23,
24
+ ARM_HWCAP2_A64_SME_I16I64 = 1 << 24,
25
+ ARM_HWCAP2_A64_SME_F64F64 = 1 << 25,
26
+ ARM_HWCAP2_A64_SME_I8I32 = 1 << 26,
27
+ ARM_HWCAP2_A64_SME_F16F32 = 1 << 27,
28
+ ARM_HWCAP2_A64_SME_B16F32 = 1 << 28,
29
+ ARM_HWCAP2_A64_SME_F32F32 = 1 << 29,
30
+ ARM_HWCAP2_A64_SME_FA64 = 1 << 30,
24
};
31
};
25
32
26
static bool cpu_type_valid(const char *cpu)
33
#define ELF_HWCAP get_elf_hwcap()
34
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
35
GET_FEATURE_ID(aa64_rndr, ARM_HWCAP2_A64_RNG);
36
GET_FEATURE_ID(aa64_bti, ARM_HWCAP2_A64_BTI);
37
GET_FEATURE_ID(aa64_mte, ARM_HWCAP2_A64_MTE);
38
+ GET_FEATURE_ID(aa64_sme, (ARM_HWCAP2_A64_SME |
39
+ ARM_HWCAP2_A64_SME_F32F32 |
40
+ ARM_HWCAP2_A64_SME_B16F32 |
41
+ ARM_HWCAP2_A64_SME_F16F32 |
42
+ ARM_HWCAP2_A64_SME_I8I32));
43
+ GET_FEATURE_ID(aa64_sme_f64f64, ARM_HWCAP2_A64_SME_F64F64);
44
+ GET_FEATURE_ID(aa64_sme_i16i64, ARM_HWCAP2_A64_SME_I16I64);
45
+ GET_FEATURE_ID(aa64_sme_fa64, ARM_HWCAP2_A64_SME_FA64);
46
47
return hwcaps;
48
}
27
--
49
--
28
2.20.1
50
2.25.1
29
30
diff view generated by jsdifflib
Deleted patch
1
For a long time now the UI layer has guaranteed that the console
2
surface is always 32 bits per pixel RGB. Remove the legacy dead
3
code from the tc6393xb display device which was handling the
4
possibility that the console surface was some other format.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215103215.4944-3-peter.maydell@linaro.org
9
---
10
include/ui/console.h | 10 ----------
11
hw/display/tc6393xb.c | 33 +--------------------------------
12
2 files changed, 1 insertion(+), 42 deletions(-)
13
14
diff --git a/include/ui/console.h b/include/ui/console.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/ui/console.h
17
+++ b/include/ui/console.h
18
@@ -XXX,XX +XXX,XX @@ PixelFormat qemu_default_pixelformat(int bpp);
19
DisplaySurface *qemu_create_displaysurface(int width, int height);
20
void qemu_free_displaysurface(DisplaySurface *surface);
21
22
-static inline int is_surface_bgr(DisplaySurface *surface)
23
-{
24
- if (PIXMAN_FORMAT_BPP(surface->format) == 32 &&
25
- PIXMAN_FORMAT_TYPE(surface->format) == PIXMAN_TYPE_ABGR) {
26
- return 1;
27
- } else {
28
- return 0;
29
- }
30
-}
31
-
32
static inline int is_buffer_shared(DisplaySurface *surface)
33
{
34
return !(surface->flags & QEMU_ALLOCATED_FLAG);
35
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/display/tc6393xb.c
38
+++ b/hw/display/tc6393xb.c
39
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
40
(uint32_t) addr, value & 0xff);
41
}
42
43
-#define BITS 8
44
-#include "tc6393xb_template.h"
45
-#define BITS 15
46
-#include "tc6393xb_template.h"
47
-#define BITS 16
48
-#include "tc6393xb_template.h"
49
-#define BITS 24
50
-#include "tc6393xb_template.h"
51
#define BITS 32
52
#include "tc6393xb_template.h"
53
54
static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
55
{
56
- DisplaySurface *surface = qemu_console_surface(s->con);
57
-
58
- switch (surface_bits_per_pixel(surface)) {
59
- case 8:
60
- tc6393xb_draw_graphic8(s);
61
- break;
62
- case 15:
63
- tc6393xb_draw_graphic15(s);
64
- break;
65
- case 16:
66
- tc6393xb_draw_graphic16(s);
67
- break;
68
- case 24:
69
- tc6393xb_draw_graphic24(s);
70
- break;
71
- case 32:
72
- tc6393xb_draw_graphic32(s);
73
- break;
74
- default:
75
- printf("tc6393xb: unknown depth %d\n",
76
- surface_bits_per_pixel(surface));
77
- return;
78
- }
79
-
80
+ tc6393xb_draw_graphic32(s);
81
dpy_gfx_update_full(s->con);
82
}
83
84
--
85
2.20.1
86
87
diff view generated by jsdifflib
Deleted patch
1
Now the template header is included only for BITS==32, expand
2
out all the macros that depended on the BITS setting.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210215103215.4944-4-peter.maydell@linaro.org
7
---
8
hw/display/tc6393xb_template.h | 35 ++++------------------------------
9
1 file changed, 4 insertions(+), 31 deletions(-)
10
11
diff --git a/hw/display/tc6393xb_template.h b/hw/display/tc6393xb_template.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/display/tc6393xb_template.h
14
+++ b/hw/display/tc6393xb_template.h
15
@@ -XXX,XX +XXX,XX @@
16
* with this program; if not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
-#if BITS == 8
20
-# define SET_PIXEL(addr, color) (*(uint8_t *)addr = color)
21
-#elif BITS == 15 || BITS == 16
22
-# define SET_PIXEL(addr, color) (*(uint16_t *)addr = color)
23
-#elif BITS == 24
24
-# define SET_PIXEL(addr, color) \
25
- do { \
26
- addr[0] = color; \
27
- addr[1] = (color) >> 8; \
28
- addr[2] = (color) >> 16; \
29
- } while (0)
30
-#elif BITS == 32
31
-# define SET_PIXEL(addr, color) (*(uint32_t *)addr = color)
32
-#else
33
-# error unknown bit depth
34
-#endif
35
-
36
-
37
-static void glue(tc6393xb_draw_graphic, BITS)(TC6393xbState *s)
38
+static void tc6393xb_draw_graphic32(TC6393xbState *s)
39
{
40
DisplaySurface *surface = qemu_console_surface(s->con);
41
int i;
42
@@ -XXX,XX +XXX,XX @@ static void glue(tc6393xb_draw_graphic, BITS)(TC6393xbState *s)
43
data_buffer = s->vram_ptr;
44
data_display = surface_data(surface);
45
for(i = 0; i < s->scr_height; i++) {
46
-#if (BITS == 16)
47
- memcpy(data_display, data_buffer, s->scr_width * 2);
48
- data_buffer += s->scr_width;
49
- data_display += surface_stride(surface);
50
-#else
51
int j;
52
- for (j = 0; j < s->scr_width; j++, data_display += BITS / 8, data_buffer++) {
53
+ for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
54
uint16_t color = *data_buffer;
55
- uint32_t dest_color = glue(rgb_to_pixel, BITS)(
56
+ uint32_t dest_color = rgb_to_pixel32(
57
((color & 0xf800) * 0x108) >> 11,
58
((color & 0x7e0) * 0x41) >> 9,
59
((color & 0x1f) * 0x21) >> 2
60
);
61
- SET_PIXEL(data_display, dest_color);
62
+ *(uint32_t *)data_display = dest_color;
63
}
64
-#endif
65
}
66
}
67
-
68
-#undef BITS
69
-#undef SET_PIXEL
70
--
71
2.20.1
72
73
diff view generated by jsdifflib
Deleted patch
1
The draw_line16_32() function in the omap_lcdc template header
2
includes an ifdef for the case where HOST_WORDS_BIGENDIAN matches
3
TARGET_WORDS_BIGENDIAN. This is trying to optimise for "source
4
bitmap and destination bitmap format match", but it is broken,
5
because in this function the formats don't match: the source is
6
16-bit colour and the destination is 32-bit colour, so a memcpy()
7
will produce corrupted graphics output. Drop the bogus ifdef.
8
1
9
This bug was introduced in commit ea644cf343129, when we dropped
10
support for DEPTH values other than 32 from the template header.
11
The old #if line was
12
#if DEPTH == 16 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
13
and this was mistakenly changed to
14
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
15
rather than deleting the #if as now having an always-false condition.
16
17
Fixes: ea644cf343129
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20210215103215.4944-7-peter.maydell@linaro.org
22
---
23
hw/display/omap_lcd_template.h | 4 ----
24
1 file changed, 4 deletions(-)
25
26
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/display/omap_lcd_template.h
29
+++ b/hw/display/omap_lcd_template.h
30
@@ -XXX,XX +XXX,XX @@ static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
31
static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
32
int width, int deststep)
33
{
34
-#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
35
- memcpy(d, s, width * 2);
36
-#else
37
uint16_t v;
38
uint8_t r, g, b;
39
40
@@ -XXX,XX +XXX,XX @@ static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
41
s += 2;
42
d += 4;
43
} while (-- width != 0);
44
-#endif
45
}
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
Deleted patch
1
Fix some minor coding style issues in the template header,
2
so checkpatch doesn't complain when we move the code.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210215103215.4944-8-peter.maydell@linaro.org
8
---
9
hw/display/omap_lcd_template.h | 6 +++---
10
1 file changed, 3 insertions(+), 3 deletions(-)
11
12
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/display/omap_lcd_template.h
15
+++ b/hw/display/omap_lcd_template.h
16
@@ -XXX,XX +XXX,XX @@ static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
17
b = (pal[v & 3] << 4) & 0xf0;
18
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
19
d += 4;
20
- s ++;
21
+ s++;
22
width -= 4;
23
} while (width > 0);
24
}
25
@@ -XXX,XX +XXX,XX @@ static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
26
b = (pal[v & 0xf] << 4) & 0xf0;
27
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
28
d += 4;
29
- s ++;
30
+ s++;
31
width -= 2;
32
} while (width > 0);
33
}
34
@@ -XXX,XX +XXX,XX @@ static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
35
g = pal[v] & 0xf0;
36
b = (pal[v] << 4) & 0xf0;
37
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
38
- s ++;
39
+ s++;
40
d += 4;
41
} while (-- width != 0);
42
}
43
--
44
2.20.1
45
46
diff view generated by jsdifflib