1
From: Alistair Francis <alistair.francis@wdc.com>
1
The following changes since commit c5ea91da443b458352c1b629b490ee6631775cb4:
2
2
3
The following changes since commit 239b8b0699a222fd21da1c5fdeba0a2456085a47:
3
Merge tag 'pull-trivial-patches' of https://gitlab.com/mjt0k/qemu into staging (2023-09-08 10:06:25 -0400)
4
5
Merge tag 'trivial-branch-for-8.0-pull-request' of https://gitlab.com/laurent_vivier/qemu into staging (2023-01-19 15:05:29 +0000)
6
4
7
are available in the Git repository at:
5
are available in the Git repository at:
8
6
9
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20230120
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20230911
10
8
11
for you to fetch changes up to b748352c555b42d497fe8ee00ee2e44eb8627660:
9
for you to fetch changes up to e7a03409f29e2da59297d55afbaec98c96e43e3a:
12
10
13
hw/riscv/virt.c: move create_fw_cfg() back to virt_machine_init() (2023-01-20 10:14:14 +1000)
11
target/riscv: don't read CSR in riscv_csrrw_do64 (2023-09-11 11:45:55 +1000)
14
12
15
----------------------------------------------------------------
13
----------------------------------------------------------------
16
Second RISC-V PR for QEMU 8.0
14
First RISC-V PR for 8.2
17
15
18
* riscv_htif: Support console output via proxy syscall
16
* Remove 'host' CPU from TCG
19
* Cleanup firmware and device tree loading
17
* riscv_htif Fixup printing on big endian hosts
20
* Fix elen check when using vector extensions
18
* Add zmmul isa string
21
* add RISC-V OpenSBI boot test
19
* Add smepmp isa string
22
* Ensure we always follow MISA parsing
20
* Fix page_check_range use in fault-only-first
23
* Fix up masking of vsip/vsie accesses
21
* Use existing lookup tables for MixColumns
24
* Trap on writes to stimecmp from VS when hvictl.VTI=1
22
* Add RISC-V vector cryptographic instruction set support
25
* Introduce helper_set_rounding_mode_chkfrm
23
* Implement WARL behaviour for mcountinhibit/mcounteren
24
* Add Zihintntl extension ISA string to DTS
25
* Fix zfa fleq.d and fltq.d
26
* Fix upper/lower mtime write calculation
27
* Make rtc variable names consistent
28
* Use abi type for linux-user target_ucontext
29
* Add RISC-V KVM AIA Support
30
* Fix riscv,pmu DT node path in the virt machine
31
* Update CSR bits name for svadu extension
32
* Mark zicond non-experimental
33
* Fix satp_mode_finalize() when satp_mode.supported = 0
34
* Fix non-KVM --enable-debug build
35
* Add new extensions to hwprobe
36
* Use accelerated helper for AES64KS1I
37
* Allocate itrigger timers only once
38
* Respect mseccfg.RLB for pmpaddrX changes
39
* Align the AIA model to v1.0 ratified spec
40
* Don't read the CSR in riscv_csrrw_do64
26
41
27
----------------------------------------------------------------
42
----------------------------------------------------------------
28
Andrew Bresticker (2):
43
Akihiko Odaki (1):
29
target/riscv: Fix up masking of vsip/vsie accesses
44
target/riscv: Allocate itrigger timers only once
30
target/riscv: Trap on writes to stimecmp from VS when hvictl.VTI=1
31
45
32
Bin Meng (11):
46
Ard Biesheuvel (2):
33
hw/char: riscv_htif: Avoid using magic numbers
47
target/riscv: Use existing lookup tables for MixColumns
34
hw/char: riscv_htif: Drop {to, from}host_size in HTIFState
48
target/riscv: Use accelerated helper for AES64KS1I
35
hw/char: riscv_htif: Drop useless assignment of memory region
36
hw/char: riscv_htif: Use conventional 's' for HTIFState
37
hw/char: riscv_htif: Move registers from CPUArchState to HTIFState
38
hw/char: riscv_htif: Remove forward declarations for non-existent variables
39
hw/char: riscv_htif: Support console output via proxy syscall
40
hw/riscv: spike: Remove the out-of-date comments
41
hw/riscv/boot.c: Introduce riscv_find_firmware()
42
hw/riscv: spike: Decouple create_fdt() dependency to ELF loading
43
target/riscv: Use TARGET_FMT_lx for env->mhartid
44
49
45
Daniel Henrique Barboza (20):
50
Conor Dooley (1):
46
hw/riscv/boot.c: make riscv_find_firmware() static
51
hw/riscv: virt: Fix riscv,pmu DT node path
47
hw/riscv/boot.c: introduce riscv_default_firmware_name()
48
tests/avocado: add RISC-V OpenSBI boot test
49
hw/riscv/spike: use 'fdt' from MachineState
50
hw/riscv/sifive_u: use 'fdt' from MachineState
51
hw/riscv/boot.c: exit early if filename is NULL in load functions
52
hw/riscv/spike.c: load initrd right after riscv_load_kernel()
53
hw/riscv: write initrd 'chosen' FDT inside riscv_load_initrd()
54
hw/riscv: write bootargs 'chosen' FDT after riscv_load_kernel()
55
hw/riscv/boot.c: use MachineState in riscv_load_initrd()
56
hw/riscv/boot.c: use MachineState in riscv_load_kernel()
57
target/riscv/cpu: set cpu->cfg in register_cpu_props()
58
target/riscv/cpu.c: do not skip misa logic in riscv_cpu_realize()
59
hw/riscv/spike.c: simplify create_fdt()
60
hw/riscv/virt.c: simplify create_fdt()
61
hw/riscv/sifive_u.c: simplify create_fdt()
62
hw/riscv/virt.c: remove 'is_32_bit' param from create_fdt_socket_cpus()
63
hw/riscv: use MachineState::fdt in riscv_socket_fdt_write_id()
64
hw/riscv: use ms->fdt in riscv_socket_fdt_write_distance_matrix()
65
hw/riscv/virt.c: move create_fw_cfg() back to virt_machine_init()
66
52
67
Dongxue Zhang (1):
53
Daniel Henrique Barboza (6):
68
target/riscv/cpu.c: Fix elen check
54
target/riscv/cpu.c: do not run 'host' CPU with TCG
55
target/riscv/cpu.c: add zmmul isa string
56
target/riscv/cpu.c: add smepmp isa string
57
target/riscv: fix satp_mode_finalize() when satp_mode.supported = 0
58
hw/riscv/virt.c: fix non-KVM --enable-debug build
59
hw/intc/riscv_aplic.c fix non-KVM --enable-debug build
69
60
70
Richard Henderson (3):
61
Dickon Hood (2):
71
tcg/riscv: Use tcg_pcrel_diff in tcg_out_ldst
62
target/riscv: Refactor translation of vector-widening instruction
72
target/riscv: Introduce helper_set_rounding_mode_chkfrm
63
target/riscv: Add Zvbb ISA extension support
73
target/riscv: Remove helper_set_rod_rounding_mode
74
64
75
include/hw/char/riscv_htif.h | 19 +-
65
Jason Chien (3):
76
include/hw/riscv/boot.h | 9 +-
66
target/riscv: Add Zihintntl extension ISA string to DTS
77
include/hw/riscv/numa.h | 10 +-
67
hw/intc: Fix upper/lower mtime write calculation
78
include/hw/riscv/sifive_u.h | 3 -
68
hw/intc: Make rtc variable names consistent
79
include/hw/riscv/spike.h | 2 -
69
80
target/riscv/cpu.h | 8 +-
70
Kiran Ostrolenk (4):
81
target/riscv/helper.h | 2 +-
71
target/riscv: Refactor some of the generic vector functionality
82
hw/char/riscv_htif.c | 172 +++++++-----
72
target/riscv: Refactor vector-vector translation macro
83
hw/riscv/boot.c | 105 +++++---
73
target/riscv: Refactor some of the generic vector functionality
84
hw/riscv/microchip_pfsoc.c | 12 +-
74
target/riscv: Add Zvknh ISA extension support
85
hw/riscv/numa.c | 14 +-
75
86
hw/riscv/opentitan.c | 3 +-
76
LIU Zhiwei (3):
87
hw/riscv/sifive_e.c | 3 +-
77
target/riscv: Fix page_check_range use in fault-only-first
88
hw/riscv/sifive_u.c | 53 ++--
78
target/riscv: Fix zfa fleq.d and fltq.d
89
hw/riscv/spike.c | 108 ++++----
79
linux-user/riscv: Use abi type for target_ucontext
90
hw/riscv/virt.c | 86 +++---
80
91
target/riscv/cpu.c | 445 ++++++++++++++++++--------------
81
Lawrence Hunter (2):
92
target/riscv/csr.c | 41 ++-
82
target/riscv: Add Zvbc ISA extension support
93
target/riscv/fpu_helper.c | 36 ++-
83
target/riscv: Add Zvksh ISA extension support
94
target/riscv/machine.c | 6 +-
84
95
target/riscv/translate.c | 21 +-
85
Leon Schuermann (1):
96
target/riscv/insn_trans/trans_rvv.c.inc | 24 +-
86
target/riscv/pmp.c: respect mseccfg.RLB for pmpaddrX changes
97
tcg/riscv/tcg-target.c.inc | 2 +-
87
98
tests/avocado/riscv_opensbi.py | 65 +++++
88
Max Chou (3):
99
24 files changed, 713 insertions(+), 536 deletions(-)
89
crypto: Create sm4_subword
100
create mode 100644 tests/avocado/riscv_opensbi.py
90
crypto: Add SM4 constant parameter CK
91
target/riscv: Add Zvksed ISA extension support
92
93
Nazar Kazakov (4):
94
target/riscv: Remove redundant "cpu_vl == 0" checks
95
target/riscv: Move vector translation checks
96
target/riscv: Add Zvkned ISA extension support
97
target/riscv: Add Zvkg ISA extension support
98
99
Nikita Shubin (1):
100
target/riscv: don't read CSR in riscv_csrrw_do64
101
102
Rob Bradford (1):
103
target/riscv: Implement WARL behaviour for mcountinhibit/mcounteren
104
105
Robbin Ehn (1):
106
linux-user/riscv: Add new extensions to hwprobe
107
108
Thomas Huth (2):
109
hw/char/riscv_htif: Fix printing of console characters on big endian hosts
110
hw/char/riscv_htif: Fix the console syscall on big endian hosts
111
112
Tommy Wu (1):
113
target/riscv: Align the AIA model to v1.0 ratified spec
114
115
Vineet Gupta (1):
116
riscv: zicond: make non-experimental
117
118
Weiwei Li (1):
119
target/riscv: Update CSR bits name for svadu extension
120
121
Yong-Xuan Wang (5):
122
target/riscv: support the AIA device emulation with KVM enabled
123
target/riscv: check the in-kernel irqchip support
124
target/riscv: Create an KVM AIA irqchip
125
target/riscv: update APLIC and IMSIC to support KVM AIA
126
target/riscv: select KVM AIA in riscv virt machine
127
128
include/crypto/aes.h | 7 +
129
include/crypto/sm4.h | 9 +
130
target/riscv/cpu_bits.h | 8 +-
131
target/riscv/cpu_cfg.h | 9 +
132
target/riscv/debug.h | 3 +-
133
target/riscv/helper.h | 98 +++
134
target/riscv/kvm_riscv.h | 5 +
135
target/riscv/vector_internals.h | 228 +++++++
136
target/riscv/insn32.decode | 58 ++
137
crypto/aes.c | 4 +-
138
crypto/sm4.c | 10 +
139
hw/char/riscv_htif.c | 12 +-
140
hw/intc/riscv_aclint.c | 11 +-
141
hw/intc/riscv_aplic.c | 52 +-
142
hw/intc/riscv_imsic.c | 25 +-
143
hw/riscv/virt.c | 374 ++++++------
144
linux-user/riscv/signal.c | 4 +-
145
linux-user/syscall.c | 14 +-
146
target/arm/tcg/crypto_helper.c | 10 +-
147
target/riscv/cpu.c | 83 ++-
148
target/riscv/cpu_helper.c | 6 +-
149
target/riscv/crypto_helper.c | 51 +-
150
target/riscv/csr.c | 54 +-
151
target/riscv/debug.c | 15 +-
152
target/riscv/kvm.c | 201 ++++++-
153
target/riscv/pmp.c | 4 +
154
target/riscv/translate.c | 1 +
155
target/riscv/vcrypto_helper.c | 970 ++++++++++++++++++++++++++++++
156
target/riscv/vector_helper.c | 245 +-------
157
target/riscv/vector_internals.c | 81 +++
158
target/riscv/insn_trans/trans_rvv.c.inc | 171 +++---
159
target/riscv/insn_trans/trans_rvvk.c.inc | 606 +++++++++++++++++++
160
target/riscv/insn_trans/trans_rvzfa.c.inc | 4 +-
161
target/riscv/meson.build | 4 +-
162
34 files changed, 2785 insertions(+), 652 deletions(-)
163
create mode 100644 target/riscv/vector_internals.h
164
create mode 100644 target/riscv/vcrypto_helper.c
165
create mode 100644 target/riscv/vector_internals.c
166
create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
All RISCV CPUs are setting cpu->cfg during their cpu_init() functions,
3
The 'host' CPU is available in a CONFIG_KVM build and it's currently
4
meaning that there's no reason to skip all the misa validation and setup
4
available for all accels, but is a KVM only CPU. This means that in a
5
if misa_ext was set beforehand - especially since we're setting an
5
RISC-V KVM capable host we can do things like this:
6
updated value in set_misa() in the end.
7
6
8
Put this code chunk into a new riscv_cpu_validate_set_extensions()
7
$ ./build/qemu-system-riscv64 -M virt,accel=tcg -cpu host --nographic
9
helper and always execute it regardless of what the board set in
8
qemu-system-riscv64: H extension requires priv spec 1.12.0
10
env->misa_ext.
11
9
12
This will put more responsibility in how each board is going to init
10
This CPU does not have a priv spec because we don't filter its extensions
13
their attributes and extensions if they're not using the defaults.
11
via priv spec. We shouldn't be reaching riscv_cpu_realize_tcg() at all
14
It'll also allow realize() to do its job looking only at the extensions
12
with the 'host' CPU.
15
enabled per se, not corner cases that some CPUs might have, and we won't
13
16
have to change multiple code paths to fix or change how extensions work.
14
We don't have a way to filter the 'host' CPU out of the available CPU
15
options (-cpu help) if the build includes both KVM and TCG. What we can
16
do is to error out during riscv_cpu_realize_tcg() if the user chooses
17
the 'host' CPU with accel=tcg:
18
19
$ ./build/qemu-system-riscv64 -M virt,accel=tcg -cpu host --nographic
20
qemu-system-riscv64: 'host' CPU is not compatible with TCG acceleration
17
21
18
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
19
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
20
Reviewed-by: Bin Meng <bmeng@tinylab.org>
24
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
21
Message-Id: <20230113175230.473975-3-dbarboza@ventanamicro.com>
25
Message-Id: <20230721133411.474105-1-dbarboza@ventanamicro.com>
22
[ Changes by AF:
23
- Rebase
24
]
25
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
26
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
26
---
27
---
27
target/riscv/cpu.c | 399 +++++++++++++++++++++++----------------------
28
target/riscv/cpu.c | 5 +++++
28
1 file changed, 205 insertions(+), 194 deletions(-)
29
1 file changed, 5 insertions(+)
29
30
30
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
31
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
31
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
32
--- a/target/riscv/cpu.c
33
--- a/target/riscv/cpu.c
33
+++ b/target/riscv/cpu.c
34
+++ b/target/riscv/cpu.c
34
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
35
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize_tcg(DeviceState *dev, Error **errp)
35
}
36
CPURISCVState *env = &cpu->env;
36
}
37
Error *local_err = NULL;
37
38
38
+/*
39
+ if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_CPU_HOST)) {
39
+ * Check consistency between chosen extensions while setting
40
+ error_setg(errp, "'host' CPU is not compatible with TCG acceleration");
40
+ * cpu->cfg accordingly, doing a set_misa() in the end.
41
+ */
42
+static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
43
+{
44
+ CPURISCVState *env = &cpu->env;
45
+ uint32_t ext = 0;
46
+
47
+ /* Do some ISA extension error checking */
48
+ if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m &&
49
+ cpu->cfg.ext_a && cpu->cfg.ext_f &&
50
+ cpu->cfg.ext_d &&
51
+ cpu->cfg.ext_icsr && cpu->cfg.ext_ifencei)) {
52
+ warn_report("Setting G will also set IMAFD_Zicsr_Zifencei");
53
+ cpu->cfg.ext_i = true;
54
+ cpu->cfg.ext_m = true;
55
+ cpu->cfg.ext_a = true;
56
+ cpu->cfg.ext_f = true;
57
+ cpu->cfg.ext_d = true;
58
+ cpu->cfg.ext_icsr = true;
59
+ cpu->cfg.ext_ifencei = true;
60
+ }
61
+
62
+ if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
63
+ error_setg(errp,
64
+ "I and E extensions are incompatible");
65
+ return;
41
+ return;
66
+ }
42
+ }
67
+
43
+
68
+ if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) {
44
riscv_cpu_validate_misa_mxl(cpu, &local_err);
69
+ error_setg(errp,
45
if (local_err != NULL) {
70
+ "Either I or E extension must be set");
46
error_propagate(errp, local_err);
71
+ return;
72
+ }
73
+
74
+ if (cpu->cfg.ext_s && !cpu->cfg.ext_u) {
75
+ error_setg(errp,
76
+ "Setting S extension without U extension is illegal");
77
+ return;
78
+ }
79
+
80
+ if (cpu->cfg.ext_h && !cpu->cfg.ext_i) {
81
+ error_setg(errp,
82
+ "H depends on an I base integer ISA with 32 x registers");
83
+ return;
84
+ }
85
+
86
+ if (cpu->cfg.ext_h && !cpu->cfg.ext_s) {
87
+ error_setg(errp, "H extension implicitly requires S-mode");
88
+ return;
89
+ }
90
+
91
+ if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) {
92
+ error_setg(errp, "F extension requires Zicsr");
93
+ return;
94
+ }
95
+
96
+ if ((cpu->cfg.ext_zawrs) && !cpu->cfg.ext_a) {
97
+ error_setg(errp, "Zawrs extension requires A extension");
98
+ return;
99
+ }
100
+
101
+ if ((cpu->cfg.ext_zfh || cpu->cfg.ext_zfhmin) && !cpu->cfg.ext_f) {
102
+ error_setg(errp, "Zfh/Zfhmin extensions require F extension");
103
+ return;
104
+ }
105
+
106
+ if (cpu->cfg.ext_d && !cpu->cfg.ext_f) {
107
+ error_setg(errp, "D extension requires F extension");
108
+ return;
109
+ }
110
+
111
+ if (cpu->cfg.ext_v && !cpu->cfg.ext_d) {
112
+ error_setg(errp, "V extension requires D extension");
113
+ return;
114
+ }
115
+
116
+ if ((cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) && !cpu->cfg.ext_f) {
117
+ error_setg(errp, "Zve32f/Zve64f extensions require F extension");
118
+ return;
119
+ }
120
+
121
+ /* Set the ISA extensions, checks should have happened above */
122
+ if (cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinx ||
123
+ cpu->cfg.ext_zhinxmin) {
124
+ cpu->cfg.ext_zfinx = true;
125
+ }
126
+
127
+ if (cpu->cfg.ext_zfinx) {
128
+ if (!cpu->cfg.ext_icsr) {
129
+ error_setg(errp, "Zfinx extension requires Zicsr");
130
+ return;
131
+ }
132
+ if (cpu->cfg.ext_f) {
133
+ error_setg(errp,
134
+ "Zfinx cannot be supported together with F extension");
135
+ return;
136
+ }
137
+ }
138
+
139
+ if (cpu->cfg.ext_zk) {
140
+ cpu->cfg.ext_zkn = true;
141
+ cpu->cfg.ext_zkr = true;
142
+ cpu->cfg.ext_zkt = true;
143
+ }
144
+
145
+ if (cpu->cfg.ext_zkn) {
146
+ cpu->cfg.ext_zbkb = true;
147
+ cpu->cfg.ext_zbkc = true;
148
+ cpu->cfg.ext_zbkx = true;
149
+ cpu->cfg.ext_zkne = true;
150
+ cpu->cfg.ext_zknd = true;
151
+ cpu->cfg.ext_zknh = true;
152
+ }
153
+
154
+ if (cpu->cfg.ext_zks) {
155
+ cpu->cfg.ext_zbkb = true;
156
+ cpu->cfg.ext_zbkc = true;
157
+ cpu->cfg.ext_zbkx = true;
158
+ cpu->cfg.ext_zksed = true;
159
+ cpu->cfg.ext_zksh = true;
160
+ }
161
+
162
+ if (cpu->cfg.ext_i) {
163
+ ext |= RVI;
164
+ }
165
+ if (cpu->cfg.ext_e) {
166
+ ext |= RVE;
167
+ }
168
+ if (cpu->cfg.ext_m) {
169
+ ext |= RVM;
170
+ }
171
+ if (cpu->cfg.ext_a) {
172
+ ext |= RVA;
173
+ }
174
+ if (cpu->cfg.ext_f) {
175
+ ext |= RVF;
176
+ }
177
+ if (cpu->cfg.ext_d) {
178
+ ext |= RVD;
179
+ }
180
+ if (cpu->cfg.ext_c) {
181
+ ext |= RVC;
182
+ }
183
+ if (cpu->cfg.ext_s) {
184
+ ext |= RVS;
185
+ }
186
+ if (cpu->cfg.ext_u) {
187
+ ext |= RVU;
188
+ }
189
+ if (cpu->cfg.ext_h) {
190
+ ext |= RVH;
191
+ }
192
+ if (cpu->cfg.ext_v) {
193
+ int vext_version = VEXT_VERSION_1_00_0;
194
+ ext |= RVV;
195
+ if (!is_power_of_2(cpu->cfg.vlen)) {
196
+ error_setg(errp,
197
+ "Vector extension VLEN must be power of 2");
198
+ return;
199
+ }
200
+ if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 128) {
201
+ error_setg(errp,
202
+ "Vector extension implementation only supports VLEN "
203
+ "in the range [128, %d]", RV_VLEN_MAX);
204
+ return;
205
+ }
206
+ if (!is_power_of_2(cpu->cfg.elen)) {
207
+ error_setg(errp,
208
+ "Vector extension ELEN must be power of 2");
209
+ return;
210
+ }
211
+ if (cpu->cfg.elen > 64 || cpu->cfg.elen < 8) {
212
+ error_setg(errp,
213
+ "Vector extension implementation only supports ELEN "
214
+ "in the range [8, 64]");
215
+ return;
216
+ }
217
+ if (cpu->cfg.vext_spec) {
218
+ if (!g_strcmp0(cpu->cfg.vext_spec, "v1.0")) {
219
+ vext_version = VEXT_VERSION_1_00_0;
220
+ } else {
221
+ error_setg(errp,
222
+ "Unsupported vector spec version '%s'",
223
+ cpu->cfg.vext_spec);
224
+ return;
225
+ }
226
+ } else {
227
+ qemu_log("vector version is not specified, "
228
+ "use the default value v1.0\n");
229
+ }
230
+ set_vext_version(env, vext_version);
231
+ }
232
+ if (cpu->cfg.ext_j) {
233
+ ext |= RVJ;
234
+ }
235
+
236
+ set_misa(env, env->misa_mxl, ext);
237
+}
238
+
239
static void riscv_cpu_realize(DeviceState *dev, Error **errp)
240
{
241
CPUState *cs = CPU(dev);
242
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
243
}
244
assert(env->misa_mxl_max == env->misa_mxl);
245
246
- /* If only MISA_EXT is unset for misa, then set it from properties */
247
- if (env->misa_ext == 0) {
248
- uint32_t ext = 0;
249
-
250
- /* Do some ISA extension error checking */
251
- if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m &&
252
- cpu->cfg.ext_a && cpu->cfg.ext_f &&
253
- cpu->cfg.ext_d &&
254
- cpu->cfg.ext_icsr && cpu->cfg.ext_ifencei)) {
255
- warn_report("Setting G will also set IMAFD_Zicsr_Zifencei");
256
- cpu->cfg.ext_i = true;
257
- cpu->cfg.ext_m = true;
258
- cpu->cfg.ext_a = true;
259
- cpu->cfg.ext_f = true;
260
- cpu->cfg.ext_d = true;
261
- cpu->cfg.ext_icsr = true;
262
- cpu->cfg.ext_ifencei = true;
263
- }
264
-
265
- if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
266
- error_setg(errp,
267
- "I and E extensions are incompatible");
268
- return;
269
- }
270
-
271
- if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) {
272
- error_setg(errp,
273
- "Either I or E extension must be set");
274
- return;
275
- }
276
-
277
- if (cpu->cfg.ext_s && !cpu->cfg.ext_u) {
278
- error_setg(errp,
279
- "Setting S extension without U extension is illegal");
280
- return;
281
- }
282
-
283
- if (cpu->cfg.ext_h && !cpu->cfg.ext_i) {
284
- error_setg(errp,
285
- "H depends on an I base integer ISA with 32 x registers");
286
- return;
287
- }
288
-
289
- if (cpu->cfg.ext_h && !cpu->cfg.ext_s) {
290
- error_setg(errp, "H extension implicitly requires S-mode");
291
- return;
292
- }
293
-
294
- if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) {
295
- error_setg(errp, "F extension requires Zicsr");
296
- return;
297
- }
298
-
299
- if ((cpu->cfg.ext_zawrs) && !cpu->cfg.ext_a) {
300
- error_setg(errp, "Zawrs extension requires A extension");
301
- return;
302
- }
303
-
304
- if ((cpu->cfg.ext_zfh || cpu->cfg.ext_zfhmin) && !cpu->cfg.ext_f) {
305
- error_setg(errp, "Zfh/Zfhmin extensions require F extension");
306
- return;
307
- }
308
-
309
- if (cpu->cfg.ext_d && !cpu->cfg.ext_f) {
310
- error_setg(errp, "D extension requires F extension");
311
- return;
312
- }
313
-
314
- if (cpu->cfg.ext_v && !cpu->cfg.ext_d) {
315
- error_setg(errp, "V extension requires D extension");
316
- return;
317
- }
318
-
319
- if ((cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) && !cpu->cfg.ext_f) {
320
- error_setg(errp, "Zve32f/Zve64f extensions require F extension");
321
- return;
322
- }
323
-
324
- /* Set the ISA extensions, checks should have happened above */
325
- if (cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinx ||
326
- cpu->cfg.ext_zhinxmin) {
327
- cpu->cfg.ext_zfinx = true;
328
- }
329
-
330
- if (cpu->cfg.ext_zfinx) {
331
- if (!cpu->cfg.ext_icsr) {
332
- error_setg(errp, "Zfinx extension requires Zicsr");
333
- return;
334
- }
335
- if (cpu->cfg.ext_f) {
336
- error_setg(errp,
337
- "Zfinx cannot be supported together with F extension");
338
- return;
339
- }
340
- }
341
-
342
- if (cpu->cfg.ext_zk) {
343
- cpu->cfg.ext_zkn = true;
344
- cpu->cfg.ext_zkr = true;
345
- cpu->cfg.ext_zkt = true;
346
- }
347
-
348
- if (cpu->cfg.ext_zkn) {
349
- cpu->cfg.ext_zbkb = true;
350
- cpu->cfg.ext_zbkc = true;
351
- cpu->cfg.ext_zbkx = true;
352
- cpu->cfg.ext_zkne = true;
353
- cpu->cfg.ext_zknd = true;
354
- cpu->cfg.ext_zknh = true;
355
- }
356
-
357
- if (cpu->cfg.ext_zks) {
358
- cpu->cfg.ext_zbkb = true;
359
- cpu->cfg.ext_zbkc = true;
360
- cpu->cfg.ext_zbkx = true;
361
- cpu->cfg.ext_zksed = true;
362
- cpu->cfg.ext_zksh = true;
363
- }
364
-
365
- if (cpu->cfg.ext_i) {
366
- ext |= RVI;
367
- }
368
- if (cpu->cfg.ext_e) {
369
- ext |= RVE;
370
- }
371
- if (cpu->cfg.ext_m) {
372
- ext |= RVM;
373
- }
374
- if (cpu->cfg.ext_a) {
375
- ext |= RVA;
376
- }
377
- if (cpu->cfg.ext_f) {
378
- ext |= RVF;
379
- }
380
- if (cpu->cfg.ext_d) {
381
- ext |= RVD;
382
- }
383
- if (cpu->cfg.ext_c) {
384
- ext |= RVC;
385
- }
386
- if (cpu->cfg.ext_s) {
387
- ext |= RVS;
388
- }
389
- if (cpu->cfg.ext_u) {
390
- ext |= RVU;
391
- }
392
- if (cpu->cfg.ext_h) {
393
- ext |= RVH;
394
- }
395
- if (cpu->cfg.ext_v) {
396
- int vext_version = VEXT_VERSION_1_00_0;
397
- ext |= RVV;
398
- if (!is_power_of_2(cpu->cfg.vlen)) {
399
- error_setg(errp,
400
- "Vector extension VLEN must be power of 2");
401
- return;
402
- }
403
- if (cpu->cfg.vlen > RV_VLEN_MAX || cpu->cfg.vlen < 128) {
404
- error_setg(errp,
405
- "Vector extension implementation only supports VLEN "
406
- "in the range [128, %d]", RV_VLEN_MAX);
407
- return;
408
- }
409
- if (!is_power_of_2(cpu->cfg.elen)) {
410
- error_setg(errp,
411
- "Vector extension ELEN must be power of 2");
412
- return;
413
- }
414
- if (cpu->cfg.elen > 64 || cpu->cfg.elen < 8) {
415
- error_setg(errp,
416
- "Vector extension implementation only supports ELEN "
417
- "in the range [8, 64]");
418
- return;
419
- }
420
- if (cpu->cfg.vext_spec) {
421
- if (!g_strcmp0(cpu->cfg.vext_spec, "v1.0")) {
422
- vext_version = VEXT_VERSION_1_00_0;
423
- } else {
424
- error_setg(errp,
425
- "Unsupported vector spec version '%s'",
426
- cpu->cfg.vext_spec);
427
- return;
428
- }
429
- } else {
430
- qemu_log("vector version is not specified, "
431
- "use the default value v1.0\n");
432
- }
433
- set_vext_version(env, vext_version);
434
- }
435
- if (cpu->cfg.ext_j) {
436
- ext |= RVJ;
437
- }
438
-
439
- set_misa(env, env->misa_mxl, ext);
440
+ riscv_cpu_validate_set_extensions(cpu, &local_err);
441
+ if (local_err != NULL) {
442
+ error_propagate(errp, local_err);
443
+ return;
444
}
445
446
#ifndef CONFIG_USER_ONLY
447
--
47
--
448
2.39.0
48
2.41.0
49
50
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
QEMU source codes tend to use 's' to represent the hardware state.
3
The character that should be printed is stored in the 64 bit "payload"
4
Let's use it for HTIFState.
4
variable. The code currently tries to print it by taking the address
5
of the variable and passing this pointer to qemu_chr_fe_write(). However,
6
this only works on little endian hosts where the least significant bits
7
are stored on the lowest address. To do this in a portable way, we have
8
to store the value in an uint8_t variable instead.
5
9
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
10
Fixes: 5033606780 ("RISC-V HTIF Console")
11
Signed-off-by: Thomas Huth <thuth@redhat.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Bin Meng <bmeng@tinylab.org>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-Id: <20221229091828.1945072-5-bmeng@tinylab.org>
16
Message-Id: <20230721094720.902454-2-thuth@redhat.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
18
---
12
hw/char/riscv_htif.c | 64 ++++++++++++++++++++++----------------------
19
hw/char/riscv_htif.c | 3 ++-
13
1 file changed, 32 insertions(+), 32 deletions(-)
20
1 file changed, 2 insertions(+), 1 deletion(-)
14
21
15
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
22
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
16
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/char/riscv_htif.c
24
--- a/hw/char/riscv_htif.c
18
+++ b/hw/char/riscv_htif.c
25
+++ b/hw/char/riscv_htif.c
19
@@ -XXX,XX +XXX,XX @@ static int htif_can_recv(void *opaque)
26
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
20
*/
27
s->tohost = 0; /* clear to indicate we read */
21
static void htif_recv(void *opaque, const uint8_t *buf, int size)
22
{
23
- HTIFState *htifstate = opaque;
24
+ HTIFState *s = opaque;
25
26
if (size != 1) {
27
return;
28
@@ -XXX,XX +XXX,XX @@ static void htif_recv(void *opaque, const uint8_t *buf, int size)
29
* will drop characters
30
*/
31
32
- uint64_t val_written = htifstate->pending_read;
33
+ uint64_t val_written = s->pending_read;
34
uint64_t resp = 0x100 | *buf;
35
36
- htifstate->env->mfromhost = (val_written >> 48 << 48) | (resp << 16 >> 16);
37
+ s->env->mfromhost = (val_written >> 48 << 48) | (resp << 16 >> 16);
38
}
39
40
/*
41
@@ -XXX,XX +XXX,XX @@ static int htif_be_change(void *opaque)
42
* For RV32, the tohost register is zero-extended, so only device=0 and
43
* command=0 (i.e. HTIF syscalls/exit codes) are supported.
44
*/
45
-static void htif_handle_tohost_write(HTIFState *htifstate, uint64_t val_written)
46
+static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
47
{
48
uint8_t device = val_written >> HTIF_DEV_SHIFT;
49
uint8_t cmd = val_written >> HTIF_CMD_SHIFT;
50
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *htifstate, uint64_t val_written)
51
/* HTIF Console */
52
if (cmd == HTIF_CONSOLE_CMD_GETC) {
53
/* this should be a queue, but not yet implemented as such */
54
- htifstate->pending_read = val_written;
55
- htifstate->env->mtohost = 0; /* clear to indicate we read */
56
+ s->pending_read = val_written;
57
+ s->env->mtohost = 0; /* clear to indicate we read */
58
return;
28
return;
59
} else if (cmd == HTIF_CONSOLE_CMD_PUTC) {
29
} else if (cmd == HTIF_CONSOLE_CMD_PUTC) {
60
- qemu_chr_fe_write(&htifstate->chr, (uint8_t *)&payload, 1);
30
- qemu_chr_fe_write(&s->chr, (uint8_t *)&payload, 1);
61
+ qemu_chr_fe_write(&s->chr, (uint8_t *)&payload, 1);
31
+ uint8_t ch = (uint8_t)payload;
32
+ qemu_chr_fe_write(&s->chr, &ch, 1);
62
resp = 0x100 | (uint8_t)payload;
33
resp = 0x100 | (uint8_t)payload;
63
} else {
34
} else {
64
qemu_log("HTIF device %d: unknown command\n", device);
35
qemu_log("HTIF device %d: unknown command\n", device);
65
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *htifstate, uint64_t val_written)
66
* With this code disabled, qemu works with bbl priv v1.9.1 and v1.10.
67
* HTIF needs protocol documentation and a more complete state machine.
68
*
69
- * while (!htifstate->fromhost_inprogress &&
70
- * htifstate->env->mfromhost != 0x0) {
71
+ * while (!s->fromhost_inprogress &&
72
+ * s->env->mfromhost != 0x0) {
73
* }
74
*/
75
- htifstate->env->mfromhost = (val_written >> 48 << 48) | (resp << 16 >> 16);
76
- htifstate->env->mtohost = 0; /* clear to indicate we read */
77
+ s->env->mfromhost = (val_written >> 48 << 48) | (resp << 16 >> 16);
78
+ s->env->mtohost = 0; /* clear to indicate we read */
79
}
80
81
-#define TOHOST_OFFSET1 (htifstate->tohost_offset)
82
-#define TOHOST_OFFSET2 (htifstate->tohost_offset + 4)
83
-#define FROMHOST_OFFSET1 (htifstate->fromhost_offset)
84
-#define FROMHOST_OFFSET2 (htifstate->fromhost_offset + 4)
85
+#define TOHOST_OFFSET1 (s->tohost_offset)
86
+#define TOHOST_OFFSET2 (s->tohost_offset + 4)
87
+#define FROMHOST_OFFSET1 (s->fromhost_offset)
88
+#define FROMHOST_OFFSET2 (s->fromhost_offset + 4)
89
90
/* CPU wants to read an HTIF register */
91
static uint64_t htif_mm_read(void *opaque, hwaddr addr, unsigned size)
92
{
93
- HTIFState *htifstate = opaque;
94
+ HTIFState *s = opaque;
95
if (addr == TOHOST_OFFSET1) {
96
- return htifstate->env->mtohost & 0xFFFFFFFF;
97
+ return s->env->mtohost & 0xFFFFFFFF;
98
} else if (addr == TOHOST_OFFSET2) {
99
- return (htifstate->env->mtohost >> 32) & 0xFFFFFFFF;
100
+ return (s->env->mtohost >> 32) & 0xFFFFFFFF;
101
} else if (addr == FROMHOST_OFFSET1) {
102
- return htifstate->env->mfromhost & 0xFFFFFFFF;
103
+ return s->env->mfromhost & 0xFFFFFFFF;
104
} else if (addr == FROMHOST_OFFSET2) {
105
- return (htifstate->env->mfromhost >> 32) & 0xFFFFFFFF;
106
+ return (s->env->mfromhost >> 32) & 0xFFFFFFFF;
107
} else {
108
qemu_log("Invalid htif read: address %016" PRIx64 "\n",
109
(uint64_t)addr);
110
@@ -XXX,XX +XXX,XX @@ static uint64_t htif_mm_read(void *opaque, hwaddr addr, unsigned size)
111
static void htif_mm_write(void *opaque, hwaddr addr,
112
uint64_t value, unsigned size)
113
{
114
- HTIFState *htifstate = opaque;
115
+ HTIFState *s = opaque;
116
if (addr == TOHOST_OFFSET1) {
117
- if (htifstate->env->mtohost == 0x0) {
118
- htifstate->allow_tohost = 1;
119
- htifstate->env->mtohost = value & 0xFFFFFFFF;
120
+ if (s->env->mtohost == 0x0) {
121
+ s->allow_tohost = 1;
122
+ s->env->mtohost = value & 0xFFFFFFFF;
123
} else {
124
- htifstate->allow_tohost = 0;
125
+ s->allow_tohost = 0;
126
}
127
} else if (addr == TOHOST_OFFSET2) {
128
- if (htifstate->allow_tohost) {
129
- htifstate->env->mtohost |= value << 32;
130
- htif_handle_tohost_write(htifstate, htifstate->env->mtohost);
131
+ if (s->allow_tohost) {
132
+ s->env->mtohost |= value << 32;
133
+ htif_handle_tohost_write(s, s->env->mtohost);
134
}
135
} else if (addr == FROMHOST_OFFSET1) {
136
- htifstate->fromhost_inprogress = 1;
137
- htifstate->env->mfromhost = value & 0xFFFFFFFF;
138
+ s->fromhost_inprogress = 1;
139
+ s->env->mfromhost = value & 0xFFFFFFFF;
140
} else if (addr == FROMHOST_OFFSET2) {
141
- htifstate->env->mfromhost |= value << 32;
142
- htifstate->fromhost_inprogress = 0;
143
+ s->env->mfromhost |= value << 32;
144
+ s->fromhost_inprogress = 0;
145
} else {
146
qemu_log("Invalid htif write: address %016" PRIx64 "\n",
147
(uint64_t)addr);
148
--
36
--
149
2.39.0
37
2.41.0
38
39
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
At present the HTIF proxy syscall is unsupported. On RV32, only
3
Values that have been read via cpu_physical_memory_read() from the
4
device 0 is supported so there is no console device for RV32.
4
guest's memory have to be swapped in case the host endianess differs
5
The only way to implement console funtionality on RV32 is to
5
from the guest.
6
support the SYS_WRITE syscall.
7
6
8
With this commit, the Spike machine is able to boot the 32-bit
7
Fixes: a6e13e31d5 ("riscv_htif: Support console output via proxy syscall")
9
OpenSBI generic image.
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
10
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Bin Meng <bmeng@tinylab.org>
10
Reviewed-by: Bin Meng <bmeng@tinylab.org>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-Id: <20230721094720.902454-3-thuth@redhat.com>
14
Message-Id: <20221229091828.1945072-8-bmeng@tinylab.org>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
14
---
17
hw/char/riscv_htif.c | 17 ++++++++++++++++-
15
hw/char/riscv_htif.c | 9 +++++----
18
1 file changed, 16 insertions(+), 1 deletion(-)
16
1 file changed, 5 insertions(+), 4 deletions(-)
19
17
20
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
18
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/char/riscv_htif.c
20
--- a/hw/char/riscv_htif.c
23
+++ b/hw/char/riscv_htif.c
21
+++ b/hw/char/riscv_htif.c
24
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
25
#define HTIF_CONSOLE_CMD_GETC 0
23
#include "qemu/timer.h"
26
#define HTIF_CONSOLE_CMD_PUTC 1
24
#include "qemu/error-report.h"
27
25
#include "exec/address-spaces.h"
28
+/* PK system call number */
26
+#include "exec/tswap.h"
29
+#define PK_SYS_WRITE 64
27
#include "sysemu/dma.h"
30
+
28
31
static uint64_t fromhost_addr, tohost_addr;
29
#define RISCV_DEBUG_HTIF 0
32
static int address_symbol_set;
33
34
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
30
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
35
int exit_code = payload >> 1;
36
exit(exit_code);
37
} else {
31
} else {
38
- qemu_log_mask(LOG_UNIMP, "pk syscall proxy not supported\n");
32
uint64_t syscall[8];
39
+ uint64_t syscall[8];
33
cpu_physical_memory_read(payload, syscall, sizeof(syscall));
40
+ cpu_physical_memory_read(payload, syscall, sizeof(syscall));
34
- if (syscall[0] == PK_SYS_WRITE &&
41
+ if (syscall[0] == PK_SYS_WRITE &&
35
- syscall[1] == HTIF_DEV_CONSOLE &&
42
+ syscall[1] == HTIF_DEV_CONSOLE &&
36
- syscall[3] == HTIF_CONSOLE_CMD_PUTC) {
43
+ syscall[3] == HTIF_CONSOLE_CMD_PUTC) {
37
+ if (tswap64(syscall[0]) == PK_SYS_WRITE &&
44
+ uint8_t ch;
38
+ tswap64(syscall[1]) == HTIF_DEV_CONSOLE &&
45
+ cpu_physical_memory_read(syscall[2], &ch, 1);
39
+ tswap64(syscall[3]) == HTIF_CONSOLE_CMD_PUTC) {
46
+ qemu_chr_fe_write(&s->chr, &ch, 1);
40
uint8_t ch;
47
+ resp = 0x100 | (uint8_t)payload;
41
- cpu_physical_memory_read(syscall[2], &ch, 1);
48
+ } else {
42
+ cpu_physical_memory_read(tswap64(syscall[2]), &ch, 1);
49
+ qemu_log_mask(LOG_UNIMP,
43
qemu_chr_fe_write(&s->chr, &ch, 1);
50
+ "pk syscall proxy not supported\n");
44
resp = 0x100 | (uint8_t)payload;
51
+ }
45
} else {
52
}
53
} else {
54
qemu_log("HTIF device %d: unknown command\n", device);
55
--
46
--
56
2.39.0
47
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
'cmdline' isn't being used. Remove it.
3
zmmul was promoted from experimental to ratified in commit 6d00ffad4e95.
4
Add a riscv,isa string for it.
4
5
5
A MachineState pointer is being retrieved via a MACHINE() macro calling
6
Fixes: 6d00ffad4e95 ("target/riscv: move zmmul out of the experimental properties")
6
qdev_get_machine(). Use MACHINE(s) instead to avoid calling qdev().
7
8
'mem_size' is being set as machine->ram_size by the caller. Retrieve it
9
via ms->ram_size.
10
11
Cc: Palmer Dabbelt <palmer@dabbelt.com>
12
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-Id: <20230111170948.316276-4-dbarboza@ventanamicro.com>
10
Message-Id: <20230720132424.371132-2-dbarboza@ventanamicro.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
12
---
18
hw/riscv/sifive_u.c | 8 ++++----
13
target/riscv/cpu.c | 1 +
19
1 file changed, 4 insertions(+), 4 deletions(-)
14
1 file changed, 1 insertion(+)
20
15
21
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
16
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/riscv/sifive_u.c
18
--- a/target/riscv/cpu.c
24
+++ b/hw/riscv/sifive_u.c
19
+++ b/target/riscv/cpu.c
25
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry sifive_u_memmap[] = {
20
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
26
#define GEM_REVISION 0x10070109
21
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
27
22
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
28
static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
23
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
29
- uint64_t mem_size, const char *cmdline, bool is_32_bit)
24
+ ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
30
+ bool is_32_bit)
25
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
31
{
26
ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
32
- MachineState *ms = MACHINE(qdev_get_machine());
27
ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
33
+ MachineState *ms = MACHINE(s);
34
+ uint64_t mem_size = ms->ram_size;
35
void *fdt;
36
int cpu, fdt_size;
37
uint32_t *cells;
38
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
39
qemu_allocate_irq(sifive_u_machine_reset, NULL, 0));
40
41
/* create device tree */
42
- create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
43
- riscv_is_32bit(&s->soc.u_cpus));
44
+ create_fdt(s, memmap, riscv_is_32bit(&s->soc.u_cpus));
45
46
if (s->start_in_flash) {
47
/*
48
--
28
--
49
2.39.0
29
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
'mem_size' and 'cmdline' are unused.
3
The cpu->cfg.epmp extension is still experimental, but it already has a
4
'smepmp' riscv,isa string. Add it.
4
5
5
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
6
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20230111170948.316276-2-dbarboza@ventanamicro.com>
9
Message-Id: <20230720132424.371132-3-dbarboza@ventanamicro.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
---
11
hw/riscv/spike.c | 4 +---
12
target/riscv/cpu.c | 1 +
12
1 file changed, 1 insertion(+), 3 deletions(-)
13
1 file changed, 1 insertion(+)
13
14
14
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
15
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/spike.c
17
--- a/target/riscv/cpu.c
17
+++ b/hw/riscv/spike.c
18
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry spike_memmap[] = {
19
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
19
};
20
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
20
21
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
21
static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
22
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
22
- uint64_t mem_size, const char *cmdline,
23
+ ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, epmp),
23
bool is_32_bit, bool htif_custom_base)
24
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
24
{
25
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
25
void *fdt;
26
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
26
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
27
}
28
29
/* Create device tree */
30
- create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
31
- riscv_is_32bit(&s->soc[0]), htif_custom_base);
32
+ create_fdt(s, memmap, riscv_is_32bit(&s->soc[0]), htif_custom_base);
33
34
/* Load kernel */
35
if (machine->kernel_filename) {
36
--
27
--
37
2.39.0
28
2.41.0
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
2
3
We failed to update this with the w^x split, so misses the fact
3
Commit bef6f008b98(accel/tcg: Return bool from page_check_range) converts
4
that true pc-relative offsets are usually small.
4
integer return value to bool type. However, it wrongly converted the use
5
of the API in riscv fault-only-first, where page_check_range < = 0, should
6
be converted to !page_check_range.
5
7
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-Id: <20230117230415.354239-1-richard.henderson@linaro.org>
10
Message-ID: <20230729031618.821-1-zhiwei_liu@linux.alibaba.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
12
---
11
tcg/riscv/tcg-target.c.inc | 2 +-
13
target/riscv/vector_helper.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
13
15
14
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
16
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/tcg/riscv/tcg-target.c.inc
18
--- a/target/riscv/vector_helper.c
17
+++ b/tcg/riscv/tcg-target.c.inc
19
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ static void tcg_out_ldst(TCGContext *s, RISCVInsn opc, TCGReg data,
20
@@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base,
19
intptr_t imm12 = sextreg(offset, 0, 12);
21
cpu_mmu_index(env, false));
20
22
if (host) {
21
if (offset != imm12) {
23
#ifdef CONFIG_USER_ONLY
22
- intptr_t diff = offset - (uintptr_t)s->code_ptr;
24
- if (page_check_range(addr, offset, PAGE_READ)) {
23
+ intptr_t diff = tcg_pcrel_diff(s, (void *)offset);
25
+ if (!page_check_range(addr, offset, PAGE_READ)) {
24
26
vl = i;
25
if (addr == TCG_REG_ZERO && diff == (int32_t)diff) {
27
goto ProbeSuccess;
26
imm12 = sextreg(diff, 0, 12);
28
}
27
--
29
--
28
2.39.0
30
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Ard Biesheuvel <ardb@kernel.org>
2
2
3
The MachineState object provides a 'fdt' pointer that is already being
3
The AES MixColumns and InvMixColumns operations are relatively
4
used by other RISC-V machines, and it's also used by the 'dumpdtb' QMP
4
expensive 4x4 matrix multiplications in GF(2^8), which is why C
5
command.
5
implementations usually rely on precomputed lookup tables rather than
6
performing the calculations on demand.
6
7
7
Remove the 'fdt' pointer from SpikeState and use MachineState::fdt
8
Given that we already carry those tables in QEMU, we can just grab the
8
instead.
9
right value in the implementation of the RISC-V AES32 instructions. Note
10
that the tables in question are permuted according to the respective
11
Sbox, so we can omit the Sbox lookup as well in this case.
9
12
10
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Cc: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Cc: Zewen Ye <lustrew@foxmail.com>
13
Reviewed-by: Bin Meng <bmeng@tinylab.org>
16
Cc: Weiwei Li <liweiwei@iscas.ac.cn>
14
Message-Id: <20230102115241.25733-3-dbarboza@ventanamicro.com>
17
Cc: Junqiang Wang <wangjunqiang@iscas.ac.cn>
18
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-ID: <20230731084043.1791984-1-ardb@kernel.org>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
22
---
17
include/hw/riscv/spike.h | 2 --
23
include/crypto/aes.h | 7 +++++++
18
hw/riscv/spike.c | 12 +++++-------
24
crypto/aes.c | 4 ++--
19
2 files changed, 5 insertions(+), 9 deletions(-)
25
target/riscv/crypto_helper.c | 34 ++++------------------------------
26
3 files changed, 13 insertions(+), 32 deletions(-)
20
27
21
diff --git a/include/hw/riscv/spike.h b/include/hw/riscv/spike.h
28
diff --git a/include/crypto/aes.h b/include/crypto/aes.h
22
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/riscv/spike.h
30
--- a/include/crypto/aes.h
24
+++ b/include/hw/riscv/spike.h
31
+++ b/include/crypto/aes.h
25
@@ -XXX,XX +XXX,XX @@ struct SpikeState {
32
@@ -XXX,XX +XXX,XX @@ void AES_decrypt(const unsigned char *in, unsigned char *out,
26
33
extern const uint8_t AES_sbox[256];
27
/*< public >*/
34
extern const uint8_t AES_isbox[256];
28
RISCVHartArrayState soc[SPIKE_SOCKETS_MAX];
35
29
- void *fdt;
36
+/*
30
- int fdt_size;
37
+AES_Te0[x] = S [x].[02, 01, 01, 03];
38
+AES_Td0[x] = Si[x].[0e, 09, 0d, 0b];
39
+*/
40
+
41
+extern const uint32_t AES_Te0[256], AES_Td0[256];
42
+
43
#endif
44
diff --git a/crypto/aes.c b/crypto/aes.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/crypto/aes.c
47
+++ b/crypto/aes.c
48
@@ -XXX,XX +XXX,XX @@ AES_Td3[x] = Si[x].[09, 0d, 0b, 0e];
49
AES_Td4[x] = Si[x].[01, 01, 01, 01];
50
*/
51
52
-static const uint32_t AES_Te0[256] = {
53
+const uint32_t AES_Te0[256] = {
54
0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
55
0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
56
0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
57
@@ -XXX,XX +XXX,XX @@ static const uint32_t AES_Te4[256] = {
58
0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
31
};
59
};
32
60
33
enum {
61
-static const uint32_t AES_Td0[256] = {
34
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
62
+const uint32_t AES_Td0[256] = {
63
0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
64
0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
65
0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
66
diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c
35
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/riscv/spike.c
68
--- a/target/riscv/crypto_helper.c
37
+++ b/hw/riscv/spike.c
69
+++ b/target/riscv/crypto_helper.c
38
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
70
@@ -XXX,XX +XXX,XX @@
39
bool is_32_bit, bool htif_custom_base)
71
#include "crypto/aes-round.h"
72
#include "crypto/sm4.h"
73
74
-#define AES_XTIME(a) \
75
- ((a << 1) ^ ((a & 0x80) ? 0x1b : 0))
76
-
77
-#define AES_GFMUL(a, b) (( \
78
- (((b) & 0x1) ? (a) : 0) ^ \
79
- (((b) & 0x2) ? AES_XTIME(a) : 0) ^ \
80
- (((b) & 0x4) ? AES_XTIME(AES_XTIME(a)) : 0) ^ \
81
- (((b) & 0x8) ? AES_XTIME(AES_XTIME(AES_XTIME(a))) : 0)) & 0xFF)
82
-
83
-static inline uint32_t aes_mixcolumn_byte(uint8_t x, bool fwd)
84
-{
85
- uint32_t u;
86
-
87
- if (fwd) {
88
- u = (AES_GFMUL(x, 3) << 24) | (x << 16) | (x << 8) |
89
- (AES_GFMUL(x, 2) << 0);
90
- } else {
91
- u = (AES_GFMUL(x, 0xb) << 24) | (AES_GFMUL(x, 0xd) << 16) |
92
- (AES_GFMUL(x, 0x9) << 8) | (AES_GFMUL(x, 0xe) << 0);
93
- }
94
- return u;
95
-}
96
-
97
#define sext32_xlen(x) (target_ulong)(int32_t)(x)
98
99
static inline target_ulong aes32_operation(target_ulong shamt,
100
@@ -XXX,XX +XXX,XX @@ static inline target_ulong aes32_operation(target_ulong shamt,
101
bool enc, bool mix)
40
{
102
{
41
void *fdt;
103
uint8_t si = rs2 >> shamt;
42
+ int fdt_size;
104
- uint8_t so;
43
uint64_t addr, size;
105
uint32_t mixed;
44
unsigned long clint_addr;
106
target_ulong res;
45
int cpu, socket;
107
46
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
108
if (enc) {
47
"sifive,clint0", "riscv,clint0"
109
- so = AES_sbox[si];
48
};
110
if (mix) {
49
111
- mixed = aes_mixcolumn_byte(so, true);
50
- fdt = s->fdt = create_device_tree(&s->fdt_size);
112
+ mixed = be32_to_cpu(AES_Te0[si]);
51
+ fdt = mc->fdt = create_device_tree(&fdt_size);
113
} else {
52
if (!fdt) {
114
- mixed = so;
53
error_report("create_device_tree() failed");
115
+ mixed = AES_sbox[si];
54
exit(1);
116
}
55
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
117
} else {
56
hwaddr end = riscv_load_initrd(machine->initrd_filename,
118
- so = AES_isbox[si];
57
machine->ram_size, kernel_entry,
119
if (mix) {
58
&start);
120
- mixed = aes_mixcolumn_byte(so, false);
59
- qemu_fdt_setprop_cell(s->fdt, "/chosen",
121
+ mixed = be32_to_cpu(AES_Td0[si]);
60
+ qemu_fdt_setprop_cell(machine->fdt, "/chosen",
122
} else {
61
"linux,initrd-start", start);
123
- mixed = so;
62
- qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
124
+ mixed = AES_isbox[si];
63
+ qemu_fdt_setprop_cell(machine->fdt, "/chosen", "linux,initrd-end",
125
}
64
end);
65
}
126
}
66
127
mixed = rol32(mixed, shamt);
67
/* Compute the fdt load address in dram */
68
fdt_load_addr = riscv_load_fdt(memmap[SPIKE_DRAM].base,
69
- machine->ram_size, s->fdt);
70
-
71
- /* Set machine->fdt for 'dumpdtb' QMP/HMP command */
72
- machine->fdt = s->fdt;
73
+ machine->ram_size, machine->fdt);
74
75
/* load the reset vector */
76
riscv_setup_rom_reset_vec(machine, &s->soc[0], memmap[SPIKE_DRAM].base,
77
--
128
--
78
2.39.0
129
2.41.0
130
131
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
There's no need to use a MachineState pointer and a fdt pointer now that
3
Take some functions/macros out of `vector_helper` and put them in a new
4
all RISC-V machines are using the FDT from the MachineState.
4
module called `vector_internals`. This ensures they can be used by both
5
vector and vector-crypto helpers (latter implemented in proceeding
6
commits).
5
7
6
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Max Chou <max.chou@sifive.com>
9
Message-Id: <20230111170948.316276-6-dbarboza@ventanamicro.com>
11
Acked-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-ID: <20230711165917.2629866-2-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
14
---
12
include/hw/riscv/numa.h | 6 +++---
15
target/riscv/vector_internals.h | 182 +++++++++++++++++++++++++++++
13
hw/riscv/numa.c | 6 +++---
16
target/riscv/vector_helper.c | 201 +-------------------------------
14
hw/riscv/spike.c | 6 +++---
17
target/riscv/vector_internals.c | 81 +++++++++++++
15
hw/riscv/virt.c | 18 +++++++++---------
18
target/riscv/meson.build | 1 +
16
4 files changed, 18 insertions(+), 18 deletions(-)
19
4 files changed, 265 insertions(+), 200 deletions(-)
20
create mode 100644 target/riscv/vector_internals.h
21
create mode 100644 target/riscv/vector_internals.c
17
22
18
diff --git a/include/hw/riscv/numa.h b/include/hw/riscv/numa.h
23
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
24
new file mode 100644
25
index XXXXXXX..XXXXXXX
26
--- /dev/null
27
+++ b/target/riscv/vector_internals.h
28
@@ -XXX,XX +XXX,XX @@
29
+/*
30
+ * RISC-V Vector Extension Internals
31
+ *
32
+ * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
33
+ *
34
+ * This program is free software; you can redistribute it and/or modify it
35
+ * under the terms and conditions of the GNU General Public License,
36
+ * version 2 or later, as published by the Free Software Foundation.
37
+ *
38
+ * This program is distributed in the hope it will be useful, but WITHOUT
39
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
40
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
41
+ * more details.
42
+ *
43
+ * You should have received a copy of the GNU General Public License along with
44
+ * this program. If not, see <http://www.gnu.org/licenses/>.
45
+ */
46
+
47
+#ifndef TARGET_RISCV_VECTOR_INTERNALS_H
48
+#define TARGET_RISCV_VECTOR_INTERNALS_H
49
+
50
+#include "qemu/osdep.h"
51
+#include "qemu/bitops.h"
52
+#include "cpu.h"
53
+#include "tcg/tcg-gvec-desc.h"
54
+#include "internals.h"
55
+
56
+static inline uint32_t vext_nf(uint32_t desc)
57
+{
58
+ return FIELD_EX32(simd_data(desc), VDATA, NF);
59
+}
60
+
61
+/*
62
+ * Note that vector data is stored in host-endian 64-bit chunks,
63
+ * so addressing units smaller than that needs a host-endian fixup.
64
+ */
65
+#if HOST_BIG_ENDIAN
66
+#define H1(x) ((x) ^ 7)
67
+#define H1_2(x) ((x) ^ 6)
68
+#define H1_4(x) ((x) ^ 4)
69
+#define H2(x) ((x) ^ 3)
70
+#define H4(x) ((x) ^ 1)
71
+#define H8(x) ((x))
72
+#else
73
+#define H1(x) (x)
74
+#define H1_2(x) (x)
75
+#define H1_4(x) (x)
76
+#define H2(x) (x)
77
+#define H4(x) (x)
78
+#define H8(x) (x)
79
+#endif
80
+
81
+/*
82
+ * Encode LMUL to lmul as following:
83
+ * LMUL vlmul lmul
84
+ * 1 000 0
85
+ * 2 001 1
86
+ * 4 010 2
87
+ * 8 011 3
88
+ * - 100 -
89
+ * 1/8 101 -3
90
+ * 1/4 110 -2
91
+ * 1/2 111 -1
92
+ */
93
+static inline int32_t vext_lmul(uint32_t desc)
94
+{
95
+ return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3);
96
+}
97
+
98
+static inline uint32_t vext_vm(uint32_t desc)
99
+{
100
+ return FIELD_EX32(simd_data(desc), VDATA, VM);
101
+}
102
+
103
+static inline uint32_t vext_vma(uint32_t desc)
104
+{
105
+ return FIELD_EX32(simd_data(desc), VDATA, VMA);
106
+}
107
+
108
+static inline uint32_t vext_vta(uint32_t desc)
109
+{
110
+ return FIELD_EX32(simd_data(desc), VDATA, VTA);
111
+}
112
+
113
+static inline uint32_t vext_vta_all_1s(uint32_t desc)
114
+{
115
+ return FIELD_EX32(simd_data(desc), VDATA, VTA_ALL_1S);
116
+}
117
+
118
+/*
119
+ * Earlier designs (pre-0.9) had a varying number of bits
120
+ * per mask value (MLEN). In the 0.9 design, MLEN=1.
121
+ * (Section 4.5)
122
+ */
123
+static inline int vext_elem_mask(void *v0, int index)
124
+{
125
+ int idx = index / 64;
126
+ int pos = index % 64;
127
+ return (((uint64_t *)v0)[idx] >> pos) & 1;
128
+}
129
+
130
+/*
131
+ * Get number of total elements, including prestart, body and tail elements.
132
+ * Note that when LMUL < 1, the tail includes the elements past VLMAX that
133
+ * are held in the same vector register.
134
+ */
135
+static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t desc,
136
+ uint32_t esz)
137
+{
138
+ uint32_t vlenb = simd_maxsz(desc);
139
+ uint32_t sew = 1 << FIELD_EX64(env->vtype, VTYPE, VSEW);
140
+ int8_t emul = ctzl(esz) - ctzl(sew) + vext_lmul(desc) < 0 ? 0 :
141
+ ctzl(esz) - ctzl(sew) + vext_lmul(desc);
142
+ return (vlenb << emul) / esz;
143
+}
144
+
145
+/* set agnostic elements to 1s */
146
+void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
147
+ uint32_t tot);
148
+
149
+/* expand macro args before macro */
150
+#define RVVCALL(macro, ...) macro(__VA_ARGS__)
151
+
152
+/* (TD, T1, T2, TX1, TX2) */
153
+#define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
154
+#define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t
155
+#define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t
156
+#define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t
157
+
158
+/* operation of two vector elements */
159
+typedef void opivv2_fn(void *vd, void *vs1, void *vs2, int i);
160
+
161
+#define OPIVV2(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP) \
162
+static void do_##NAME(void *vd, void *vs1, void *vs2, int i) \
163
+{ \
164
+ TX1 s1 = *((T1 *)vs1 + HS1(i)); \
165
+ TX2 s2 = *((T2 *)vs2 + HS2(i)); \
166
+ *((TD *)vd + HD(i)) = OP(s2, s1); \
167
+}
168
+
169
+void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
170
+ CPURISCVState *env, uint32_t desc,
171
+ opivv2_fn *fn, uint32_t esz);
172
+
173
+/* generate the helpers for OPIVV */
174
+#define GEN_VEXT_VV(NAME, ESZ) \
175
+void HELPER(NAME)(void *vd, void *v0, void *vs1, \
176
+ void *vs2, CPURISCVState *env, \
177
+ uint32_t desc) \
178
+{ \
179
+ do_vext_vv(vd, v0, vs1, vs2, env, desc, \
180
+ do_##NAME, ESZ); \
181
+}
182
+
183
+typedef void opivx2_fn(void *vd, target_long s1, void *vs2, int i);
184
+
185
+/*
186
+ * (T1)s1 gives the real operator type.
187
+ * (TX1)(T1)s1 expands the operator type of widen or narrow operations.
188
+ */
189
+#define OPIVX2(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \
190
+static void do_##NAME(void *vd, target_long s1, void *vs2, int i) \
191
+{ \
192
+ TX2 s2 = *((T2 *)vs2 + HS2(i)); \
193
+ *((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1); \
194
+}
195
+
196
+void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
197
+ CPURISCVState *env, uint32_t desc,
198
+ opivx2_fn fn, uint32_t esz);
199
+
200
+/* generate the helpers for OPIVX */
201
+#define GEN_VEXT_VX(NAME, ESZ) \
202
+void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
203
+ void *vs2, CPURISCVState *env, \
204
+ uint32_t desc) \
205
+{ \
206
+ do_vext_vx(vd, v0, s1, vs2, env, desc, \
207
+ do_##NAME, ESZ); \
208
+}
209
+
210
+#endif /* TARGET_RISCV_VECTOR_INTERNALS_H */
211
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
19
index XXXXXXX..XXXXXXX 100644
212
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/riscv/numa.h
213
--- a/target/riscv/vector_helper.c
21
+++ b/include/hw/riscv/numa.h
214
+++ b/target/riscv/vector_helper.c
22
@@ -XXX,XX +XXX,XX @@ bool riscv_socket_check_hartids(const MachineState *ms, int socket_id);
215
@@ -XXX,XX +XXX,XX @@
23
* @ms: pointer to machine state
216
#include "fpu/softfloat.h"
24
* @socket_id: socket index
217
#include "tcg/tcg-gvec-desc.h"
218
#include "internals.h"
219
+#include "vector_internals.h"
220
#include <math.h>
221
222
target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
223
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
224
return vl;
225
}
226
227
-/*
228
- * Note that vector data is stored in host-endian 64-bit chunks,
229
- * so addressing units smaller than that needs a host-endian fixup.
230
- */
231
-#if HOST_BIG_ENDIAN
232
-#define H1(x) ((x) ^ 7)
233
-#define H1_2(x) ((x) ^ 6)
234
-#define H1_4(x) ((x) ^ 4)
235
-#define H2(x) ((x) ^ 3)
236
-#define H4(x) ((x) ^ 1)
237
-#define H8(x) ((x))
238
-#else
239
-#define H1(x) (x)
240
-#define H1_2(x) (x)
241
-#define H1_4(x) (x)
242
-#define H2(x) (x)
243
-#define H4(x) (x)
244
-#define H8(x) (x)
245
-#endif
246
-
247
-static inline uint32_t vext_nf(uint32_t desc)
248
-{
249
- return FIELD_EX32(simd_data(desc), VDATA, NF);
250
-}
251
-
252
-static inline uint32_t vext_vm(uint32_t desc)
253
-{
254
- return FIELD_EX32(simd_data(desc), VDATA, VM);
255
-}
256
-
257
-/*
258
- * Encode LMUL to lmul as following:
259
- * LMUL vlmul lmul
260
- * 1 000 0
261
- * 2 001 1
262
- * 4 010 2
263
- * 8 011 3
264
- * - 100 -
265
- * 1/8 101 -3
266
- * 1/4 110 -2
267
- * 1/2 111 -1
268
- */
269
-static inline int32_t vext_lmul(uint32_t desc)
270
-{
271
- return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3);
272
-}
273
-
274
-static inline uint32_t vext_vta(uint32_t desc)
275
-{
276
- return FIELD_EX32(simd_data(desc), VDATA, VTA);
277
-}
278
-
279
-static inline uint32_t vext_vma(uint32_t desc)
280
-{
281
- return FIELD_EX32(simd_data(desc), VDATA, VMA);
282
-}
283
-
284
-static inline uint32_t vext_vta_all_1s(uint32_t desc)
285
-{
286
- return FIELD_EX32(simd_data(desc), VDATA, VTA_ALL_1S);
287
-}
288
-
289
/*
290
* Get the maximum number of elements can be operated.
25
*
291
*
26
- * Write NUMA node-id FDT property for given FDT node
292
@@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz)
27
+ * Write NUMA node-id FDT property in MachineState->fdt
293
return scale < 0 ? vlenb >> -scale : vlenb << scale;
28
*/
29
-void riscv_socket_fdt_write_id(const MachineState *ms, void *fdt,
30
- const char *node_name, int socket_id);
31
+void riscv_socket_fdt_write_id(const MachineState *ms, const char *node_name,
32
+ int socket_id);
33
34
/**
35
* riscv_socket_fdt_write_distance_matrix:
36
diff --git a/hw/riscv/numa.c b/hw/riscv/numa.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/riscv/numa.c
39
+++ b/hw/riscv/numa.c
40
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_socket_mem_size(const MachineState *ms, int socket_id)
41
ms->numa_state->nodes[socket_id].node_mem : 0;
42
}
294
}
43
295
44
-void riscv_socket_fdt_write_id(const MachineState *ms, void *fdt,
296
-/*
45
- const char *node_name, int socket_id)
297
- * Get number of total elements, including prestart, body and tail elements.
46
+void riscv_socket_fdt_write_id(const MachineState *ms, const char *node_name,
298
- * Note that when LMUL < 1, the tail includes the elements past VLMAX that
47
+ int socket_id)
299
- * are held in the same vector register.
300
- */
301
-static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t desc,
302
- uint32_t esz)
303
-{
304
- uint32_t vlenb = simd_maxsz(desc);
305
- uint32_t sew = 1 << FIELD_EX64(env->vtype, VTYPE, VSEW);
306
- int8_t emul = ctzl(esz) - ctzl(sew) + vext_lmul(desc) < 0 ? 0 :
307
- ctzl(esz) - ctzl(sew) + vext_lmul(desc);
308
- return (vlenb << emul) / esz;
309
-}
310
-
311
static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
48
{
312
{
49
if (numa_enabled(ms)) {
313
return (addr & ~env->cur_pmmask) | env->cur_pmbase;
50
- qemu_fdt_setprop_cell(fdt, node_name, "numa-node-id", socket_id);
314
@@ -XXX,XX +XXX,XX @@ static void probe_pages(CPURISCVState *env, target_ulong addr,
51
+ qemu_fdt_setprop_cell(ms->fdt, node_name, "numa-node-id", socket_id);
52
}
315
}
53
}
316
}
54
317
55
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
318
-/* set agnostic elements to 1s */
319
-static void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
320
- uint32_t tot)
321
-{
322
- if (is_agnostic == 0) {
323
- /* policy undisturbed */
324
- return;
325
- }
326
- if (tot - cnt == 0) {
327
- return;
328
- }
329
- memset(base + cnt, -1, tot - cnt);
330
-}
331
-
332
static inline void vext_set_elem_mask(void *v0, int index,
333
uint8_t value)
334
{
335
@@ -XXX,XX +XXX,XX @@ static inline void vext_set_elem_mask(void *v0, int index,
336
((uint64_t *)v0)[idx] = deposit64(old, pos, 1, value);
337
}
338
339
-/*
340
- * Earlier designs (pre-0.9) had a varying number of bits
341
- * per mask value (MLEN). In the 0.9 design, MLEN=1.
342
- * (Section 4.5)
343
- */
344
-static inline int vext_elem_mask(void *v0, int index)
345
-{
346
- int idx = index / 64;
347
- int pos = index % 64;
348
- return (((uint64_t *)v0)[idx] >> pos) & 1;
349
-}
350
-
351
/* elements operations for load and store */
352
typedef void vext_ldst_elem_fn(CPURISCVState *env, abi_ptr addr,
353
uint32_t idx, void *vd, uintptr_t retaddr);
354
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
355
* Vector Integer Arithmetic Instructions
356
*/
357
358
-/* expand macro args before macro */
359
-#define RVVCALL(macro, ...) macro(__VA_ARGS__)
360
-
361
/* (TD, T1, T2, TX1, TX2) */
362
#define OP_SSS_B int8_t, int8_t, int8_t, int8_t, int8_t
363
#define OP_SSS_H int16_t, int16_t, int16_t, int16_t, int16_t
364
#define OP_SSS_W int32_t, int32_t, int32_t, int32_t, int32_t
365
#define OP_SSS_D int64_t, int64_t, int64_t, int64_t, int64_t
366
-#define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
367
-#define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t
368
-#define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t
369
-#define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t
370
#define OP_SUS_B int8_t, uint8_t, int8_t, uint8_t, int8_t
371
#define OP_SUS_H int16_t, uint16_t, int16_t, uint16_t, int16_t
372
#define OP_SUS_W int32_t, uint32_t, int32_t, uint32_t, int32_t
373
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
374
#define NOP_UUU_H uint16_t, uint16_t, uint32_t, uint16_t, uint32_t
375
#define NOP_UUU_W uint32_t, uint32_t, uint64_t, uint32_t, uint64_t
376
377
-/* operation of two vector elements */
378
-typedef void opivv2_fn(void *vd, void *vs1, void *vs2, int i);
379
-
380
-#define OPIVV2(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP) \
381
-static void do_##NAME(void *vd, void *vs1, void *vs2, int i) \
382
-{ \
383
- TX1 s1 = *((T1 *)vs1 + HS1(i)); \
384
- TX2 s2 = *((T2 *)vs2 + HS2(i)); \
385
- *((TD *)vd + HD(i)) = OP(s2, s1); \
386
-}
387
#define DO_SUB(N, M) (N - M)
388
#define DO_RSUB(N, M) (M - N)
389
390
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vsub_vv_h, OP_SSS_H, H2, H2, H2, DO_SUB)
391
RVVCALL(OPIVV2, vsub_vv_w, OP_SSS_W, H4, H4, H4, DO_SUB)
392
RVVCALL(OPIVV2, vsub_vv_d, OP_SSS_D, H8, H8, H8, DO_SUB)
393
394
-static void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
395
- CPURISCVState *env, uint32_t desc,
396
- opivv2_fn *fn, uint32_t esz)
397
-{
398
- uint32_t vm = vext_vm(desc);
399
- uint32_t vl = env->vl;
400
- uint32_t total_elems = vext_get_total_elems(env, desc, esz);
401
- uint32_t vta = vext_vta(desc);
402
- uint32_t vma = vext_vma(desc);
403
- uint32_t i;
404
-
405
- for (i = env->vstart; i < vl; i++) {
406
- if (!vm && !vext_elem_mask(v0, i)) {
407
- /* set masked-off elements to 1s */
408
- vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
409
- continue;
410
- }
411
- fn(vd, vs1, vs2, i);
412
- }
413
- env->vstart = 0;
414
- /* set tail elements to 1s */
415
- vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
416
-}
417
-
418
-/* generate the helpers for OPIVV */
419
-#define GEN_VEXT_VV(NAME, ESZ) \
420
-void HELPER(NAME)(void *vd, void *v0, void *vs1, \
421
- void *vs2, CPURISCVState *env, \
422
- uint32_t desc) \
423
-{ \
424
- do_vext_vv(vd, v0, vs1, vs2, env, desc, \
425
- do_##NAME, ESZ); \
426
-}
427
-
428
GEN_VEXT_VV(vadd_vv_b, 1)
429
GEN_VEXT_VV(vadd_vv_h, 2)
430
GEN_VEXT_VV(vadd_vv_w, 4)
431
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_VV(vsub_vv_h, 2)
432
GEN_VEXT_VV(vsub_vv_w, 4)
433
GEN_VEXT_VV(vsub_vv_d, 8)
434
435
-typedef void opivx2_fn(void *vd, target_long s1, void *vs2, int i);
436
-
437
-/*
438
- * (T1)s1 gives the real operator type.
439
- * (TX1)(T1)s1 expands the operator type of widen or narrow operations.
440
- */
441
-#define OPIVX2(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \
442
-static void do_##NAME(void *vd, target_long s1, void *vs2, int i) \
443
-{ \
444
- TX2 s2 = *((T2 *)vs2 + HS2(i)); \
445
- *((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1); \
446
-}
447
448
RVVCALL(OPIVX2, vadd_vx_b, OP_SSS_B, H1, H1, DO_ADD)
449
RVVCALL(OPIVX2, vadd_vx_h, OP_SSS_H, H2, H2, DO_ADD)
450
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vrsub_vx_h, OP_SSS_H, H2, H2, DO_RSUB)
451
RVVCALL(OPIVX2, vrsub_vx_w, OP_SSS_W, H4, H4, DO_RSUB)
452
RVVCALL(OPIVX2, vrsub_vx_d, OP_SSS_D, H8, H8, DO_RSUB)
453
454
-static void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
455
- CPURISCVState *env, uint32_t desc,
456
- opivx2_fn fn, uint32_t esz)
457
-{
458
- uint32_t vm = vext_vm(desc);
459
- uint32_t vl = env->vl;
460
- uint32_t total_elems = vext_get_total_elems(env, desc, esz);
461
- uint32_t vta = vext_vta(desc);
462
- uint32_t vma = vext_vma(desc);
463
- uint32_t i;
464
-
465
- for (i = env->vstart; i < vl; i++) {
466
- if (!vm && !vext_elem_mask(v0, i)) {
467
- /* set masked-off elements to 1s */
468
- vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
469
- continue;
470
- }
471
- fn(vd, s1, vs2, i);
472
- }
473
- env->vstart = 0;
474
- /* set tail elements to 1s */
475
- vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
476
-}
477
-
478
-/* generate the helpers for OPIVX */
479
-#define GEN_VEXT_VX(NAME, ESZ) \
480
-void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
481
- void *vs2, CPURISCVState *env, \
482
- uint32_t desc) \
483
-{ \
484
- do_vext_vx(vd, v0, s1, vs2, env, desc, \
485
- do_##NAME, ESZ); \
486
-}
487
-
488
GEN_VEXT_VX(vadd_vx_b, 1)
489
GEN_VEXT_VX(vadd_vx_h, 2)
490
GEN_VEXT_VX(vadd_vx_w, 4)
491
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
492
new file mode 100644
493
index XXXXXXX..XXXXXXX
494
--- /dev/null
495
+++ b/target/riscv/vector_internals.c
496
@@ -XXX,XX +XXX,XX @@
497
+/*
498
+ * RISC-V Vector Extension Internals
499
+ *
500
+ * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
501
+ *
502
+ * This program is free software; you can redistribute it and/or modify it
503
+ * under the terms and conditions of the GNU General Public License,
504
+ * version 2 or later, as published by the Free Software Foundation.
505
+ *
506
+ * This program is distributed in the hope it will be useful, but WITHOUT
507
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
508
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
509
+ * more details.
510
+ *
511
+ * You should have received a copy of the GNU General Public License along with
512
+ * this program. If not, see <http://www.gnu.org/licenses/>.
513
+ */
514
+
515
+#include "vector_internals.h"
516
+
517
+/* set agnostic elements to 1s */
518
+void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
519
+ uint32_t tot)
520
+{
521
+ if (is_agnostic == 0) {
522
+ /* policy undisturbed */
523
+ return;
524
+ }
525
+ if (tot - cnt == 0) {
526
+ return ;
527
+ }
528
+ memset(base + cnt, -1, tot - cnt);
529
+}
530
+
531
+void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
532
+ CPURISCVState *env, uint32_t desc,
533
+ opivv2_fn *fn, uint32_t esz)
534
+{
535
+ uint32_t vm = vext_vm(desc);
536
+ uint32_t vl = env->vl;
537
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
538
+ uint32_t vta = vext_vta(desc);
539
+ uint32_t vma = vext_vma(desc);
540
+ uint32_t i;
541
+
542
+ for (i = env->vstart; i < vl; i++) {
543
+ if (!vm && !vext_elem_mask(v0, i)) {
544
+ /* set masked-off elements to 1s */
545
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
546
+ continue;
547
+ }
548
+ fn(vd, vs1, vs2, i);
549
+ }
550
+ env->vstart = 0;
551
+ /* set tail elements to 1s */
552
+ vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
553
+}
554
+
555
+void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
556
+ CPURISCVState *env, uint32_t desc,
557
+ opivx2_fn fn, uint32_t esz)
558
+{
559
+ uint32_t vm = vext_vm(desc);
560
+ uint32_t vl = env->vl;
561
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
562
+ uint32_t vta = vext_vta(desc);
563
+ uint32_t vma = vext_vma(desc);
564
+ uint32_t i;
565
+
566
+ for (i = env->vstart; i < vl; i++) {
567
+ if (!vm && !vext_elem_mask(v0, i)) {
568
+ /* set masked-off elements to 1s */
569
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
570
+ continue;
571
+ }
572
+ fn(vd, s1, vs2, i);
573
+ }
574
+ env->vstart = 0;
575
+ /* set tail elements to 1s */
576
+ vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
577
+}
578
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
56
index XXXXXXX..XXXXXXX 100644
579
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/riscv/spike.c
580
--- a/target/riscv/meson.build
58
+++ b/hw/riscv/spike.c
581
+++ b/target/riscv/meson.build
59
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
582
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(files(
60
qemu_fdt_setprop_cell(fdt, cpu_name, "reg",
583
'gdbstub.c',
61
s->soc[socket].hartid_base + cpu);
584
'op_helper.c',
62
qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu");
585
'vector_helper.c',
63
- riscv_socket_fdt_write_id(mc, fdt, cpu_name, socket);
586
+ 'vector_internals.c',
64
+ riscv_socket_fdt_write_id(mc, cpu_name, socket);
587
'bitmanip_helper.c',
65
qemu_fdt_setprop_cell(fdt, cpu_name, "phandle", cpu_phandle);
588
'translate.c',
66
589
'm128_helper.c',
67
intc_name = g_strdup_printf("%s/interrupt-controller", cpu_name);
68
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
69
qemu_fdt_setprop_cells(fdt, mem_name, "reg",
70
addr >> 32, addr, size >> 32, size);
71
qemu_fdt_setprop_string(fdt, mem_name, "device_type", "memory");
72
- riscv_socket_fdt_write_id(mc, fdt, mem_name, socket);
73
+ riscv_socket_fdt_write_id(mc, mem_name, socket);
74
g_free(mem_name);
75
76
clint_addr = memmap[SPIKE_CLINT].base +
77
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
78
0x0, clint_addr, 0x0, memmap[SPIKE_CLINT].size);
79
qemu_fdt_setprop(fdt, clint_name, "interrupts-extended",
80
clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
81
- riscv_socket_fdt_write_id(mc, fdt, clint_name, socket);
82
+ riscv_socket_fdt_write_id(mc, clint_name, socket);
83
84
g_free(clint_name);
85
g_free(clint_cells);
86
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/hw/riscv/virt.c
89
+++ b/hw/riscv/virt.c
90
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
91
qemu_fdt_setprop_cell(mc->fdt, cpu_name, "reg",
92
s->soc[socket].hartid_base + cpu);
93
qemu_fdt_setprop_string(mc->fdt, cpu_name, "device_type", "cpu");
94
- riscv_socket_fdt_write_id(mc, mc->fdt, cpu_name, socket);
95
+ riscv_socket_fdt_write_id(mc, cpu_name, socket);
96
qemu_fdt_setprop_cell(mc->fdt, cpu_name, "phandle", cpu_phandle);
97
98
intc_phandles[cpu] = (*phandle)++;
99
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_memory(RISCVVirtState *s,
100
qemu_fdt_setprop_cells(mc->fdt, mem_name, "reg",
101
addr >> 32, addr, size >> 32, size);
102
qemu_fdt_setprop_string(mc->fdt, mem_name, "device_type", "memory");
103
- riscv_socket_fdt_write_id(mc, mc->fdt, mem_name, socket);
104
+ riscv_socket_fdt_write_id(mc, mem_name, socket);
105
g_free(mem_name);
106
}
107
108
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_clint(RISCVVirtState *s,
109
0x0, clint_addr, 0x0, memmap[VIRT_CLINT].size);
110
qemu_fdt_setprop(mc->fdt, clint_name, "interrupts-extended",
111
clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
112
- riscv_socket_fdt_write_id(mc, mc->fdt, clint_name, socket);
113
+ riscv_socket_fdt_write_id(mc, clint_name, socket);
114
g_free(clint_name);
115
116
g_free(clint_cells);
117
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aclint(RISCVVirtState *s,
118
aclint_mswi_cells, aclint_cells_size);
119
qemu_fdt_setprop(mc->fdt, name, "interrupt-controller", NULL, 0);
120
qemu_fdt_setprop_cell(mc->fdt, name, "#interrupt-cells", 0);
121
- riscv_socket_fdt_write_id(mc, mc->fdt, name, socket);
122
+ riscv_socket_fdt_write_id(mc, name, socket);
123
g_free(name);
124
}
125
126
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aclint(RISCVVirtState *s,
127
0x0, RISCV_ACLINT_DEFAULT_MTIME);
128
qemu_fdt_setprop(mc->fdt, name, "interrupts-extended",
129
aclint_mtimer_cells, aclint_cells_size);
130
- riscv_socket_fdt_write_id(mc, mc->fdt, name, socket);
131
+ riscv_socket_fdt_write_id(mc, name, socket);
132
g_free(name);
133
134
if (s->aia_type != VIRT_AIA_TYPE_APLIC_IMSIC) {
135
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aclint(RISCVVirtState *s,
136
aclint_sswi_cells, aclint_cells_size);
137
qemu_fdt_setprop(mc->fdt, name, "interrupt-controller", NULL, 0);
138
qemu_fdt_setprop_cell(mc->fdt, name, "#interrupt-cells", 0);
139
- riscv_socket_fdt_write_id(mc, mc->fdt, name, socket);
140
+ riscv_socket_fdt_write_id(mc, name, socket);
141
g_free(name);
142
}
143
144
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_plic(RISCVVirtState *s,
145
0x0, plic_addr, 0x0, memmap[VIRT_PLIC].size);
146
qemu_fdt_setprop_cell(mc->fdt, plic_name, "riscv,ndev",
147
VIRT_IRQCHIP_NUM_SOURCES - 1);
148
- riscv_socket_fdt_write_id(mc, mc->fdt, plic_name, socket);
149
+ riscv_socket_fdt_write_id(mc, plic_name, socket);
150
qemu_fdt_setprop_cell(mc->fdt, plic_name, "phandle",
151
plic_phandles[socket]);
152
153
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
154
aplic_s_phandle);
155
qemu_fdt_setprop_cells(mc->fdt, aplic_name, "riscv,delegate",
156
aplic_s_phandle, 0x1, VIRT_IRQCHIP_NUM_SOURCES);
157
- riscv_socket_fdt_write_id(mc, mc->fdt, aplic_name, socket);
158
+ riscv_socket_fdt_write_id(mc, aplic_name, socket);
159
qemu_fdt_setprop_cell(mc->fdt, aplic_name, "phandle", aplic_m_phandle);
160
g_free(aplic_name);
161
162
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
163
0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_S].size);
164
qemu_fdt_setprop_cell(mc->fdt, aplic_name, "riscv,num-sources",
165
VIRT_IRQCHIP_NUM_SOURCES);
166
- riscv_socket_fdt_write_id(mc, mc->fdt, aplic_name, socket);
167
+ riscv_socket_fdt_write_id(mc, aplic_name, socket);
168
qemu_fdt_setprop_cell(mc->fdt, aplic_name, "phandle", aplic_s_phandle);
169
170
if (!socket) {
171
--
590
--
172
2.39.0
591
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
At present for some unknown reason the HTIF registers (fromhost &
3
Refactor the non SEW-specific stuff out of `GEN_OPIVV_TRANS` into
4
tohost) are defined in the RISC-V CPUArchState. It should really
4
function `opivv_trans` (similar to `opivi_trans`). `opivv_trans` will be
5
be put in the HTIFState struct as it is only meaningful to HTIF.
5
used in proceeding vector-crypto commits.
6
6
7
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20221229091828.1945072-6-bmeng@tinylab.org>
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
12
Message-ID: <20230711165917.2629866-3-max.chou@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
14
---
13
include/hw/char/riscv_htif.h | 8 ++++----
15
target/riscv/insn_trans/trans_rvv.c.inc | 62 +++++++++++++------------
14
target/riscv/cpu.h | 4 ----
16
1 file changed, 32 insertions(+), 30 deletions(-)
15
hw/char/riscv_htif.c | 35 +++++++++++++++++------------------
16
hw/riscv/spike.c | 3 +--
17
target/riscv/machine.c | 6 ++----
18
5 files changed, 24 insertions(+), 32 deletions(-)
19
17
20
diff --git a/include/hw/char/riscv_htif.h b/include/hw/char/riscv_htif.h
18
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/char/riscv_htif.h
20
--- a/target/riscv/insn_trans/trans_rvv.c.inc
23
+++ b/include/hw/char/riscv_htif.h
21
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
24
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ GEN_OPIWX_WIDEN_TRANS(vwadd_wx)
25
#include "chardev/char.h"
23
GEN_OPIWX_WIDEN_TRANS(vwsubu_wx)
26
#include "chardev/char-fe.h"
24
GEN_OPIWX_WIDEN_TRANS(vwsub_wx)
27
#include "exec/memory.h"
25
28
-#include "target/riscv/cpu.h"
26
+static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
29
27
+ gen_helper_gvec_4_ptr *fn, DisasContext *s)
30
#define TYPE_HTIF_UART "riscv.htif.uart"
28
+{
31
29
+ uint32_t data = 0;
32
@@ -XXX,XX +XXX,XX @@ typedef struct HTIFState {
30
+ TCGLabel *over = gen_new_label();
33
int allow_tohost;
31
+ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
34
int fromhost_inprogress;
32
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
35
33
+
36
+ uint64_t tohost;
34
+ data = FIELD_DP32(data, VDATA, VM, vm);
37
+ uint64_t fromhost;
35
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
38
hwaddr tohost_offset;
36
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
39
hwaddr fromhost_offset;
37
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
40
MemoryRegion mmio;
38
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
41
39
+ tcg_gen_gvec_4_ptr(vreg_ofs(s, vd), vreg_ofs(s, 0), vreg_ofs(s, vs1),
42
- CPURISCVState *env;
40
+ vreg_ofs(s, vs2), cpu_env, s->cfg_ptr->vlen / 8,
43
CharBackend chr;
41
+ s->cfg_ptr->vlen / 8, data, fn);
44
uint64_t pending_read;
42
+ mark_vs_dirty(s);
45
} HTIFState;
43
+ gen_set_label(over);
46
@@ -XXX,XX +XXX,XX @@ void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value,
44
+ return true;
47
bool htif_uses_elf_symbols(void);
45
+}
48
46
+
49
/* legacy pre qom */
47
/* Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions */
50
-HTIFState *htif_mm_init(MemoryRegion *address_space, CPURISCVState *env,
48
/* OPIVV without GVEC IR */
51
- Chardev *chr, uint64_t nonelf_base);
49
-#define GEN_OPIVV_TRANS(NAME, CHECK) \
52
+HTIFState *htif_mm_init(MemoryRegion *address_space, Chardev *chr,
50
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
53
+ uint64_t nonelf_base);
51
-{ \
54
52
- if (CHECK(s, a)) { \
55
#endif
53
- uint32_t data = 0; \
56
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
54
- static gen_helper_gvec_4_ptr * const fns[4] = { \
57
index XXXXXXX..XXXXXXX 100644
55
- gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
58
--- a/target/riscv/cpu.h
56
- gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
59
+++ b/target/riscv/cpu.h
57
- }; \
60
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
58
- TCGLabel *over = gen_new_label(); \
61
target_ulong sscratch;
59
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
62
target_ulong mscratch;
60
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
63
61
- \
64
- /* temporary htif regs */
62
- data = FIELD_DP32(data, VDATA, VM, a->vm); \
65
- uint64_t mfromhost;
63
- data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
66
- uint64_t mtohost;
64
- data = FIELD_DP32(data, VDATA, VTA, s->vta); \
67
-
65
- data = \
68
/* Sstc CSRs */
66
- FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
69
uint64_t stimecmp;
67
- data = FIELD_DP32(data, VDATA, VMA, s->vma); \
70
68
- tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
71
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
69
- vreg_ofs(s, a->rs1), \
72
index XXXXXXX..XXXXXXX 100644
70
- vreg_ofs(s, a->rs2), cpu_env, \
73
--- a/hw/char/riscv_htif.c
71
- s->cfg_ptr->vlen / 8, \
74
+++ b/hw/char/riscv_htif.c
72
- s->cfg_ptr->vlen / 8, data, \
75
@@ -XXX,XX +XXX,XX @@ static void htif_recv(void *opaque, const uint8_t *buf, int size)
73
- fns[s->sew]); \
76
uint64_t val_written = s->pending_read;
74
- mark_vs_dirty(s); \
77
uint64_t resp = 0x100 | *buf;
75
- gen_set_label(over); \
78
76
- return true; \
79
- s->env->mfromhost = (val_written >> 48 << 48) | (resp << 16 >> 16);
77
- } \
80
+ s->fromhost = (val_written >> 48 << 48) | (resp << 16 >> 16);
78
- return false; \
79
+#define GEN_OPIVV_TRANS(NAME, CHECK) \
80
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
81
+{ \
82
+ if (CHECK(s, a)) { \
83
+ static gen_helper_gvec_4_ptr * const fns[4] = { \
84
+ gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
85
+ gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
86
+ }; \
87
+ return opivv_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s);\
88
+ } \
89
+ return false; \
81
}
90
}
82
91
83
/*
92
/*
84
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
85
if (cmd == HTIF_CONSOLE_CMD_GETC) {
86
/* this should be a queue, but not yet implemented as such */
87
s->pending_read = val_written;
88
- s->env->mtohost = 0; /* clear to indicate we read */
89
+ s->tohost = 0; /* clear to indicate we read */
90
return;
91
} else if (cmd == HTIF_CONSOLE_CMD_PUTC) {
92
qemu_chr_fe_write(&s->chr, (uint8_t *)&payload, 1);
93
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
94
* HTIF needs protocol documentation and a more complete state machine.
95
*
96
* while (!s->fromhost_inprogress &&
97
- * s->env->mfromhost != 0x0) {
98
+ * s->fromhost != 0x0) {
99
* }
100
*/
101
- s->env->mfromhost = (val_written >> 48 << 48) | (resp << 16 >> 16);
102
- s->env->mtohost = 0; /* clear to indicate we read */
103
+ s->fromhost = (val_written >> 48 << 48) | (resp << 16 >> 16);
104
+ s->tohost = 0; /* clear to indicate we read */
105
}
106
107
#define TOHOST_OFFSET1 (s->tohost_offset)
108
@@ -XXX,XX +XXX,XX @@ static uint64_t htif_mm_read(void *opaque, hwaddr addr, unsigned size)
109
{
110
HTIFState *s = opaque;
111
if (addr == TOHOST_OFFSET1) {
112
- return s->env->mtohost & 0xFFFFFFFF;
113
+ return s->tohost & 0xFFFFFFFF;
114
} else if (addr == TOHOST_OFFSET2) {
115
- return (s->env->mtohost >> 32) & 0xFFFFFFFF;
116
+ return (s->tohost >> 32) & 0xFFFFFFFF;
117
} else if (addr == FROMHOST_OFFSET1) {
118
- return s->env->mfromhost & 0xFFFFFFFF;
119
+ return s->fromhost & 0xFFFFFFFF;
120
} else if (addr == FROMHOST_OFFSET2) {
121
- return (s->env->mfromhost >> 32) & 0xFFFFFFFF;
122
+ return (s->fromhost >> 32) & 0xFFFFFFFF;
123
} else {
124
qemu_log("Invalid htif read: address %016" PRIx64 "\n",
125
(uint64_t)addr);
126
@@ -XXX,XX +XXX,XX @@ static void htif_mm_write(void *opaque, hwaddr addr,
127
{
128
HTIFState *s = opaque;
129
if (addr == TOHOST_OFFSET1) {
130
- if (s->env->mtohost == 0x0) {
131
+ if (s->tohost == 0x0) {
132
s->allow_tohost = 1;
133
- s->env->mtohost = value & 0xFFFFFFFF;
134
+ s->tohost = value & 0xFFFFFFFF;
135
} else {
136
s->allow_tohost = 0;
137
}
138
} else if (addr == TOHOST_OFFSET2) {
139
if (s->allow_tohost) {
140
- s->env->mtohost |= value << 32;
141
- htif_handle_tohost_write(s, s->env->mtohost);
142
+ s->tohost |= value << 32;
143
+ htif_handle_tohost_write(s, s->tohost);
144
}
145
} else if (addr == FROMHOST_OFFSET1) {
146
s->fromhost_inprogress = 1;
147
- s->env->mfromhost = value & 0xFFFFFFFF;
148
+ s->fromhost = value & 0xFFFFFFFF;
149
} else if (addr == FROMHOST_OFFSET2) {
150
- s->env->mfromhost |= value << 32;
151
+ s->fromhost |= value << 32;
152
s->fromhost_inprogress = 0;
153
} else {
154
qemu_log("Invalid htif write: address %016" PRIx64 "\n",
155
@@ -XXX,XX +XXX,XX @@ bool htif_uses_elf_symbols(void)
156
return (address_symbol_set == 3) ? true : false;
157
}
158
159
-HTIFState *htif_mm_init(MemoryRegion *address_space, CPURISCVState *env,
160
- Chardev *chr, uint64_t nonelf_base)
161
+HTIFState *htif_mm_init(MemoryRegion *address_space, Chardev *chr,
162
+ uint64_t nonelf_base)
163
{
164
uint64_t base, size, tohost_offset, fromhost_offset;
165
166
@@ -XXX,XX +XXX,XX @@ HTIFState *htif_mm_init(MemoryRegion *address_space, CPURISCVState *env,
167
fromhost_offset = fromhost_addr - base;
168
169
HTIFState *s = g_new0(HTIFState, 1);
170
- s->env = env;
171
s->tohost_offset = tohost_offset;
172
s->fromhost_offset = fromhost_offset;
173
s->pending_read = 0;
174
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
175
index XXXXXXX..XXXXXXX 100644
176
--- a/hw/riscv/spike.c
177
+++ b/hw/riscv/spike.c
178
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
179
fdt_load_addr);
180
181
/* initialize HTIF using symbols found in load_kernel */
182
- htif_mm_init(system_memory, &s->soc[0].harts[0].env,
183
- serial_hd(0), memmap[SPIKE_HTIF].base);
184
+ htif_mm_init(system_memory, serial_hd(0), memmap[SPIKE_HTIF].base);
185
}
186
187
static void spike_machine_instance_init(Object *obj)
188
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
189
index XXXXXXX..XXXXXXX 100644
190
--- a/target/riscv/machine.c
191
+++ b/target/riscv/machine.c
192
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmu_ctr_state = {
193
194
const VMStateDescription vmstate_riscv_cpu = {
195
.name = "cpu",
196
- .version_id = 5,
197
- .minimum_version_id = 5,
198
+ .version_id = 6,
199
+ .minimum_version_id = 6,
200
.post_load = riscv_cpu_post_load,
201
.fields = (VMStateField[]) {
202
VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
203
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
204
VMSTATE_UINTTL_ARRAY(env.mhpmeventh_val, RISCVCPU, RV_MAX_MHPMEVENTS),
205
VMSTATE_UINTTL(env.sscratch, RISCVCPU),
206
VMSTATE_UINTTL(env.mscratch, RISCVCPU),
207
- VMSTATE_UINT64(env.mfromhost, RISCVCPU),
208
- VMSTATE_UINT64(env.mtohost, RISCVCPU),
209
VMSTATE_UINT64(env.stimecmp, RISCVCPU),
210
211
VMSTATE_END_OF_LIST()
212
--
93
--
213
2.39.0
94
2.41.0
diff view generated by jsdifflib
New patch
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
1
2
3
Remove the redundant "vl == 0" check which is already included within the vstart >= vl check, when vl == 0.
4
5
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
6
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
7
Signed-off-by: Max Chou <max.chou@sifive.com>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20230711165917.2629866-4-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/insn_trans/trans_rvv.c.inc | 31 +------------------------
13
1 file changed, 1 insertion(+), 30 deletions(-)
14
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
20
TCGv_i32 desc;
21
22
TCGLabel *over = gen_new_label();
23
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
24
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
25
26
dest = tcg_temp_new_ptr();
27
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
28
TCGv_i32 desc;
29
30
TCGLabel *over = gen_new_label();
31
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
32
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
33
34
dest = tcg_temp_new_ptr();
35
@@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
36
TCGv_i32 desc;
37
38
TCGLabel *over = gen_new_label();
39
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
40
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
41
42
dest = tcg_temp_new_ptr();
43
@@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
44
TCGv_i32 desc;
45
46
TCGLabel *over = gen_new_label();
47
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
48
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
49
50
dest = tcg_temp_new_ptr();
51
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
52
return false;
53
}
54
55
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
56
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
57
58
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
59
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
60
uint32_t data = 0;
61
62
TCGLabel *over = gen_new_label();
63
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
64
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
65
66
dest = tcg_temp_new_ptr();
67
@@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
68
uint32_t data = 0;
69
70
TCGLabel *over = gen_new_label();
71
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
72
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
73
74
dest = tcg_temp_new_ptr();
75
@@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
76
if (checkfn(s, a)) {
77
uint32_t data = 0;
78
TCGLabel *over = gen_new_label();
79
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
80
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
81
82
data = FIELD_DP32(data, VDATA, VM, a->vm);
83
@@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
84
if (opiwv_widen_check(s, a)) {
85
uint32_t data = 0;
86
TCGLabel *over = gen_new_label();
87
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
88
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
89
90
data = FIELD_DP32(data, VDATA, VM, a->vm);
91
@@ -XXX,XX +XXX,XX @@ static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
92
{
93
uint32_t data = 0;
94
TCGLabel *over = gen_new_label();
95
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
96
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
97
98
data = FIELD_DP32(data, VDATA, VM, vm);
99
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
100
gen_helper_##NAME##_w, \
101
}; \
102
TCGLabel *over = gen_new_label(); \
103
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
104
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
105
\
106
data = FIELD_DP32(data, VDATA, VM, a->vm); \
107
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
108
gen_helper_vmv_v_v_w, gen_helper_vmv_v_v_d,
109
};
110
TCGLabel *over = gen_new_label();
111
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
112
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
113
114
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
115
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
116
vext_check_ss(s, a->rd, 0, 1)) {
117
TCGv s1;
118
TCGLabel *over = gen_new_label();
119
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
120
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
121
122
s1 = get_gpr(s, a->rs1, EXT_SIGN);
123
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
124
gen_helper_vmv_v_x_w, gen_helper_vmv_v_x_d,
125
};
126
TCGLabel *over = gen_new_label();
127
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
128
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
129
130
s1 = tcg_constant_i64(simm);
131
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
132
}; \
133
TCGLabel *over = gen_new_label(); \
134
gen_set_rm(s, RISCV_FRM_DYN); \
135
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
136
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
137
\
138
data = FIELD_DP32(data, VDATA, VM, a->vm); \
139
@@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
140
TCGv_i64 t1;
141
142
TCGLabel *over = gen_new_label();
143
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
144
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
145
146
dest = tcg_temp_new_ptr();
147
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
148
}; \
149
TCGLabel *over = gen_new_label(); \
150
gen_set_rm(s, RISCV_FRM_DYN); \
151
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
152
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);\
153
\
154
data = FIELD_DP32(data, VDATA, VM, a->vm); \
155
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
156
}; \
157
TCGLabel *over = gen_new_label(); \
158
gen_set_rm(s, RISCV_FRM_DYN); \
159
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
160
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
161
\
162
data = FIELD_DP32(data, VDATA, VM, a->vm); \
163
@@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
164
uint32_t data = 0;
165
TCGLabel *over = gen_new_label();
166
gen_set_rm_chkfrm(s, rm);
167
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
168
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
169
170
data = FIELD_DP32(data, VDATA, VM, a->vm);
171
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
172
gen_helper_vmv_v_x_d,
173
};
174
TCGLabel *over = gen_new_label();
175
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
176
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
177
178
t1 = tcg_temp_new_i64();
179
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
180
}; \
181
TCGLabel *over = gen_new_label(); \
182
gen_set_rm_chkfrm(s, FRM); \
183
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
184
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
185
\
186
data = FIELD_DP32(data, VDATA, VM, a->vm); \
187
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
188
}; \
189
TCGLabel *over = gen_new_label(); \
190
gen_set_rm(s, RISCV_FRM_DYN); \
191
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
192
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
193
\
194
data = FIELD_DP32(data, VDATA, VM, a->vm); \
195
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
196
}; \
197
TCGLabel *over = gen_new_label(); \
198
gen_set_rm_chkfrm(s, FRM); \
199
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
200
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
201
\
202
data = FIELD_DP32(data, VDATA, VM, a->vm); \
203
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
204
}; \
205
TCGLabel *over = gen_new_label(); \
206
gen_set_rm_chkfrm(s, FRM); \
207
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
208
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
209
\
210
data = FIELD_DP32(data, VDATA, VM, a->vm); \
211
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \
212
uint32_t data = 0; \
213
gen_helper_gvec_4_ptr *fn = gen_helper_##NAME; \
214
TCGLabel *over = gen_new_label(); \
215
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
216
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
217
\
218
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
219
@@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
220
require_vm(a->vm, a->rd)) {
221
uint32_t data = 0;
222
TCGLabel *over = gen_new_label();
223
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
224
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
225
226
data = FIELD_DP32(data, VDATA, VM, a->vm);
227
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
228
TCGv s1;
229
TCGLabel *over = gen_new_label();
230
231
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
232
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
233
234
t1 = tcg_temp_new_i64();
235
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
236
TCGv_i64 t1;
237
TCGLabel *over = gen_new_label();
238
239
- /* if vl == 0 or vstart >= vl, skip vector register write back */
240
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
241
+ /* if vstart >= vl, skip vector register write back */
242
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
243
244
/* NaN-box f[rs1] */
245
@@ -XXX,XX +XXX,XX @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
246
uint32_t data = 0;
247
gen_helper_gvec_3_ptr *fn;
248
TCGLabel *over = gen_new_label();
249
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
250
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
251
252
static gen_helper_gvec_3_ptr * const fns[6][4] = {
253
--
254
2.41.0
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
2
2
3
The only setting of RISCV_FRM_ROD is from the vector unit,
3
This commit adds support for the Zvbc vector-crypto extension, which
4
and now handled by helper_set_rounding_mode_chkfrm.
4
consists of the following instructions:
5
This helper is now unused.
5
6
6
* vclmulh.[vx,vv]
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
* vclmul.[vx,vv]
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Translation functions are defined in
10
Message-Id: <20230115160657.3169274-3-richard.henderson@linaro.org>
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
14
Co-authored-by: Max Chou <max.chou@sifive.com>
15
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
16
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
17
Signed-off-by: Max Chou <max.chou@sifive.com>
18
[max.chou@sifive.com: Exposed x-zvbc property]
19
Message-ID: <20230711165917.2629866-5-max.chou@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
21
---
13
target/riscv/helper.h | 1 -
22
target/riscv/cpu_cfg.h | 1 +
14
target/riscv/fpu_helper.c | 5 -----
23
target/riscv/helper.h | 6 +++
15
target/riscv/translate.c | 4 ----
24
target/riscv/insn32.decode | 6 +++
16
3 files changed, 10 deletions(-)
25
target/riscv/cpu.c | 9 ++++
17
26
target/riscv/translate.c | 1 +
27
target/riscv/vcrypto_helper.c | 59 ++++++++++++++++++++++
28
target/riscv/insn_trans/trans_rvvk.c.inc | 62 ++++++++++++++++++++++++
29
target/riscv/meson.build | 3 +-
30
8 files changed, 146 insertions(+), 1 deletion(-)
31
create mode 100644 target/riscv/vcrypto_helper.c
32
create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc
33
34
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/riscv/cpu_cfg.h
37
+++ b/target/riscv/cpu_cfg.h
38
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
39
bool ext_zve32f;
40
bool ext_zve64f;
41
bool ext_zve64d;
42
+ bool ext_zvbc;
43
bool ext_zmmul;
44
bool ext_zvfbfmin;
45
bool ext_zvfbfwma;
18
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
46
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
19
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/helper.h
48
--- a/target/riscv/helper.h
21
+++ b/target/riscv/helper.h
49
+++ b/target/riscv/helper.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(raise_exception, noreturn, env, i32)
50
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vfwcvtbf16_f_f_v, void, ptr, ptr, ptr, env, i32)
23
/* Floating Point - rounding mode */
51
24
DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32)
52
DEF_HELPER_6(vfwmaccbf16_vv, void, ptr, ptr, ptr, ptr, env, i32)
25
DEF_HELPER_FLAGS_2(set_rounding_mode_chkfrm, TCG_CALL_NO_WG, void, env, i32)
53
DEF_HELPER_6(vfwmaccbf16_vf, void, ptr, ptr, i64, ptr, env, i32)
26
-DEF_HELPER_FLAGS_1(set_rod_rounding_mode, TCG_CALL_NO_WG, void, env)
54
+
27
55
+/* Vector crypto functions */
28
/* Floating Point - fused */
56
+DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
29
DEF_HELPER_FLAGS_4(fmadd_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
57
+DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
30
diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
58
+DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
31
index XXXXXXX..XXXXXXX 100644
59
+DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
32
--- a/target/riscv/fpu_helper.c
60
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
33
+++ b/target/riscv/fpu_helper.c
61
index XXXXXXX..XXXXXXX 100644
34
@@ -XXX,XX +XXX,XX @@ void helper_set_rounding_mode_chkfrm(CPURISCVState *env, uint32_t rm)
62
--- a/target/riscv/insn32.decode
35
set_float_rounding_mode(softrm, &env->fp_status);
63
+++ b/target/riscv/insn32.decode
36
}
64
@@ -XXX,XX +XXX,XX @@ vfwcvtbf16_f_f_v 010010 . ..... 01101 001 ..... 1010111 @r2_vm
37
65
# *** Zvfbfwma Standard Extension ***
38
-void helper_set_rod_rounding_mode(CPURISCVState *env)
66
vfwmaccbf16_vv 111011 . ..... ..... 001 ..... 1010111 @r_vm
39
-{
67
vfwmaccbf16_vf 111011 . ..... ..... 101 ..... 1010111 @r_vm
40
- set_float_rounding_mode(float_round_to_odd, &env->fp_status);
68
+
41
-}
69
+# *** Zvbc vector crypto extension ***
42
-
70
+vclmul_vv 001100 . ..... ..... 010 ..... 1010111 @r_vm
43
static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
71
+vclmul_vx 001100 . ..... ..... 110 ..... 1010111 @r_vm
44
uint64_t rs3, int flags)
72
+vclmulh_vv 001101 . ..... ..... 010 ..... 1010111 @r_vm
45
{
73
+vclmulh_vx 001101 . ..... ..... 110 ..... 1010111 @r_vm
74
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/riscv/cpu.c
77
+++ b/target/riscv/cpu.c
78
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
79
ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
80
ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
81
ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
82
+ ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
83
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
84
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
85
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
86
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
87
return;
88
}
89
90
+ if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
91
+ error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
92
+ return;
93
+ }
94
+
95
if (cpu->cfg.ext_zk) {
96
cpu->cfg.ext_zkn = true;
97
cpu->cfg.ext_zkr = true;
98
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
99
DEFINE_PROP_BOOL("x-zvfbfmin", RISCVCPU, cfg.ext_zvfbfmin, false),
100
DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
101
102
+ /* Vector cryptography extensions */
103
+ DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
104
+
105
DEFINE_PROP_END_OF_LIST(),
106
};
107
46
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
108
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
47
index XXXXXXX..XXXXXXX 100644
109
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/translate.c
110
--- a/target/riscv/translate.c
49
+++ b/target/riscv/translate.c
111
+++ b/target/riscv/translate.c
50
@@ -XXX,XX +XXX,XX @@ static void gen_set_rm(DisasContext *ctx, int rm)
112
@@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
51
}
113
#include "insn_trans/trans_rvzfa.c.inc"
52
ctx->frm = rm;
114
#include "insn_trans/trans_rvzfh.c.inc"
53
115
#include "insn_trans/trans_rvk.c.inc"
54
- if (rm == RISCV_FRM_ROD) {
116
+#include "insn_trans/trans_rvvk.c.inc"
55
- gen_helper_set_rod_rounding_mode(cpu_env);
117
#include "insn_trans/trans_privileged.c.inc"
56
- return;
118
#include "insn_trans/trans_svinval.c.inc"
57
- }
119
#include "insn_trans/trans_rvbf16.c.inc"
58
if (rm == RISCV_FRM_DYN) {
120
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
59
/* The helper will return only if frm valid. */
121
new file mode 100644
60
ctx->frm_valid = true;
122
index XXXXXXX..XXXXXXX
123
--- /dev/null
124
+++ b/target/riscv/vcrypto_helper.c
125
@@ -XXX,XX +XXX,XX @@
126
+/*
127
+ * RISC-V Vector Crypto Extension Helpers for QEMU.
128
+ *
129
+ * Copyright (C) 2023 SiFive, Inc.
130
+ * Written by Codethink Ltd and SiFive.
131
+ *
132
+ * This program is free software; you can redistribute it and/or modify it
133
+ * under the terms and conditions of the GNU General Public License,
134
+ * version 2 or later, as published by the Free Software Foundation.
135
+ *
136
+ * This program is distributed in the hope it will be useful, but WITHOUT
137
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
138
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
139
+ * more details.
140
+ *
141
+ * You should have received a copy of the GNU General Public License along with
142
+ * this program. If not, see <http://www.gnu.org/licenses/>.
143
+ */
144
+
145
+#include "qemu/osdep.h"
146
+#include "qemu/host-utils.h"
147
+#include "qemu/bitops.h"
148
+#include "cpu.h"
149
+#include "exec/memop.h"
150
+#include "exec/exec-all.h"
151
+#include "exec/helper-proto.h"
152
+#include "internals.h"
153
+#include "vector_internals.h"
154
+
155
+static uint64_t clmul64(uint64_t y, uint64_t x)
156
+{
157
+ uint64_t result = 0;
158
+ for (int j = 63; j >= 0; j--) {
159
+ if ((y >> j) & 1) {
160
+ result ^= (x << j);
161
+ }
162
+ }
163
+ return result;
164
+}
165
+
166
+static uint64_t clmulh64(uint64_t y, uint64_t x)
167
+{
168
+ uint64_t result = 0;
169
+ for (int j = 63; j >= 1; j--) {
170
+ if ((y >> j) & 1) {
171
+ result ^= (x >> (64 - j));
172
+ }
173
+ }
174
+ return result;
175
+}
176
+
177
+RVVCALL(OPIVV2, vclmul_vv, OP_UUU_D, H8, H8, H8, clmul64)
178
+GEN_VEXT_VV(vclmul_vv, 8)
179
+RVVCALL(OPIVX2, vclmul_vx, OP_UUU_D, H8, H8, clmul64)
180
+GEN_VEXT_VX(vclmul_vx, 8)
181
+RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64)
182
+GEN_VEXT_VV(vclmulh_vv, 8)
183
+RVVCALL(OPIVX2, vclmulh_vx, OP_UUU_D, H8, H8, clmulh64)
184
+GEN_VEXT_VX(vclmulh_vx, 8)
185
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
186
new file mode 100644
187
index XXXXXXX..XXXXXXX
188
--- /dev/null
189
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
190
@@ -XXX,XX +XXX,XX @@
191
+/*
192
+ * RISC-V translation routines for the vector crypto extension.
193
+ *
194
+ * Copyright (C) 2023 SiFive, Inc.
195
+ * Written by Codethink Ltd and SiFive.
196
+ *
197
+ * This program is free software; you can redistribute it and/or modify it
198
+ * under the terms and conditions of the GNU General Public License,
199
+ * version 2 or later, as published by the Free Software Foundation.
200
+ *
201
+ * This program is distributed in the hope it will be useful, but WITHOUT
202
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
203
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
204
+ * more details.
205
+ *
206
+ * You should have received a copy of the GNU General Public License along with
207
+ * this program. If not, see <http://www.gnu.org/licenses/>.
208
+ */
209
+
210
+/*
211
+ * Zvbc
212
+ */
213
+
214
+#define GEN_VV_MASKED_TRANS(NAME, CHECK) \
215
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
216
+ { \
217
+ if (CHECK(s, a)) { \
218
+ return opivv_trans(a->rd, a->rs1, a->rs2, a->vm, \
219
+ gen_helper_##NAME, s); \
220
+ } \
221
+ return false; \
222
+ }
223
+
224
+static bool vclmul_vv_check(DisasContext *s, arg_rmrr *a)
225
+{
226
+ return opivv_check(s, a) &&
227
+ s->cfg_ptr->ext_zvbc == true &&
228
+ s->sew == MO_64;
229
+}
230
+
231
+GEN_VV_MASKED_TRANS(vclmul_vv, vclmul_vv_check)
232
+GEN_VV_MASKED_TRANS(vclmulh_vv, vclmul_vv_check)
233
+
234
+#define GEN_VX_MASKED_TRANS(NAME, CHECK) \
235
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
236
+ { \
237
+ if (CHECK(s, a)) { \
238
+ return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, \
239
+ gen_helper_##NAME, s); \
240
+ } \
241
+ return false; \
242
+ }
243
+
244
+static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a)
245
+{
246
+ return opivx_check(s, a) &&
247
+ s->cfg_ptr->ext_zvbc == true &&
248
+ s->sew == MO_64;
249
+}
250
+
251
+GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check)
252
+GEN_VX_MASKED_TRANS(vclmulh_vx, vclmul_vx_check)
253
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
254
index XXXXXXX..XXXXXXX 100644
255
--- a/target/riscv/meson.build
256
+++ b/target/riscv/meson.build
257
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(files(
258
'translate.c',
259
'm128_helper.c',
260
'crypto_helper.c',
261
- 'zce_helper.c'
262
+ 'zce_helper.c',
263
+ 'vcrypto_helper.c'
264
))
265
riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c'))
266
61
--
267
--
62
2.39.0
268
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
All callers are using kernel_filename as machine->kernel_filename.
3
Move the checks out of `do_opiv{v,x,i}_gvec{,_shift}` functions
4
and into the corresponding macros. This enables the functions to be
5
reused in proceeding commits without check duplication.
4
6
5
This will also simplify the changes in riscv_load_kernel() that we're
7
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
6
going to do next.
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
9
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Cc: Palmer Dabbelt <palmer@dabbelt.com>
10
Signed-off-by: Max Chou <max.chou@sifive.com>
9
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Message-ID: <20230711165917.2629866-6-max.chou@sifive.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Bin Meng <bmeng@tinylab.org>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-Id: <20230102115241.25733-10-dbarboza@ventanamicro.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
13
---
16
include/hw/riscv/boot.h | 2 +-
14
target/riscv/insn_trans/trans_rvv.c.inc | 28 +++++++++++--------------
17
hw/riscv/boot.c | 3 ++-
15
1 file changed, 12 insertions(+), 16 deletions(-)
18
hw/riscv/microchip_pfsoc.c | 3 +--
19
hw/riscv/opentitan.c | 3 +--
20
hw/riscv/sifive_e.c | 3 +--
21
hw/riscv/sifive_u.c | 3 +--
22
hw/riscv/spike.c | 3 +--
23
hw/riscv/virt.c | 3 +--
24
8 files changed, 9 insertions(+), 14 deletions(-)
25
16
26
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
17
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
27
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/riscv/boot.h
19
--- a/target/riscv/insn_trans/trans_rvv.c.inc
29
+++ b/include/hw/riscv/boot.h
20
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
30
@@ -XXX,XX +XXX,XX @@ char *riscv_find_firmware(const char *firmware_filename,
21
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
31
target_ulong riscv_load_firmware(const char *firmware_filename,
22
gen_helper_gvec_4_ptr *fn)
32
hwaddr firmware_load_addr,
23
{
33
symbol_fn_t sym_cb);
24
TCGLabel *over = gen_new_label();
34
-target_ulong riscv_load_kernel(const char *kernel_filename,
25
- if (!opivv_check(s, a)) {
35
+target_ulong riscv_load_kernel(MachineState *machine,
26
- return false;
36
target_ulong firmware_end_addr,
27
- }
37
symbol_fn_t sym_cb);
28
38
void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry);
29
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
39
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
30
40
index XXXXXXX..XXXXXXX 100644
31
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
41
--- a/hw/riscv/boot.c
32
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
42
+++ b/hw/riscv/boot.c
33
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
43
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_firmware(const char *firmware_filename,
34
}; \
44
exit(1);
35
+ if (!opivv_check(s, a)) { \
36
+ return false; \
37
+ } \
38
return do_opivv_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
45
}
39
}
46
40
47
-target_ulong riscv_load_kernel(const char *kernel_filename,
41
@@ -XXX,XX +XXX,XX @@ static inline bool
48
+target_ulong riscv_load_kernel(MachineState *machine,
42
do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
49
target_ulong kernel_start_addr,
43
gen_helper_opivx *fn)
50
symbol_fn_t sym_cb)
51
{
44
{
52
+ const char *kernel_filename = machine->kernel_filename;
45
- if (!opivx_check(s, a)) {
53
uint64_t kernel_load_base, kernel_entry;
46
- return false;
54
47
- }
55
g_assert(kernel_filename != NULL);
48
-
56
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
49
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
57
index XXXXXXX..XXXXXXX 100644
50
TCGv_i64 src1 = tcg_temp_new_i64();
58
--- a/hw/riscv/microchip_pfsoc.c
51
59
+++ b/hw/riscv/microchip_pfsoc.c
52
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
60
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
53
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
61
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc.u_cpus,
54
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
62
firmware_end_addr);
55
}; \
63
56
+ if (!opivx_check(s, a)) { \
64
- kernel_entry = riscv_load_kernel(machine->kernel_filename,
57
+ return false; \
65
- kernel_start_addr, NULL);
58
+ } \
66
+ kernel_entry = riscv_load_kernel(machine, kernel_start_addr, NULL);
59
return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
67
68
if (machine->initrd_filename) {
69
riscv_load_initrd(machine, kernel_entry);
70
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/hw/riscv/opentitan.c
73
+++ b/hw/riscv/opentitan.c
74
@@ -XXX,XX +XXX,XX @@ static void opentitan_board_init(MachineState *machine)
75
}
76
77
if (machine->kernel_filename) {
78
- riscv_load_kernel(machine->kernel_filename,
79
- memmap[IBEX_DEV_RAM].base, NULL);
80
+ riscv_load_kernel(machine, memmap[IBEX_DEV_RAM].base, NULL);
81
}
82
}
60
}
83
61
84
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
62
@@ -XXX,XX +XXX,XX @@ static inline bool
85
index XXXXXXX..XXXXXXX 100644
63
do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn,
86
--- a/hw/riscv/sifive_e.c
64
gen_helper_opivx *fn, imm_mode_t imm_mode)
87
+++ b/hw/riscv/sifive_e.c
65
{
88
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_init(MachineState *machine)
66
- if (!opivx_check(s, a)) {
89
memmap[SIFIVE_E_DEV_MROM].base, &address_space_memory);
67
- return false;
90
68
- }
91
if (machine->kernel_filename) {
69
-
92
- riscv_load_kernel(machine->kernel_filename,
70
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
93
- memmap[SIFIVE_E_DEV_DTIM].base, NULL);
71
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
94
+ riscv_load_kernel(machine, memmap[SIFIVE_E_DEV_DTIM].base, NULL);
72
extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s));
95
}
73
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
74
gen_helper_##OPIVX##_b, gen_helper_##OPIVX##_h, \
75
gen_helper_##OPIVX##_w, gen_helper_##OPIVX##_d, \
76
}; \
77
+ if (!opivx_check(s, a)) { \
78
+ return false; \
79
+ } \
80
return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, \
81
fns[s->sew], IMM_MODE); \
96
}
82
}
97
83
@@ -XXX,XX +XXX,XX @@ static inline bool
98
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
84
do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
99
index XXXXXXX..XXXXXXX 100644
85
gen_helper_opivx *fn)
100
--- a/hw/riscv/sifive_u.c
86
{
101
+++ b/hw/riscv/sifive_u.c
87
- if (!opivx_check(s, a)) {
102
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
88
- return false;
103
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc.u_cpus,
89
- }
104
firmware_end_addr);
90
-
105
91
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
106
- kernel_entry = riscv_load_kernel(machine->kernel_filename,
92
TCGv_i32 src1 = tcg_temp_new_i32();
107
- kernel_start_addr, NULL);
93
108
+ kernel_entry = riscv_load_kernel(machine, kernel_start_addr, NULL);
94
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
109
95
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
110
if (machine->initrd_filename) {
96
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
111
riscv_load_initrd(machine, kernel_entry);
97
}; \
112
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
98
- \
113
index XXXXXXX..XXXXXXX 100644
99
+ if (!opivx_check(s, a)) { \
114
--- a/hw/riscv/spike.c
100
+ return false; \
115
+++ b/hw/riscv/spike.c
101
+ } \
116
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
102
return do_opivx_gvec_shift(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
117
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0],
103
}
118
firmware_end_addr);
104
119
120
- kernel_entry = riscv_load_kernel(machine->kernel_filename,
121
- kernel_start_addr,
122
+ kernel_entry = riscv_load_kernel(machine, kernel_start_addr,
123
htif_symbol_callback);
124
125
if (machine->initrd_filename) {
126
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/riscv/virt.c
129
+++ b/hw/riscv/virt.c
130
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
131
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0],
132
firmware_end_addr);
133
134
- kernel_entry = riscv_load_kernel(machine->kernel_filename,
135
- kernel_start_addr, NULL);
136
+ kernel_entry = riscv_load_kernel(machine, kernel_start_addr, NULL);
137
138
if (machine->initrd_filename) {
139
riscv_load_initrd(machine, kernel_entry);
140
--
105
--
141
2.39.0
106
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Dickon Hood <dickon.hood@codethink.co.uk>
2
2
3
riscv_load_initrd() returns the initrd end addr while also writing a
3
Zvbb (implemented in later commit) has a widening instruction, which
4
'start' var to mark the addr start. These informations are being used
4
requires an extra check on the enabled extensions. Refactor
5
just to write the initrd FDT node. Every existing caller of
5
GEN_OPIVX_WIDEN_TRANS() to take a check function to avoid reimplementing
6
riscv_load_initrd() is writing the FDT in the same manner.
6
it.
7
7
8
We can simplify things by writing the FDT inside riscv_load_initrd(),
8
Signed-off-by: Dickon Hood <dickon.hood@codethink.co.uk>
9
sparing callers from having to manage start/end addrs to write the FDT
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
themselves.
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
11
11
Signed-off-by: Max Chou <max.chou@sifive.com>
12
An 'if (fdt)' check is already inserted at the end of the function
12
Message-ID: <20230711165917.2629866-7-max.chou@sifive.com>
13
because we'll end up using it later on with other boards that doesn´t
14
have a FDT.
15
16
Cc: Palmer Dabbelt <palmer@dabbelt.com>
17
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
18
Reviewed-by: Bin Meng <bmeng@tinylab.org>
19
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-Id: <20230102115241.25733-7-dbarboza@ventanamicro.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
14
---
24
include/hw/riscv/boot.h | 4 ++--
15
target/riscv/insn_trans/trans_rvv.c.inc | 52 +++++++++++--------------
25
hw/riscv/boot.c | 18 ++++++++++++------
16
1 file changed, 23 insertions(+), 29 deletions(-)
26
hw/riscv/microchip_pfsoc.c | 10 ++--------
27
hw/riscv/sifive_u.c | 10 ++--------
28
hw/riscv/spike.c | 10 ++--------
29
hw/riscv/virt.c | 10 ++--------
30
6 files changed, 22 insertions(+), 40 deletions(-)
31
17
32
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
18
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
33
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
34
--- a/include/hw/riscv/boot.h
20
--- a/target/riscv/insn_trans/trans_rvv.c.inc
35
+++ b/include/hw/riscv/boot.h
21
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
36
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_firmware(const char *firmware_filename,
22
@@ -XXX,XX +XXX,XX @@ static bool opivx_widen_check(DisasContext *s, arg_rmrr *a)
37
target_ulong riscv_load_kernel(const char *kernel_filename,
23
vext_check_ds(s, a->rd, a->rs2, a->vm);
38
target_ulong firmware_end_addr,
39
symbol_fn_t sym_cb);
40
-hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
41
- uint64_t kernel_entry, hwaddr *start);
42
+void riscv_load_initrd(const char *filename, uint64_t mem_size,
43
+ uint64_t kernel_entry, void *fdt);
44
uint64_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt);
45
void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts,
46
hwaddr saddr,
47
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/riscv/boot.c
50
+++ b/hw/riscv/boot.c
51
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(const char *kernel_filename,
52
exit(1);
53
}
24
}
54
25
55
-hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
26
-static bool do_opivx_widen(DisasContext *s, arg_rmrr *a,
56
- uint64_t kernel_entry, hwaddr *start)
27
- gen_helper_opivx *fn)
57
+void riscv_load_initrd(const char *filename, uint64_t mem_size,
28
-{
58
+ uint64_t kernel_entry, void *fdt)
29
- if (opivx_widen_check(s, a)) {
59
{
30
- return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
60
+ hwaddr start, end;
31
- }
61
ssize_t size;
32
- return false;
62
33
-}
63
g_assert(filename != NULL);
34
-
64
@@ -XXX,XX +XXX,XX @@ hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
35
-#define GEN_OPIVX_WIDEN_TRANS(NAME) \
65
* halfway into RAM, and for boards with 256MB of RAM or more we put
36
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
66
* the initrd at 128MB.
37
-{ \
67
*/
38
- static gen_helper_opivx * const fns[3] = { \
68
- *start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
39
- gen_helper_##NAME##_b, \
69
+ start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
40
- gen_helper_##NAME##_h, \
70
41
- gen_helper_##NAME##_w \
71
- size = load_ramdisk(filename, *start, mem_size - *start);
42
- }; \
72
+ size = load_ramdisk(filename, start, mem_size - start);
43
- return do_opivx_widen(s, a, fns[s->sew]); \
73
if (size == -1) {
44
+#define GEN_OPIVX_WIDEN_TRANS(NAME, CHECK) \
74
- size = load_image_targphys(filename, *start, mem_size - *start);
45
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
75
+ size = load_image_targphys(filename, start, mem_size - start);
46
+{ \
76
if (size == -1) {
47
+ if (CHECK(s, a)) { \
77
error_report("could not load ramdisk '%s'", filename);
48
+ static gen_helper_opivx * const fns[3] = { \
78
exit(1);
49
+ gen_helper_##NAME##_b, \
79
}
50
+ gen_helper_##NAME##_h, \
80
}
51
+ gen_helper_##NAME##_w \
81
52
+ }; \
82
- return *start + size;
53
+ return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s); \
83
+ /* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
54
+ } \
84
+ if (fdt) {
55
+ return false; \
85
+ end = start + size;
86
+ qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
87
+ qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
88
+ }
89
}
56
}
90
57
91
uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
58
-GEN_OPIVX_WIDEN_TRANS(vwaddu_vx)
92
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
59
-GEN_OPIVX_WIDEN_TRANS(vwadd_vx)
93
index XXXXXXX..XXXXXXX 100644
60
-GEN_OPIVX_WIDEN_TRANS(vwsubu_vx)
94
--- a/hw/riscv/microchip_pfsoc.c
61
-GEN_OPIVX_WIDEN_TRANS(vwsub_vx)
95
+++ b/hw/riscv/microchip_pfsoc.c
62
+GEN_OPIVX_WIDEN_TRANS(vwaddu_vx, opivx_widen_check)
96
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
63
+GEN_OPIVX_WIDEN_TRANS(vwadd_vx, opivx_widen_check)
97
kernel_start_addr, NULL);
64
+GEN_OPIVX_WIDEN_TRANS(vwsubu_vx, opivx_widen_check)
98
65
+GEN_OPIVX_WIDEN_TRANS(vwsub_vx, opivx_widen_check)
99
if (machine->initrd_filename) {
66
100
- hwaddr start;
67
/* WIDEN OPIVV with WIDEN */
101
- hwaddr end = riscv_load_initrd(machine->initrd_filename,
68
static bool opiwv_widen_check(DisasContext *s, arg_rmrr *a)
102
- machine->ram_size, kernel_entry,
69
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vrem_vx, opivx_check)
103
- &start);
70
GEN_OPIVV_WIDEN_TRANS(vwmul_vv, opivv_widen_check)
104
- qemu_fdt_setprop_cell(machine->fdt, "/chosen",
71
GEN_OPIVV_WIDEN_TRANS(vwmulu_vv, opivv_widen_check)
105
- "linux,initrd-start", start);
72
GEN_OPIVV_WIDEN_TRANS(vwmulsu_vv, opivv_widen_check)
106
- qemu_fdt_setprop_cell(machine->fdt, "/chosen",
73
-GEN_OPIVX_WIDEN_TRANS(vwmul_vx)
107
- "linux,initrd-end", end);
74
-GEN_OPIVX_WIDEN_TRANS(vwmulu_vx)
108
+ riscv_load_initrd(machine->initrd_filename, machine->ram_size,
75
-GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx)
109
+ kernel_entry, machine->fdt);
76
+GEN_OPIVX_WIDEN_TRANS(vwmul_vx, opivx_widen_check)
110
}
77
+GEN_OPIVX_WIDEN_TRANS(vwmulu_vx, opivx_widen_check)
111
78
+GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx, opivx_widen_check)
112
if (machine->kernel_cmdline && *machine->kernel_cmdline) {
79
113
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
80
/* Vector Single-Width Integer Multiply-Add Instructions */
114
index XXXXXXX..XXXXXXX 100644
81
GEN_OPIVV_TRANS(vmacc_vv, opivv_check)
115
--- a/hw/riscv/sifive_u.c
82
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vnmsub_vx, opivx_check)
116
+++ b/hw/riscv/sifive_u.c
83
GEN_OPIVV_WIDEN_TRANS(vwmaccu_vv, opivv_widen_check)
117
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
84
GEN_OPIVV_WIDEN_TRANS(vwmacc_vv, opivv_widen_check)
118
kernel_start_addr, NULL);
85
GEN_OPIVV_WIDEN_TRANS(vwmaccsu_vv, opivv_widen_check)
119
86
-GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx)
120
if (machine->initrd_filename) {
87
-GEN_OPIVX_WIDEN_TRANS(vwmacc_vx)
121
- hwaddr start;
88
-GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx)
122
- hwaddr end = riscv_load_initrd(machine->initrd_filename,
89
-GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx)
123
- machine->ram_size, kernel_entry,
90
+GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx, opivx_widen_check)
124
- &start);
91
+GEN_OPIVX_WIDEN_TRANS(vwmacc_vx, opivx_widen_check)
125
- qemu_fdt_setprop_cell(machine->fdt, "/chosen",
92
+GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx, opivx_widen_check)
126
- "linux,initrd-start", start);
93
+GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx, opivx_widen_check)
127
- qemu_fdt_setprop_cell(machine->fdt, "/chosen", "linux,initrd-end",
94
128
- end);
95
/* Vector Integer Merge and Move Instructions */
129
+ riscv_load_initrd(machine->initrd_filename, machine->ram_size,
96
static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
130
+ kernel_entry, machine->fdt);
131
}
132
} else {
133
/*
134
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
135
index XXXXXXX..XXXXXXX 100644
136
--- a/hw/riscv/spike.c
137
+++ b/hw/riscv/spike.c
138
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
139
htif_symbol_callback);
140
141
if (machine->initrd_filename) {
142
- hwaddr start;
143
- hwaddr end = riscv_load_initrd(machine->initrd_filename,
144
- machine->ram_size, kernel_entry,
145
- &start);
146
- qemu_fdt_setprop_cell(machine->fdt, "/chosen",
147
- "linux,initrd-start", start);
148
- qemu_fdt_setprop_cell(machine->fdt, "/chosen", "linux,initrd-end",
149
- end);
150
+ riscv_load_initrd(machine->initrd_filename, machine->ram_size,
151
+ kernel_entry, machine->fdt);
152
}
153
} else {
154
/*
155
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/hw/riscv/virt.c
158
+++ b/hw/riscv/virt.c
159
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
160
kernel_start_addr, NULL);
161
162
if (machine->initrd_filename) {
163
- hwaddr start;
164
- hwaddr end = riscv_load_initrd(machine->initrd_filename,
165
- machine->ram_size, kernel_entry,
166
- &start);
167
- qemu_fdt_setprop_cell(machine->fdt, "/chosen",
168
- "linux,initrd-start", start);
169
- qemu_fdt_setprop_cell(machine->fdt, "/chosen", "linux,initrd-end",
170
- end);
171
+ riscv_load_initrd(machine->initrd_filename, machine->ram_size,
172
+ kernel_entry, machine->fdt);
173
}
174
} else {
175
/*
176
--
97
--
177
2.39.0
98
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
The only caller is riscv_find_and_load_firmware(), which is in the same
3
Move some macros out of `vector_helper` and into `vector_internals`.
4
file.
4
This ensures they can be used by both vector and vector-crypto helpers
5
(latter implemented in proceeding commits).
5
6
6
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Max Chou <max.chou@sifive.com>
9
Reviewed-by: Bin Meng <bmeng@tinylab.org>
10
Message-ID: <20230711165917.2629866-8-max.chou@sifive.com>
10
Signed-off-by: Bin Meng <bmeng@tinylab.org>
11
Message-Id: <20221221182300.307900-5-dbarboza@ventanamicro.com>
12
Message-Id: <20221229091828.1945072-10-bmeng@tinylab.org>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
12
---
15
include/hw/riscv/boot.h | 1 -
13
target/riscv/vector_internals.h | 46 +++++++++++++++++++++++++++++++++
16
hw/riscv/boot.c | 44 ++++++++++++++++++++---------------------
14
target/riscv/vector_helper.c | 42 ------------------------------
17
2 files changed, 22 insertions(+), 23 deletions(-)
15
2 files changed, 46 insertions(+), 42 deletions(-)
18
16
19
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
17
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/riscv/boot.h
19
--- a/target/riscv/vector_internals.h
22
+++ b/include/hw/riscv/boot.h
20
+++ b/target/riscv/vector_internals.h
23
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_find_and_load_firmware(MachineState *machine,
21
@@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
24
const char *default_machine_firmware,
22
/* expand macro args before macro */
25
hwaddr firmware_load_addr,
23
#define RVVCALL(macro, ...) macro(__VA_ARGS__)
26
symbol_fn_t sym_cb);
24
27
-char *riscv_find_firmware(const char *firmware_filename);
25
+/* (TD, T2, TX2) */
28
target_ulong riscv_load_firmware(const char *firmware_filename,
26
+#define OP_UU_B uint8_t, uint8_t, uint8_t
29
hwaddr firmware_load_addr,
27
+#define OP_UU_H uint16_t, uint16_t, uint16_t
30
symbol_fn_t sym_cb);
28
+#define OP_UU_W uint32_t, uint32_t, uint32_t
31
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
29
+#define OP_UU_D uint64_t, uint64_t, uint64_t
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/riscv/boot.c
34
+++ b/hw/riscv/boot.c
35
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState *harts,
36
}
37
}
38
39
+static char *riscv_find_firmware(const char *firmware_filename)
40
+{
41
+ char *filename;
42
+
30
+
43
+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware_filename);
31
/* (TD, T1, T2, TX1, TX2) */
44
+ if (filename == NULL) {
32
#define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
45
+ if (!qtest_enabled()) {
33
#define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t
46
+ /*
34
#define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t
47
+ * We only ship OpenSBI binary bios images in the QEMU source.
35
#define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t
48
+ * For machines that use images other than the default bios,
36
49
+ * running QEMU test will complain hence let's suppress the error
37
+#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
50
+ * report for QEMU testing.
38
+static void do_##NAME(void *vd, void *vs2, int i) \
51
+ */
39
+{ \
52
+ error_report("Unable to load the RISC-V firmware \"%s\"",
40
+ TX2 s2 = *((T2 *)vs2 + HS2(i)); \
53
+ firmware_filename);
41
+ *((TD *)vd + HD(i)) = OP(s2); \
54
+ exit(1);
55
+ }
56
+ }
57
+
58
+ return filename;
59
+}
42
+}
60
+
43
+
61
target_ulong riscv_find_and_load_firmware(MachineState *machine,
44
+#define GEN_VEXT_V(NAME, ESZ) \
62
const char *default_machine_firmware,
45
+void HELPER(NAME)(void *vd, void *v0, void *vs2, \
63
hwaddr firmware_load_addr,
46
+ CPURISCVState *env, uint32_t desc) \
64
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_find_and_load_firmware(MachineState *machine,
47
+{ \
65
return firmware_end_addr;
48
+ uint32_t vm = vext_vm(desc); \
49
+ uint32_t vl = env->vl; \
50
+ uint32_t total_elems = \
51
+ vext_get_total_elems(env, desc, ESZ); \
52
+ uint32_t vta = vext_vta(desc); \
53
+ uint32_t vma = vext_vma(desc); \
54
+ uint32_t i; \
55
+ \
56
+ for (i = env->vstart; i < vl; i++) { \
57
+ if (!vm && !vext_elem_mask(v0, i)) { \
58
+ /* set masked-off elements to 1s */ \
59
+ vext_set_elems_1s(vd, vma, i * ESZ, \
60
+ (i + 1) * ESZ); \
61
+ continue; \
62
+ } \
63
+ do_##NAME(vd, vs2, i); \
64
+ } \
65
+ env->vstart = 0; \
66
+ /* set tail elements to 1s */ \
67
+ vext_set_elems_1s(vd, vta, vl * ESZ, \
68
+ total_elems * ESZ); \
69
+}
70
+
71
/* operation of two vector elements */
72
typedef void opivv2_fn(void *vd, void *vs1, void *vs2, int i);
73
74
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
75
do_##NAME, ESZ); \
66
}
76
}
67
77
68
-char *riscv_find_firmware(const char *firmware_filename)
78
+/* Three of the widening shortening macros: */
69
-{
79
+/* (TD, T1, T2, TX1, TX2) */
70
- char *filename;
80
+#define WOP_UUU_B uint16_t, uint8_t, uint8_t, uint16_t, uint16_t
81
+#define WOP_UUU_H uint32_t, uint16_t, uint16_t, uint32_t, uint32_t
82
+#define WOP_UUU_W uint64_t, uint32_t, uint32_t, uint64_t, uint64_t
83
+
84
#endif /* TARGET_RISCV_VECTOR_INTERNALS_H */
85
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/riscv/vector_helper.c
88
+++ b/target/riscv/vector_helper.c
89
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
90
#define OP_SUS_H int16_t, uint16_t, int16_t, uint16_t, int16_t
91
#define OP_SUS_W int32_t, uint32_t, int32_t, uint32_t, int32_t
92
#define OP_SUS_D int64_t, uint64_t, int64_t, uint64_t, int64_t
93
-#define WOP_UUU_B uint16_t, uint8_t, uint8_t, uint16_t, uint16_t
94
-#define WOP_UUU_H uint32_t, uint16_t, uint16_t, uint32_t, uint32_t
95
-#define WOP_UUU_W uint64_t, uint32_t, uint32_t, uint64_t, uint64_t
96
#define WOP_SSS_B int16_t, int8_t, int8_t, int16_t, int16_t
97
#define WOP_SSS_H int32_t, int16_t, int16_t, int32_t, int32_t
98
#define WOP_SSS_W int64_t, int32_t, int32_t, int64_t, int64_t
99
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_VF(vfwnmsac_vf_h, 4)
100
GEN_VEXT_VF(vfwnmsac_vf_w, 8)
101
102
/* Vector Floating-Point Square-Root Instruction */
103
-/* (TD, T2, TX2) */
104
-#define OP_UU_H uint16_t, uint16_t, uint16_t
105
-#define OP_UU_W uint32_t, uint32_t, uint32_t
106
-#define OP_UU_D uint64_t, uint64_t, uint64_t
71
-
107
-
72
- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware_filename);
108
#define OPFVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
73
- if (filename == NULL) {
109
static void do_##NAME(void *vd, void *vs2, int i, \
74
- if (!qtest_enabled()) {
110
CPURISCVState *env) \
75
- /*
111
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_CMP_VF(vmfge_vf_w, uint32_t, H4, vmfge32)
76
- * We only ship OpenSBI binary bios images in the QEMU source.
112
GEN_VEXT_CMP_VF(vmfge_vf_d, uint64_t, H8, vmfge64)
77
- * For machines that use images other than the default bios,
113
78
- * running QEMU test will complain hence let's suppress the error
114
/* Vector Floating-Point Classify Instruction */
79
- * report for QEMU testing.
115
-#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
80
- */
116
-static void do_##NAME(void *vd, void *vs2, int i) \
81
- error_report("Unable to load the RISC-V firmware \"%s\"",
117
-{ \
82
- firmware_filename);
118
- TX2 s2 = *((T2 *)vs2 + HS2(i)); \
83
- exit(1);
119
- *((TD *)vd + HD(i)) = OP(s2); \
84
- }
85
- }
86
-
87
- return filename;
88
-}
120
-}
89
-
121
-
90
target_ulong riscv_load_firmware(const char *firmware_filename,
122
-#define GEN_VEXT_V(NAME, ESZ) \
91
hwaddr firmware_load_addr,
123
-void HELPER(NAME)(void *vd, void *v0, void *vs2, \
92
symbol_fn_t sym_cb)
124
- CPURISCVState *env, uint32_t desc) \
125
-{ \
126
- uint32_t vm = vext_vm(desc); \
127
- uint32_t vl = env->vl; \
128
- uint32_t total_elems = \
129
- vext_get_total_elems(env, desc, ESZ); \
130
- uint32_t vta = vext_vta(desc); \
131
- uint32_t vma = vext_vma(desc); \
132
- uint32_t i; \
133
- \
134
- for (i = env->vstart; i < vl; i++) { \
135
- if (!vm && !vext_elem_mask(v0, i)) { \
136
- /* set masked-off elements to 1s */ \
137
- vext_set_elems_1s(vd, vma, i * ESZ, \
138
- (i + 1) * ESZ); \
139
- continue; \
140
- } \
141
- do_##NAME(vd, vs2, i); \
142
- } \
143
- env->vstart = 0; \
144
- /* set tail elements to 1s */ \
145
- vext_set_elems_1s(vd, vta, vl * ESZ, \
146
- total_elems * ESZ); \
147
-}
148
-
149
target_ulong fclass_h(uint64_t frs1)
150
{
151
float16 f = frs1;
93
--
152
--
94
2.39.0
153
2.41.0
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Dickon Hood <dickon.hood@codethink.co.uk>
2
2
3
The new helper always validates the contents of FRM, even
3
This commit adds support for the Zvbb vector-crypto extension, which
4
if the new rounding mode is not DYN. This is required by
4
consists of the following instructions:
5
the vector unit.
6
5
7
Track whether we've validated FRM separately from whether
6
* vrol.[vv,vx]
8
we've updated fp_status with a given rounding mode, so that
7
* vror.[vv,vx,vi]
9
we can elide calls correctly.
8
* vbrev8.v
9
* vrev8.v
10
* vandn.[vv,vx]
11
* vbrev.v
12
* vclz.v
13
* vctz.v
14
* vcpop.v
15
* vwsll.[vv,vx,vi]
10
16
11
This partially reverts d6c4d3f2a69 which attempted the to do
17
Translation functions are defined in
12
the same thing, but with two calls to gen_set_rm(), which is
18
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
13
both inefficient and tickles an assertion in decode_save_opc.
19
`target/riscv/vcrypto_helper.c`.
14
20
15
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1441
21
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
22
Co-authored-by: William Salmon <will.salmon@codethink.co.uk>
23
Co-authored-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
24
[max.chou@sifive.com: Fix imm mode of vror.vi]
25
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
26
Signed-off-by: William Salmon <will.salmon@codethink.co.uk>
27
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
28
Signed-off-by: Dickon Hood <dickon.hood@codethink.co.uk>
29
Signed-off-by: Max Chou <max.chou@sifive.com>
17
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
30
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
18
Acked-by: Alistair Francis <alistair.francis@wdc.com>
31
[max.chou@sifive.com: Exposed x-zvbb property]
19
Message-Id: <20230115160657.3169274-2-richard.henderson@linaro.org>
32
Message-ID: <20230711165917.2629866-9-max.chou@sifive.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
34
---
22
target/riscv/helper.h | 1 +
35
target/riscv/cpu_cfg.h | 1 +
23
target/riscv/fpu_helper.c | 37 +++++++++++++++++++++++++
36
target/riscv/helper.h | 62 +++++++++
24
target/riscv/translate.c | 19 +++++++++++++
37
target/riscv/insn32.decode | 20 +++
25
target/riscv/insn_trans/trans_rvv.c.inc | 24 +++-------------
38
target/riscv/cpu.c | 12 ++
26
4 files changed, 61 insertions(+), 20 deletions(-)
39
target/riscv/vcrypto_helper.c | 138 +++++++++++++++++++
40
target/riscv/insn_trans/trans_rvvk.c.inc | 164 +++++++++++++++++++++++
41
6 files changed, 397 insertions(+)
27
42
43
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/cpu_cfg.h
46
+++ b/target/riscv/cpu_cfg.h
47
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
48
bool ext_zve32f;
49
bool ext_zve64f;
50
bool ext_zve64d;
51
+ bool ext_zvbb;
52
bool ext_zvbc;
53
bool ext_zmmul;
54
bool ext_zvfbfmin;
28
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
55
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
29
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
30
--- a/target/riscv/helper.h
57
--- a/target/riscv/helper.h
31
+++ b/target/riscv/helper.h
58
+++ b/target/riscv/helper.h
32
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(raise_exception, noreturn, env, i32)
59
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
33
60
DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
34
/* Floating Point - rounding mode */
61
DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
35
DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32)
62
DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
36
+DEF_HELPER_FLAGS_2(set_rounding_mode_chkfrm, TCG_CALL_NO_WG, void, env, i32)
63
+
37
DEF_HELPER_FLAGS_1(set_rod_rounding_mode, TCG_CALL_NO_WG, void, env)
64
+DEF_HELPER_6(vror_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
38
65
+DEF_HELPER_6(vror_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
39
/* Floating Point - fused */
66
+DEF_HELPER_6(vror_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
40
diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
67
+DEF_HELPER_6(vror_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
68
+
69
+DEF_HELPER_6(vror_vx_b, void, ptr, ptr, tl, ptr, env, i32)
70
+DEF_HELPER_6(vror_vx_h, void, ptr, ptr, tl, ptr, env, i32)
71
+DEF_HELPER_6(vror_vx_w, void, ptr, ptr, tl, ptr, env, i32)
72
+DEF_HELPER_6(vror_vx_d, void, ptr, ptr, tl, ptr, env, i32)
73
+
74
+DEF_HELPER_6(vrol_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
75
+DEF_HELPER_6(vrol_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
76
+DEF_HELPER_6(vrol_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
77
+DEF_HELPER_6(vrol_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
78
+
79
+DEF_HELPER_6(vrol_vx_b, void, ptr, ptr, tl, ptr, env, i32)
80
+DEF_HELPER_6(vrol_vx_h, void, ptr, ptr, tl, ptr, env, i32)
81
+DEF_HELPER_6(vrol_vx_w, void, ptr, ptr, tl, ptr, env, i32)
82
+DEF_HELPER_6(vrol_vx_d, void, ptr, ptr, tl, ptr, env, i32)
83
+
84
+DEF_HELPER_5(vrev8_v_b, void, ptr, ptr, ptr, env, i32)
85
+DEF_HELPER_5(vrev8_v_h, void, ptr, ptr, ptr, env, i32)
86
+DEF_HELPER_5(vrev8_v_w, void, ptr, ptr, ptr, env, i32)
87
+DEF_HELPER_5(vrev8_v_d, void, ptr, ptr, ptr, env, i32)
88
+DEF_HELPER_5(vbrev8_v_b, void, ptr, ptr, ptr, env, i32)
89
+DEF_HELPER_5(vbrev8_v_h, void, ptr, ptr, ptr, env, i32)
90
+DEF_HELPER_5(vbrev8_v_w, void, ptr, ptr, ptr, env, i32)
91
+DEF_HELPER_5(vbrev8_v_d, void, ptr, ptr, ptr, env, i32)
92
+DEF_HELPER_5(vbrev_v_b, void, ptr, ptr, ptr, env, i32)
93
+DEF_HELPER_5(vbrev_v_h, void, ptr, ptr, ptr, env, i32)
94
+DEF_HELPER_5(vbrev_v_w, void, ptr, ptr, ptr, env, i32)
95
+DEF_HELPER_5(vbrev_v_d, void, ptr, ptr, ptr, env, i32)
96
+
97
+DEF_HELPER_5(vclz_v_b, void, ptr, ptr, ptr, env, i32)
98
+DEF_HELPER_5(vclz_v_h, void, ptr, ptr, ptr, env, i32)
99
+DEF_HELPER_5(vclz_v_w, void, ptr, ptr, ptr, env, i32)
100
+DEF_HELPER_5(vclz_v_d, void, ptr, ptr, ptr, env, i32)
101
+DEF_HELPER_5(vctz_v_b, void, ptr, ptr, ptr, env, i32)
102
+DEF_HELPER_5(vctz_v_h, void, ptr, ptr, ptr, env, i32)
103
+DEF_HELPER_5(vctz_v_w, void, ptr, ptr, ptr, env, i32)
104
+DEF_HELPER_5(vctz_v_d, void, ptr, ptr, ptr, env, i32)
105
+DEF_HELPER_5(vcpop_v_b, void, ptr, ptr, ptr, env, i32)
106
+DEF_HELPER_5(vcpop_v_h, void, ptr, ptr, ptr, env, i32)
107
+DEF_HELPER_5(vcpop_v_w, void, ptr, ptr, ptr, env, i32)
108
+DEF_HELPER_5(vcpop_v_d, void, ptr, ptr, ptr, env, i32)
109
+
110
+DEF_HELPER_6(vwsll_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
111
+DEF_HELPER_6(vwsll_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
112
+DEF_HELPER_6(vwsll_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
113
+DEF_HELPER_6(vwsll_vx_b, void, ptr, ptr, tl, ptr, env, i32)
114
+DEF_HELPER_6(vwsll_vx_h, void, ptr, ptr, tl, ptr, env, i32)
115
+DEF_HELPER_6(vwsll_vx_w, void, ptr, ptr, tl, ptr, env, i32)
116
+
117
+DEF_HELPER_6(vandn_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
118
+DEF_HELPER_6(vandn_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
119
+DEF_HELPER_6(vandn_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
120
+DEF_HELPER_6(vandn_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
121
+DEF_HELPER_6(vandn_vx_b, void, ptr, ptr, tl, ptr, env, i32)
122
+DEF_HELPER_6(vandn_vx_h, void, ptr, ptr, tl, ptr, env, i32)
123
+DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, i32)
124
+DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32)
125
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
41
index XXXXXXX..XXXXXXX 100644
126
index XXXXXXX..XXXXXXX 100644
42
--- a/target/riscv/fpu_helper.c
127
--- a/target/riscv/insn32.decode
43
+++ b/target/riscv/fpu_helper.c
128
+++ b/target/riscv/insn32.decode
44
@@ -XXX,XX +XXX,XX @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
129
@@ -XXX,XX +XXX,XX @@
45
set_float_rounding_mode(softrm, &env->fp_status);
130
%imm_u 12:s20 !function=ex_shift_12
46
}
131
%imm_bs 30:2 !function=ex_shift_3
47
132
%imm_rnum 20:4
48
+void helper_set_rounding_mode_chkfrm(CPURISCVState *env, uint32_t rm)
133
+%imm_z6 26:1 15:5
49
+{
134
50
+ int softrm;
135
# Argument sets:
51
+
136
&empty
52
+ /* Always validate frm, even if rm != DYN. */
137
@@ -XXX,XX +XXX,XX @@
53
+ if (unlikely(env->frm >= 5)) {
138
@r_vm ...... vm:1 ..... ..... ... ..... ....... &rmrr %rs2 %rs1 %rd
54
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
139
@r_vm_1 ...... . ..... ..... ... ..... ....... &rmrr vm=1 %rs2 %rs1 %rd
55
+ }
140
@r_vm_0 ...... . ..... ..... ... ..... ....... &rmrr vm=0 %rs2 %rs1 %rd
56
+ if (rm == RISCV_FRM_DYN) {
141
+@r2_zimm6 ..... . vm:1 ..... ..... ... ..... ....... &rmrr %rs2 rs1=%imm_z6 %rd
57
+ rm = env->frm;
142
@r2_zimm11 . zimm:11 ..... ... ..... ....... %rs1 %rd
58
+ }
143
@r2_zimm10 .. zimm:10 ..... ... ..... ....... %rs1 %rd
59
+ switch (rm) {
144
@r2_s ....... ..... ..... ... ..... ....... %rs2 %rs1
60
+ case RISCV_FRM_RNE:
145
@@ -XXX,XX +XXX,XX @@ vclmul_vv 001100 . ..... ..... 010 ..... 1010111 @r_vm
61
+ softrm = float_round_nearest_even;
146
vclmul_vx 001100 . ..... ..... 110 ..... 1010111 @r_vm
62
+ break;
147
vclmulh_vv 001101 . ..... ..... 010 ..... 1010111 @r_vm
63
+ case RISCV_FRM_RTZ:
148
vclmulh_vx 001101 . ..... ..... 110 ..... 1010111 @r_vm
64
+ softrm = float_round_to_zero;
149
+
65
+ break;
150
+# *** Zvbb vector crypto extension ***
66
+ case RISCV_FRM_RDN:
151
+vrol_vv 010101 . ..... ..... 000 ..... 1010111 @r_vm
67
+ softrm = float_round_down;
152
+vrol_vx 010101 . ..... ..... 100 ..... 1010111 @r_vm
68
+ break;
153
+vror_vv 010100 . ..... ..... 000 ..... 1010111 @r_vm
69
+ case RISCV_FRM_RUP:
154
+vror_vx 010100 . ..... ..... 100 ..... 1010111 @r_vm
70
+ softrm = float_round_up;
155
+vror_vi 01010. . ..... ..... 011 ..... 1010111 @r2_zimm6
71
+ break;
156
+vbrev8_v 010010 . ..... 01000 010 ..... 1010111 @r2_vm
72
+ case RISCV_FRM_RMM:
157
+vrev8_v 010010 . ..... 01001 010 ..... 1010111 @r2_vm
73
+ softrm = float_round_ties_away;
158
+vandn_vv 000001 . ..... ..... 000 ..... 1010111 @r_vm
74
+ break;
159
+vandn_vx 000001 . ..... ..... 100 ..... 1010111 @r_vm
75
+ case RISCV_FRM_ROD:
160
+vbrev_v 010010 . ..... 01010 010 ..... 1010111 @r2_vm
76
+ softrm = float_round_to_odd;
161
+vclz_v 010010 . ..... 01100 010 ..... 1010111 @r2_vm
77
+ break;
162
+vctz_v 010010 . ..... 01101 010 ..... 1010111 @r2_vm
78
+ default:
163
+vcpop_v 010010 . ..... 01110 010 ..... 1010111 @r2_vm
79
+ g_assert_not_reached();
164
+vwsll_vv 110101 . ..... ..... 000 ..... 1010111 @r_vm
80
+ }
165
+vwsll_vx 110101 . ..... ..... 100 ..... 1010111 @r_vm
81
+
166
+vwsll_vi 110101 . ..... ..... 011 ..... 1010111 @r_vm
82
+ set_float_rounding_mode(softrm, &env->fp_status);
167
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
83
+}
84
+
85
void helper_set_rod_rounding_mode(CPURISCVState *env)
86
{
87
set_float_rounding_mode(float_round_to_odd, &env->fp_status);
88
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
89
index XXXXXXX..XXXXXXX 100644
168
index XXXXXXX..XXXXXXX 100644
90
--- a/target/riscv/translate.c
169
--- a/target/riscv/cpu.c
91
+++ b/target/riscv/translate.c
170
+++ b/target/riscv/cpu.c
92
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
171
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
93
bool pm_base_enabled;
172
ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
94
/* Use icount trigger for native debug */
173
ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
95
bool itrigger;
174
ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
96
+ /* FRM is known to contain a valid value. */
175
+ ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
97
+ bool frm_valid;
176
ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
98
/* TCG of the current insn_start */
177
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
99
TCGOp *insn_start;
178
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
100
} DisasContext;
179
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
101
@@ -XXX,XX +XXX,XX @@ static void gen_set_rm(DisasContext *ctx, int rm)
102
gen_helper_set_rod_rounding_mode(cpu_env);
103
return;
180
return;
104
}
181
}
105
+ if (rm == RISCV_FRM_DYN) {
182
106
+ /* The helper will return only if frm valid. */
183
+ /*
107
+ ctx->frm_valid = true;
184
+ * In principle Zve*x would also suffice here, were they supported
108
+ }
185
+ * in qemu
109
186
+ */
110
/* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
187
+ if (cpu->cfg.ext_zvbb && !cpu->cfg.ext_zve32f) {
111
decode_save_opc(ctx);
188
+ error_setg(errp,
112
gen_helper_set_rounding_mode(cpu_env, tcg_constant_i32(rm));
189
+ "Vector crypto extensions require V or Zve* extensions");
113
}
190
+ return;
114
191
+ }
115
+static void gen_set_rm_chkfrm(DisasContext *ctx, int rm)
192
+
193
if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
194
error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
195
return;
196
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
197
DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
198
199
/* Vector cryptography extensions */
200
+ DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
201
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
202
203
DEFINE_PROP_END_OF_LIST(),
204
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
205
index XXXXXXX..XXXXXXX 100644
206
--- a/target/riscv/vcrypto_helper.c
207
+++ b/target/riscv/vcrypto_helper.c
208
@@ -XXX,XX +XXX,XX @@
209
#include "qemu/osdep.h"
210
#include "qemu/host-utils.h"
211
#include "qemu/bitops.h"
212
+#include "qemu/bswap.h"
213
#include "cpu.h"
214
#include "exec/memop.h"
215
#include "exec/exec-all.h"
216
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64)
217
GEN_VEXT_VV(vclmulh_vv, 8)
218
RVVCALL(OPIVX2, vclmulh_vx, OP_UUU_D, H8, H8, clmulh64)
219
GEN_VEXT_VX(vclmulh_vx, 8)
220
+
221
+RVVCALL(OPIVV2, vror_vv_b, OP_UUU_B, H1, H1, H1, ror8)
222
+RVVCALL(OPIVV2, vror_vv_h, OP_UUU_H, H2, H2, H2, ror16)
223
+RVVCALL(OPIVV2, vror_vv_w, OP_UUU_W, H4, H4, H4, ror32)
224
+RVVCALL(OPIVV2, vror_vv_d, OP_UUU_D, H8, H8, H8, ror64)
225
+GEN_VEXT_VV(vror_vv_b, 1)
226
+GEN_VEXT_VV(vror_vv_h, 2)
227
+GEN_VEXT_VV(vror_vv_w, 4)
228
+GEN_VEXT_VV(vror_vv_d, 8)
229
+
230
+RVVCALL(OPIVX2, vror_vx_b, OP_UUU_B, H1, H1, ror8)
231
+RVVCALL(OPIVX2, vror_vx_h, OP_UUU_H, H2, H2, ror16)
232
+RVVCALL(OPIVX2, vror_vx_w, OP_UUU_W, H4, H4, ror32)
233
+RVVCALL(OPIVX2, vror_vx_d, OP_UUU_D, H8, H8, ror64)
234
+GEN_VEXT_VX(vror_vx_b, 1)
235
+GEN_VEXT_VX(vror_vx_h, 2)
236
+GEN_VEXT_VX(vror_vx_w, 4)
237
+GEN_VEXT_VX(vror_vx_d, 8)
238
+
239
+RVVCALL(OPIVV2, vrol_vv_b, OP_UUU_B, H1, H1, H1, rol8)
240
+RVVCALL(OPIVV2, vrol_vv_h, OP_UUU_H, H2, H2, H2, rol16)
241
+RVVCALL(OPIVV2, vrol_vv_w, OP_UUU_W, H4, H4, H4, rol32)
242
+RVVCALL(OPIVV2, vrol_vv_d, OP_UUU_D, H8, H8, H8, rol64)
243
+GEN_VEXT_VV(vrol_vv_b, 1)
244
+GEN_VEXT_VV(vrol_vv_h, 2)
245
+GEN_VEXT_VV(vrol_vv_w, 4)
246
+GEN_VEXT_VV(vrol_vv_d, 8)
247
+
248
+RVVCALL(OPIVX2, vrol_vx_b, OP_UUU_B, H1, H1, rol8)
249
+RVVCALL(OPIVX2, vrol_vx_h, OP_UUU_H, H2, H2, rol16)
250
+RVVCALL(OPIVX2, vrol_vx_w, OP_UUU_W, H4, H4, rol32)
251
+RVVCALL(OPIVX2, vrol_vx_d, OP_UUU_D, H8, H8, rol64)
252
+GEN_VEXT_VX(vrol_vx_b, 1)
253
+GEN_VEXT_VX(vrol_vx_h, 2)
254
+GEN_VEXT_VX(vrol_vx_w, 4)
255
+GEN_VEXT_VX(vrol_vx_d, 8)
256
+
257
+static uint64_t brev8(uint64_t val)
116
+{
258
+{
117
+ if (ctx->frm == rm && ctx->frm_valid) {
259
+ val = ((val & 0x5555555555555555ull) << 1) |
118
+ return;
260
+ ((val & 0xAAAAAAAAAAAAAAAAull) >> 1);
119
+ }
261
+ val = ((val & 0x3333333333333333ull) << 2) |
120
+ ctx->frm = rm;
262
+ ((val & 0xCCCCCCCCCCCCCCCCull) >> 2);
121
+ ctx->frm_valid = true;
263
+ val = ((val & 0x0F0F0F0F0F0F0F0Full) << 4) |
122
+
264
+ ((val & 0xF0F0F0F0F0F0F0F0ull) >> 4);
123
+ /* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
265
+
124
+ decode_save_opc(ctx);
266
+ return val;
125
+ gen_helper_set_rounding_mode_chkfrm(cpu_env, tcg_constant_i32(rm));
126
+}
267
+}
127
+
268
+
128
static int ex_plus_1(DisasContext *ctx, int nf)
269
+RVVCALL(OPIVV1, vbrev8_v_b, OP_UU_B, H1, H1, brev8)
129
{
270
+RVVCALL(OPIVV1, vbrev8_v_h, OP_UU_H, H2, H2, brev8)
130
return nf + 1;
271
+RVVCALL(OPIVV1, vbrev8_v_w, OP_UU_W, H4, H4, brev8)
131
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
272
+RVVCALL(OPIVV1, vbrev8_v_d, OP_UU_D, H8, H8, brev8)
273
+GEN_VEXT_V(vbrev8_v_b, 1)
274
+GEN_VEXT_V(vbrev8_v_h, 2)
275
+GEN_VEXT_V(vbrev8_v_w, 4)
276
+GEN_VEXT_V(vbrev8_v_d, 8)
277
+
278
+#define DO_IDENTITY(a) (a)
279
+RVVCALL(OPIVV1, vrev8_v_b, OP_UU_B, H1, H1, DO_IDENTITY)
280
+RVVCALL(OPIVV1, vrev8_v_h, OP_UU_H, H2, H2, bswap16)
281
+RVVCALL(OPIVV1, vrev8_v_w, OP_UU_W, H4, H4, bswap32)
282
+RVVCALL(OPIVV1, vrev8_v_d, OP_UU_D, H8, H8, bswap64)
283
+GEN_VEXT_V(vrev8_v_b, 1)
284
+GEN_VEXT_V(vrev8_v_h, 2)
285
+GEN_VEXT_V(vrev8_v_w, 4)
286
+GEN_VEXT_V(vrev8_v_d, 8)
287
+
288
+#define DO_ANDN(a, b) ((a) & ~(b))
289
+RVVCALL(OPIVV2, vandn_vv_b, OP_UUU_B, H1, H1, H1, DO_ANDN)
290
+RVVCALL(OPIVV2, vandn_vv_h, OP_UUU_H, H2, H2, H2, DO_ANDN)
291
+RVVCALL(OPIVV2, vandn_vv_w, OP_UUU_W, H4, H4, H4, DO_ANDN)
292
+RVVCALL(OPIVV2, vandn_vv_d, OP_UUU_D, H8, H8, H8, DO_ANDN)
293
+GEN_VEXT_VV(vandn_vv_b, 1)
294
+GEN_VEXT_VV(vandn_vv_h, 2)
295
+GEN_VEXT_VV(vandn_vv_w, 4)
296
+GEN_VEXT_VV(vandn_vv_d, 8)
297
+
298
+RVVCALL(OPIVX2, vandn_vx_b, OP_UUU_B, H1, H1, DO_ANDN)
299
+RVVCALL(OPIVX2, vandn_vx_h, OP_UUU_H, H2, H2, DO_ANDN)
300
+RVVCALL(OPIVX2, vandn_vx_w, OP_UUU_W, H4, H4, DO_ANDN)
301
+RVVCALL(OPIVX2, vandn_vx_d, OP_UUU_D, H8, H8, DO_ANDN)
302
+GEN_VEXT_VX(vandn_vx_b, 1)
303
+GEN_VEXT_VX(vandn_vx_h, 2)
304
+GEN_VEXT_VX(vandn_vx_w, 4)
305
+GEN_VEXT_VX(vandn_vx_d, 8)
306
+
307
+RVVCALL(OPIVV1, vbrev_v_b, OP_UU_B, H1, H1, revbit8)
308
+RVVCALL(OPIVV1, vbrev_v_h, OP_UU_H, H2, H2, revbit16)
309
+RVVCALL(OPIVV1, vbrev_v_w, OP_UU_W, H4, H4, revbit32)
310
+RVVCALL(OPIVV1, vbrev_v_d, OP_UU_D, H8, H8, revbit64)
311
+GEN_VEXT_V(vbrev_v_b, 1)
312
+GEN_VEXT_V(vbrev_v_h, 2)
313
+GEN_VEXT_V(vbrev_v_w, 4)
314
+GEN_VEXT_V(vbrev_v_d, 8)
315
+
316
+RVVCALL(OPIVV1, vclz_v_b, OP_UU_B, H1, H1, clz8)
317
+RVVCALL(OPIVV1, vclz_v_h, OP_UU_H, H2, H2, clz16)
318
+RVVCALL(OPIVV1, vclz_v_w, OP_UU_W, H4, H4, clz32)
319
+RVVCALL(OPIVV1, vclz_v_d, OP_UU_D, H8, H8, clz64)
320
+GEN_VEXT_V(vclz_v_b, 1)
321
+GEN_VEXT_V(vclz_v_h, 2)
322
+GEN_VEXT_V(vclz_v_w, 4)
323
+GEN_VEXT_V(vclz_v_d, 8)
324
+
325
+RVVCALL(OPIVV1, vctz_v_b, OP_UU_B, H1, H1, ctz8)
326
+RVVCALL(OPIVV1, vctz_v_h, OP_UU_H, H2, H2, ctz16)
327
+RVVCALL(OPIVV1, vctz_v_w, OP_UU_W, H4, H4, ctz32)
328
+RVVCALL(OPIVV1, vctz_v_d, OP_UU_D, H8, H8, ctz64)
329
+GEN_VEXT_V(vctz_v_b, 1)
330
+GEN_VEXT_V(vctz_v_h, 2)
331
+GEN_VEXT_V(vctz_v_w, 4)
332
+GEN_VEXT_V(vctz_v_d, 8)
333
+
334
+RVVCALL(OPIVV1, vcpop_v_b, OP_UU_B, H1, H1, ctpop8)
335
+RVVCALL(OPIVV1, vcpop_v_h, OP_UU_H, H2, H2, ctpop16)
336
+RVVCALL(OPIVV1, vcpop_v_w, OP_UU_W, H4, H4, ctpop32)
337
+RVVCALL(OPIVV1, vcpop_v_d, OP_UU_D, H8, H8, ctpop64)
338
+GEN_VEXT_V(vcpop_v_b, 1)
339
+GEN_VEXT_V(vcpop_v_h, 2)
340
+GEN_VEXT_V(vcpop_v_w, 4)
341
+GEN_VEXT_V(vcpop_v_d, 8)
342
+
343
+#define DO_SLL(N, M) (N << (M & (sizeof(N) * 8 - 1)))
344
+RVVCALL(OPIVV2, vwsll_vv_b, WOP_UUU_B, H2, H1, H1, DO_SLL)
345
+RVVCALL(OPIVV2, vwsll_vv_h, WOP_UUU_H, H4, H2, H2, DO_SLL)
346
+RVVCALL(OPIVV2, vwsll_vv_w, WOP_UUU_W, H8, H4, H4, DO_SLL)
347
+GEN_VEXT_VV(vwsll_vv_b, 2)
348
+GEN_VEXT_VV(vwsll_vv_h, 4)
349
+GEN_VEXT_VV(vwsll_vv_w, 8)
350
+
351
+RVVCALL(OPIVX2, vwsll_vx_b, WOP_UUU_B, H2, H1, DO_SLL)
352
+RVVCALL(OPIVX2, vwsll_vx_h, WOP_UUU_H, H4, H2, DO_SLL)
353
+RVVCALL(OPIVX2, vwsll_vx_w, WOP_UUU_W, H8, H4, DO_SLL)
354
+GEN_VEXT_VX(vwsll_vx_b, 2)
355
+GEN_VEXT_VX(vwsll_vx_h, 4)
356
+GEN_VEXT_VX(vwsll_vx_w, 8)
357
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
132
index XXXXXXX..XXXXXXX 100644
358
index XXXXXXX..XXXXXXX 100644
133
--- a/target/riscv/insn_trans/trans_rvv.c.inc
359
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
134
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
360
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
135
@@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
361
@@ -XXX,XX +XXX,XX @@ static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a)
136
int rm)
362
137
{
363
GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check)
138
if (checkfn(s, a)) {
364
GEN_VX_MASKED_TRANS(vclmulh_vx, vclmul_vx_check)
139
- if (rm != RISCV_FRM_DYN) {
365
+
140
- gen_set_rm(s, RISCV_FRM_DYN);
366
+/*
141
- }
367
+ * Zvbb
142
-
368
+ */
143
uint32_t data = 0;
369
+
144
TCGLabel *over = gen_new_label();
370
+#define GEN_OPIVI_GVEC_TRANS_CHECK(NAME, IMM_MODE, OPIVX, SUF, CHECK) \
145
- gen_set_rm(s, rm);
371
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
146
+ gen_set_rm_chkfrm(s, rm);
372
+ { \
147
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
373
+ if (CHECK(s, a)) { \
148
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
374
+ static gen_helper_opivx *const fns[4] = { \
149
375
+ gen_helper_##OPIVX##_b, \
150
@@ -XXX,XX +XXX,XX @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
376
+ gen_helper_##OPIVX##_h, \
151
static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
377
+ gen_helper_##OPIVX##_w, \
152
{ \
378
+ gen_helper_##OPIVX##_d, \
153
if (CHECK(s, a)) { \
379
+ }; \
154
- if (FRM != RISCV_FRM_DYN) { \
380
+ return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew], \
155
- gen_set_rm(s, RISCV_FRM_DYN); \
381
+ IMM_MODE); \
156
- } \
382
+ } \
157
- \
383
+ return false; \
158
uint32_t data = 0; \
384
+ }
159
static gen_helper_gvec_3_ptr * const fns[2] = { \
385
+
160
gen_helper_##HELPER##_h, \
386
+#define GEN_OPIVV_GVEC_TRANS_CHECK(NAME, SUF, CHECK) \
161
gen_helper_##HELPER##_w, \
387
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
162
}; \
388
+ { \
163
TCGLabel *over = gen_new_label(); \
389
+ if (CHECK(s, a)) { \
164
- gen_set_rm(s, FRM); \
390
+ static gen_helper_gvec_4_ptr *const fns[4] = { \
165
+ gen_set_rm_chkfrm(s, FRM); \
391
+ gen_helper_##NAME##_b, \
166
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
392
+ gen_helper_##NAME##_h, \
167
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
393
+ gen_helper_##NAME##_w, \
168
\
394
+ gen_helper_##NAME##_d, \
169
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
395
+ }; \
170
static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
396
+ return do_opivv_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
171
{ \
397
+ } \
172
if (CHECK(s, a)) { \
398
+ return false; \
173
- if (FRM != RISCV_FRM_DYN) { \
399
+ }
174
- gen_set_rm(s, RISCV_FRM_DYN); \
400
+
175
- } \
401
+#define GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(NAME, SUF, CHECK) \
176
- \
402
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
177
uint32_t data = 0; \
403
+ { \
178
static gen_helper_gvec_3_ptr * const fns[2] = { \
404
+ if (CHECK(s, a)) { \
179
gen_helper_##HELPER##_h, \
405
+ static gen_helper_opivx *const fns[4] = { \
180
gen_helper_##HELPER##_w, \
406
+ gen_helper_##NAME##_b, \
181
}; \
407
+ gen_helper_##NAME##_h, \
182
TCGLabel *over = gen_new_label(); \
408
+ gen_helper_##NAME##_w, \
183
- gen_set_rm(s, FRM); \
409
+ gen_helper_##NAME##_d, \
184
+ gen_set_rm_chkfrm(s, FRM); \
410
+ }; \
185
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
411
+ return do_opivx_gvec_shift(s, a, tcg_gen_gvec_##SUF, \
186
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
412
+ fns[s->sew]); \
187
\
413
+ } \
188
@@ -XXX,XX +XXX,XX @@ static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a)
414
+ return false; \
189
static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
415
+ }
190
{ \
416
+
191
if (opxfv_narrow_check(s, a)) { \
417
+static bool zvbb_vv_check(DisasContext *s, arg_rmrr *a)
192
- if (FRM != RISCV_FRM_DYN) { \
418
+{
193
- gen_set_rm(s, RISCV_FRM_DYN); \
419
+ return opivv_check(s, a) && s->cfg_ptr->ext_zvbb == true;
194
- } \
420
+}
195
- \
421
+
196
uint32_t data = 0; \
422
+static bool zvbb_vx_check(DisasContext *s, arg_rmrr *a)
197
static gen_helper_gvec_3_ptr * const fns[3] = { \
423
+{
198
gen_helper_##HELPER##_b, \
424
+ return opivx_check(s, a) && s->cfg_ptr->ext_zvbb == true;
199
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
425
+}
200
gen_helper_##HELPER##_w, \
426
+
201
}; \
427
+/* vrol.v[vx] */
202
TCGLabel *over = gen_new_label(); \
428
+GEN_OPIVV_GVEC_TRANS_CHECK(vrol_vv, rotlv, zvbb_vv_check)
203
- gen_set_rm(s, FRM); \
429
+GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vrol_vx, rotls, zvbb_vx_check)
204
+ gen_set_rm_chkfrm(s, FRM); \
430
+
205
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
431
+/* vror.v[vxi] */
206
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
432
+GEN_OPIVV_GVEC_TRANS_CHECK(vror_vv, rotrv, zvbb_vv_check)
207
\
433
+GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vror_vx, rotrs, zvbb_vx_check)
434
+GEN_OPIVI_GVEC_TRANS_CHECK(vror_vi, IMM_TRUNC_SEW, vror_vx, rotri, zvbb_vx_check)
435
+
436
+#define GEN_OPIVX_GVEC_TRANS_CHECK(NAME, SUF, CHECK) \
437
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
438
+ { \
439
+ if (CHECK(s, a)) { \
440
+ static gen_helper_opivx *const fns[4] = { \
441
+ gen_helper_##NAME##_b, \
442
+ gen_helper_##NAME##_h, \
443
+ gen_helper_##NAME##_w, \
444
+ gen_helper_##NAME##_d, \
445
+ }; \
446
+ return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
447
+ } \
448
+ return false; \
449
+ }
450
+
451
+/* vandn.v[vx] */
452
+GEN_OPIVV_GVEC_TRANS_CHECK(vandn_vv, andc, zvbb_vv_check)
453
+GEN_OPIVX_GVEC_TRANS_CHECK(vandn_vx, andcs, zvbb_vx_check)
454
+
455
+#define GEN_OPIV_TRANS(NAME, CHECK) \
456
+ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
457
+ { \
458
+ if (CHECK(s, a)) { \
459
+ uint32_t data = 0; \
460
+ static gen_helper_gvec_3_ptr *const fns[4] = { \
461
+ gen_helper_##NAME##_b, \
462
+ gen_helper_##NAME##_h, \
463
+ gen_helper_##NAME##_w, \
464
+ gen_helper_##NAME##_d, \
465
+ }; \
466
+ TCGLabel *over = gen_new_label(); \
467
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
468
+ \
469
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
470
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
471
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
472
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
473
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
474
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
475
+ vreg_ofs(s, a->rs2), cpu_env, \
476
+ s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, \
477
+ data, fns[s->sew]); \
478
+ mark_vs_dirty(s); \
479
+ gen_set_label(over); \
480
+ return true; \
481
+ } \
482
+ return false; \
483
+ }
484
+
485
+static bool zvbb_opiv_check(DisasContext *s, arg_rmr *a)
486
+{
487
+ return s->cfg_ptr->ext_zvbb == true &&
488
+ require_rvv(s) &&
489
+ vext_check_isa_ill(s) &&
490
+ vext_check_ss(s, a->rd, a->rs2, a->vm);
491
+}
492
+
493
+GEN_OPIV_TRANS(vbrev8_v, zvbb_opiv_check)
494
+GEN_OPIV_TRANS(vrev8_v, zvbb_opiv_check)
495
+GEN_OPIV_TRANS(vbrev_v, zvbb_opiv_check)
496
+GEN_OPIV_TRANS(vclz_v, zvbb_opiv_check)
497
+GEN_OPIV_TRANS(vctz_v, zvbb_opiv_check)
498
+GEN_OPIV_TRANS(vcpop_v, zvbb_opiv_check)
499
+
500
+static bool vwsll_vv_check(DisasContext *s, arg_rmrr *a)
501
+{
502
+ return s->cfg_ptr->ext_zvbb && opivv_widen_check(s, a);
503
+}
504
+
505
+static bool vwsll_vx_check(DisasContext *s, arg_rmrr *a)
506
+{
507
+ return s->cfg_ptr->ext_zvbb && opivx_widen_check(s, a);
508
+}
509
+
510
+/* OPIVI without GVEC IR */
511
+#define GEN_OPIVI_WIDEN_TRANS(NAME, IMM_MODE, OPIVX, CHECK) \
512
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
513
+ { \
514
+ if (CHECK(s, a)) { \
515
+ static gen_helper_opivx *const fns[3] = { \
516
+ gen_helper_##OPIVX##_b, \
517
+ gen_helper_##OPIVX##_h, \
518
+ gen_helper_##OPIVX##_w, \
519
+ }; \
520
+ return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s, \
521
+ IMM_MODE); \
522
+ } \
523
+ return false; \
524
+ }
525
+
526
+GEN_OPIVV_WIDEN_TRANS(vwsll_vv, vwsll_vv_check)
527
+GEN_OPIVX_WIDEN_TRANS(vwsll_vx, vwsll_vx_check)
528
+GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
208
--
529
--
209
2.39.0
530
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
riscv_load_firmware(), riscv_load_initrd() and riscv_load_kernel() works
3
This commit adds support for the Zvkned vector-crypto extension, which
4
under the assumption that a 'filename' parameter is always not NULL.
4
consists of the following instructions:
5
5
6
This is currently the case since all callers of these functions are
6
* vaesef.[vv,vs]
7
checking for NULL before calling them. Add an g_assert() to make sure
7
* vaesdf.[vv,vs]
8
that a NULL value in these cases are to be considered a bug.
8
* vaesdm.[vv,vs]
9
* vaesz.vs
10
* vaesem.[vv,vs]
11
* vaeskf1.vi
12
* vaeskf2.vi
9
13
10
Suggested-by: Alex Bennée <alex.bennee@linaro.org>
14
Translation functions are defined in
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
12
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
16
`target/riscv/vcrypto_helper.c`.
13
Reviewed-by: Bin Meng <bmeng@tinylab.org>
17
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
15
Message-Id: <20230102115241.25733-5-dbarboza@ventanamicro.com>
19
Co-authored-by: William Salmon <will.salmon@codethink.co.uk>
20
[max.chou@sifive.com: Replaced vstart checking by TCG op]
21
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
22
Signed-off-by: William Salmon <will.salmon@codethink.co.uk>
23
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
24
Signed-off-by: Max Chou <max.chou@sifive.com>
25
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
26
[max.chou@sifive.com: Imported aes-round.h and exposed x-zvkned
27
property]
28
[max.chou@sifive.com: Fixed endian issues and replaced the vstart & vl
29
egs checking by helper function]
30
[max.chou@sifive.com: Replaced bswap32 calls in aes key expanding]
31
Message-ID: <20230711165917.2629866-10-max.chou@sifive.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
32
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
33
---
18
hw/riscv/boot.c | 6 ++++++
34
target/riscv/cpu_cfg.h | 1 +
19
1 file changed, 6 insertions(+)
35
target/riscv/helper.h | 14 ++
36
target/riscv/insn32.decode | 14 ++
37
target/riscv/cpu.c | 4 +-
38
target/riscv/vcrypto_helper.c | 202 +++++++++++++++++++++++
39
target/riscv/insn_trans/trans_rvvk.c.inc | 147 +++++++++++++++++
40
6 files changed, 381 insertions(+), 1 deletion(-)
20
41
21
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
42
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
22
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/riscv/boot.c
44
--- a/target/riscv/cpu_cfg.h
24
+++ b/hw/riscv/boot.c
45
+++ b/target/riscv/cpu_cfg.h
25
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_firmware(const char *firmware_filename,
46
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
26
uint64_t firmware_entry, firmware_end;
47
bool ext_zve64d;
27
ssize_t firmware_size;
48
bool ext_zvbb;
28
49
bool ext_zvbc;
29
+ g_assert(firmware_filename != NULL);
50
+ bool ext_zvkned;
30
+
51
bool ext_zmmul;
31
if (load_elf_ram_sym(firmware_filename, NULL, NULL, NULL,
52
bool ext_zvfbfmin;
32
&firmware_entry, NULL, &firmware_end, NULL,
53
bool ext_zvfbfwma;
33
0, EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
54
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
34
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(const char *kernel_filename,
55
index XXXXXXX..XXXXXXX 100644
35
{
56
--- a/target/riscv/helper.h
36
uint64_t kernel_load_base, kernel_entry;
57
+++ b/target/riscv/helper.h
37
58
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vandn_vx_b, void, ptr, ptr, tl, ptr, env, i32)
38
+ g_assert(kernel_filename != NULL);
59
DEF_HELPER_6(vandn_vx_h, void, ptr, ptr, tl, ptr, env, i32)
39
+
60
DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, i32)
40
/*
61
DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32)
41
* NB: Use low address not ELF entry point to ensure that the fw_dynamic
62
+
42
* behaviour when loading an ELF matches the fw_payload, fw_jump and BBL
63
+DEF_HELPER_2(egs_check, void, i32, env)
43
@@ -XXX,XX +XXX,XX @@ hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
64
+
44
{
65
+DEF_HELPER_4(vaesef_vv, void, ptr, ptr, env, i32)
45
ssize_t size;
66
+DEF_HELPER_4(vaesef_vs, void, ptr, ptr, env, i32)
46
67
+DEF_HELPER_4(vaesdf_vv, void, ptr, ptr, env, i32)
47
+ g_assert(filename != NULL);
68
+DEF_HELPER_4(vaesdf_vs, void, ptr, ptr, env, i32)
48
+
69
+DEF_HELPER_4(vaesem_vv, void, ptr, ptr, env, i32)
49
/*
70
+DEF_HELPER_4(vaesem_vs, void, ptr, ptr, env, i32)
50
* We want to put the initrd far enough into RAM that when the
71
+DEF_HELPER_4(vaesdm_vv, void, ptr, ptr, env, i32)
51
* kernel is uncompressed it will not clobber the initrd. However
72
+DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
73
+DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
74
+DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
75
+DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
76
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/riscv/insn32.decode
79
+++ b/target/riscv/insn32.decode
80
@@ -XXX,XX +XXX,XX @@
81
@r_rm ....... ..... ..... ... ..... ....... %rs2 %rs1 %rm %rd
82
@r2_rm ....... ..... ..... ... ..... ....... %rs1 %rm %rd
83
@r2 ....... ..... ..... ... ..... ....... &r2 %rs1 %rd
84
+@r2_vm_1 ...... . ..... ..... ... ..... ....... &rmr vm=1 %rs2 %rd
85
@r2_nfvm ... ... vm:1 ..... ..... ... ..... ....... &r2nfvm %nf %rs1 %rd
86
@r2_vm ...... vm:1 ..... ..... ... ..... ....... &rmr %rs2 %rd
87
@r1_vm ...... vm:1 ..... ..... ... ..... ....... %rd
88
@@ -XXX,XX +XXX,XX @@ vcpop_v 010010 . ..... 01110 010 ..... 1010111 @r2_vm
89
vwsll_vv 110101 . ..... ..... 000 ..... 1010111 @r_vm
90
vwsll_vx 110101 . ..... ..... 100 ..... 1010111 @r_vm
91
vwsll_vi 110101 . ..... ..... 011 ..... 1010111 @r_vm
92
+
93
+# *** Zvkned vector crypto extension ***
94
+vaesef_vv 101000 1 ..... 00011 010 ..... 1110111 @r2_vm_1
95
+vaesef_vs 101001 1 ..... 00011 010 ..... 1110111 @r2_vm_1
96
+vaesdf_vv 101000 1 ..... 00001 010 ..... 1110111 @r2_vm_1
97
+vaesdf_vs 101001 1 ..... 00001 010 ..... 1110111 @r2_vm_1
98
+vaesem_vv 101000 1 ..... 00010 010 ..... 1110111 @r2_vm_1
99
+vaesem_vs 101001 1 ..... 00010 010 ..... 1110111 @r2_vm_1
100
+vaesdm_vv 101000 1 ..... 00000 010 ..... 1110111 @r2_vm_1
101
+vaesdm_vs 101001 1 ..... 00000 010 ..... 1110111 @r2_vm_1
102
+vaesz_vs 101001 1 ..... 00111 010 ..... 1110111 @r2_vm_1
103
+vaeskf1_vi 100010 1 ..... ..... 010 ..... 1110111 @r_vm_1
104
+vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1
105
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/riscv/cpu.c
108
+++ b/target/riscv/cpu.c
109
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
110
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
111
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
112
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
113
+ ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
114
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
115
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
116
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
117
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
118
* In principle Zve*x would also suffice here, were they supported
119
* in qemu
120
*/
121
- if (cpu->cfg.ext_zvbb && !cpu->cfg.ext_zve32f) {
122
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) && !cpu->cfg.ext_zve32f) {
123
error_setg(errp,
124
"Vector crypto extensions require V or Zve* extensions");
125
return;
126
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
127
/* Vector cryptography extensions */
128
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
129
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
130
+ DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
131
132
DEFINE_PROP_END_OF_LIST(),
133
};
134
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
135
index XXXXXXX..XXXXXXX 100644
136
--- a/target/riscv/vcrypto_helper.c
137
+++ b/target/riscv/vcrypto_helper.c
138
@@ -XXX,XX +XXX,XX @@
139
#include "qemu/bitops.h"
140
#include "qemu/bswap.h"
141
#include "cpu.h"
142
+#include "crypto/aes.h"
143
+#include "crypto/aes-round.h"
144
#include "exec/memop.h"
145
#include "exec/exec-all.h"
146
#include "exec/helper-proto.h"
147
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vwsll_vx_w, WOP_UUU_W, H8, H4, DO_SLL)
148
GEN_VEXT_VX(vwsll_vx_b, 2)
149
GEN_VEXT_VX(vwsll_vx_h, 4)
150
GEN_VEXT_VX(vwsll_vx_w, 8)
151
+
152
+void HELPER(egs_check)(uint32_t egs, CPURISCVState *env)
153
+{
154
+ uint32_t vl = env->vl;
155
+ uint32_t vstart = env->vstart;
156
+
157
+ if (vl % egs != 0 || vstart % egs != 0) {
158
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
159
+ }
160
+}
161
+
162
+static inline void xor_round_key(AESState *round_state, AESState *round_key)
163
+{
164
+ round_state->v = round_state->v ^ round_key->v;
165
+}
166
+
167
+#define GEN_ZVKNED_HELPER_VV(NAME, ...) \
168
+ void HELPER(NAME)(void *vd, void *vs2, CPURISCVState *env, \
169
+ uint32_t desc) \
170
+ { \
171
+ uint32_t vl = env->vl; \
172
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4); \
173
+ uint32_t vta = vext_vta(desc); \
174
+ \
175
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \
176
+ AESState round_key; \
177
+ round_key.d[0] = *((uint64_t *)vs2 + H8(i * 2 + 0)); \
178
+ round_key.d[1] = *((uint64_t *)vs2 + H8(i * 2 + 1)); \
179
+ AESState round_state; \
180
+ round_state.d[0] = *((uint64_t *)vd + H8(i * 2 + 0)); \
181
+ round_state.d[1] = *((uint64_t *)vd + H8(i * 2 + 1)); \
182
+ __VA_ARGS__; \
183
+ *((uint64_t *)vd + H8(i * 2 + 0)) = round_state.d[0]; \
184
+ *((uint64_t *)vd + H8(i * 2 + 1)) = round_state.d[1]; \
185
+ } \
186
+ env->vstart = 0; \
187
+ /* set tail elements to 1s */ \
188
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4); \
189
+ }
190
+
191
+#define GEN_ZVKNED_HELPER_VS(NAME, ...) \
192
+ void HELPER(NAME)(void *vd, void *vs2, CPURISCVState *env, \
193
+ uint32_t desc) \
194
+ { \
195
+ uint32_t vl = env->vl; \
196
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4); \
197
+ uint32_t vta = vext_vta(desc); \
198
+ \
199
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \
200
+ AESState round_key; \
201
+ round_key.d[0] = *((uint64_t *)vs2 + H8(0)); \
202
+ round_key.d[1] = *((uint64_t *)vs2 + H8(1)); \
203
+ AESState round_state; \
204
+ round_state.d[0] = *((uint64_t *)vd + H8(i * 2 + 0)); \
205
+ round_state.d[1] = *((uint64_t *)vd + H8(i * 2 + 1)); \
206
+ __VA_ARGS__; \
207
+ *((uint64_t *)vd + H8(i * 2 + 0)) = round_state.d[0]; \
208
+ *((uint64_t *)vd + H8(i * 2 + 1)) = round_state.d[1]; \
209
+ } \
210
+ env->vstart = 0; \
211
+ /* set tail elements to 1s */ \
212
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4); \
213
+ }
214
+
215
+GEN_ZVKNED_HELPER_VV(vaesef_vv, aesenc_SB_SR_AK(&round_state,
216
+ &round_state,
217
+ &round_key,
218
+ false);)
219
+GEN_ZVKNED_HELPER_VS(vaesef_vs, aesenc_SB_SR_AK(&round_state,
220
+ &round_state,
221
+ &round_key,
222
+ false);)
223
+GEN_ZVKNED_HELPER_VV(vaesdf_vv, aesdec_ISB_ISR_AK(&round_state,
224
+ &round_state,
225
+ &round_key,
226
+ false);)
227
+GEN_ZVKNED_HELPER_VS(vaesdf_vs, aesdec_ISB_ISR_AK(&round_state,
228
+ &round_state,
229
+ &round_key,
230
+ false);)
231
+GEN_ZVKNED_HELPER_VV(vaesem_vv, aesenc_SB_SR_MC_AK(&round_state,
232
+ &round_state,
233
+ &round_key,
234
+ false);)
235
+GEN_ZVKNED_HELPER_VS(vaesem_vs, aesenc_SB_SR_MC_AK(&round_state,
236
+ &round_state,
237
+ &round_key,
238
+ false);)
239
+GEN_ZVKNED_HELPER_VV(vaesdm_vv, aesdec_ISB_ISR_AK_IMC(&round_state,
240
+ &round_state,
241
+ &round_key,
242
+ false);)
243
+GEN_ZVKNED_HELPER_VS(vaesdm_vs, aesdec_ISB_ISR_AK_IMC(&round_state,
244
+ &round_state,
245
+ &round_key,
246
+ false);)
247
+GEN_ZVKNED_HELPER_VS(vaesz_vs, xor_round_key(&round_state, &round_key);)
248
+
249
+void HELPER(vaeskf1_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
250
+ CPURISCVState *env, uint32_t desc)
251
+{
252
+ uint32_t *vd = vd_vptr;
253
+ uint32_t *vs2 = vs2_vptr;
254
+ uint32_t vl = env->vl;
255
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
256
+ uint32_t vta = vext_vta(desc);
257
+
258
+ uimm &= 0b1111;
259
+ if (uimm > 10 || uimm == 0) {
260
+ uimm ^= 0b1000;
261
+ }
262
+
263
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
264
+ uint32_t rk[8], tmp;
265
+ static const uint32_t rcon[] = {
266
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
267
+ 0x00000020, 0x00000040, 0x00000080, 0x0000001B, 0x00000036,
268
+ };
269
+
270
+ rk[0] = vs2[i * 4 + H4(0)];
271
+ rk[1] = vs2[i * 4 + H4(1)];
272
+ rk[2] = vs2[i * 4 + H4(2)];
273
+ rk[3] = vs2[i * 4 + H4(3)];
274
+ tmp = ror32(rk[3], 8);
275
+
276
+ rk[4] = rk[0] ^ (((uint32_t)AES_sbox[(tmp >> 24) & 0xff] << 24) |
277
+ ((uint32_t)AES_sbox[(tmp >> 16) & 0xff] << 16) |
278
+ ((uint32_t)AES_sbox[(tmp >> 8) & 0xff] << 8) |
279
+ ((uint32_t)AES_sbox[(tmp >> 0) & 0xff] << 0))
280
+ ^ rcon[uimm - 1];
281
+ rk[5] = rk[1] ^ rk[4];
282
+ rk[6] = rk[2] ^ rk[5];
283
+ rk[7] = rk[3] ^ rk[6];
284
+
285
+ vd[i * 4 + H4(0)] = rk[4];
286
+ vd[i * 4 + H4(1)] = rk[5];
287
+ vd[i * 4 + H4(2)] = rk[6];
288
+ vd[i * 4 + H4(3)] = rk[7];
289
+ }
290
+ env->vstart = 0;
291
+ /* set tail elements to 1s */
292
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
293
+}
294
+
295
+void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
296
+ CPURISCVState *env, uint32_t desc)
297
+{
298
+ uint32_t *vd = vd_vptr;
299
+ uint32_t *vs2 = vs2_vptr;
300
+ uint32_t vl = env->vl;
301
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
302
+ uint32_t vta = vext_vta(desc);
303
+
304
+ uimm &= 0b1111;
305
+ if (uimm > 14 || uimm < 2) {
306
+ uimm ^= 0b1000;
307
+ }
308
+
309
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
310
+ uint32_t rk[12], tmp;
311
+ static const uint32_t rcon[] = {
312
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
313
+ 0x00000020, 0x00000040, 0x00000080, 0x0000001B, 0x00000036,
314
+ };
315
+
316
+ rk[0] = vd[i * 4 + H4(0)];
317
+ rk[1] = vd[i * 4 + H4(1)];
318
+ rk[2] = vd[i * 4 + H4(2)];
319
+ rk[3] = vd[i * 4 + H4(3)];
320
+ rk[4] = vs2[i * 4 + H4(0)];
321
+ rk[5] = vs2[i * 4 + H4(1)];
322
+ rk[6] = vs2[i * 4 + H4(2)];
323
+ rk[7] = vs2[i * 4 + H4(3)];
324
+
325
+ if (uimm % 2 == 0) {
326
+ tmp = ror32(rk[7], 8);
327
+ rk[8] = rk[0] ^ (((uint32_t)AES_sbox[(tmp >> 24) & 0xff] << 24) |
328
+ ((uint32_t)AES_sbox[(tmp >> 16) & 0xff] << 16) |
329
+ ((uint32_t)AES_sbox[(tmp >> 8) & 0xff] << 8) |
330
+ ((uint32_t)AES_sbox[(tmp >> 0) & 0xff] << 0))
331
+ ^ rcon[(uimm - 1) / 2];
332
+ } else {
333
+ rk[8] = rk[0] ^ (((uint32_t)AES_sbox[(rk[7] >> 24) & 0xff] << 24) |
334
+ ((uint32_t)AES_sbox[(rk[7] >> 16) & 0xff] << 16) |
335
+ ((uint32_t)AES_sbox[(rk[7] >> 8) & 0xff] << 8) |
336
+ ((uint32_t)AES_sbox[(rk[7] >> 0) & 0xff] << 0));
337
+ }
338
+ rk[9] = rk[1] ^ rk[8];
339
+ rk[10] = rk[2] ^ rk[9];
340
+ rk[11] = rk[3] ^ rk[10];
341
+
342
+ vd[i * 4 + H4(0)] = rk[8];
343
+ vd[i * 4 + H4(1)] = rk[9];
344
+ vd[i * 4 + H4(2)] = rk[10];
345
+ vd[i * 4 + H4(3)] = rk[11];
346
+ }
347
+ env->vstart = 0;
348
+ /* set tail elements to 1s */
349
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
350
+}
351
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
352
index XXXXXXX..XXXXXXX 100644
353
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
354
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
355
@@ -XXX,XX +XXX,XX @@ static bool vwsll_vx_check(DisasContext *s, arg_rmrr *a)
356
GEN_OPIVV_WIDEN_TRANS(vwsll_vv, vwsll_vv_check)
357
GEN_OPIVX_WIDEN_TRANS(vwsll_vx, vwsll_vx_check)
358
GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
359
+
360
+/*
361
+ * Zvkned
362
+ */
363
+
364
+#define ZVKNED_EGS 4
365
+
366
+#define GEN_V_UNMASKED_TRANS(NAME, CHECK, EGS) \
367
+ static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
368
+ { \
369
+ if (CHECK(s, a)) { \
370
+ TCGv_ptr rd_v, rs2_v; \
371
+ TCGv_i32 desc, egs; \
372
+ uint32_t data = 0; \
373
+ TCGLabel *over = gen_new_label(); \
374
+ \
375
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
376
+ /* save opcode for unwinding in case we throw an exception */ \
377
+ decode_save_opc(s); \
378
+ egs = tcg_constant_i32(EGS); \
379
+ gen_helper_egs_check(egs, cpu_env); \
380
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
381
+ } \
382
+ \
383
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
384
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
385
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
386
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
387
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
388
+ rd_v = tcg_temp_new_ptr(); \
389
+ rs2_v = tcg_temp_new_ptr(); \
390
+ desc = tcg_constant_i32( \
391
+ simd_desc(s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, data)); \
392
+ tcg_gen_addi_ptr(rd_v, cpu_env, vreg_ofs(s, a->rd)); \
393
+ tcg_gen_addi_ptr(rs2_v, cpu_env, vreg_ofs(s, a->rs2)); \
394
+ gen_helper_##NAME(rd_v, rs2_v, cpu_env, desc); \
395
+ mark_vs_dirty(s); \
396
+ gen_set_label(over); \
397
+ return true; \
398
+ } \
399
+ return false; \
400
+ }
401
+
402
+static bool vaes_check_vv(DisasContext *s, arg_rmr *a)
403
+{
404
+ int egw_bytes = ZVKNED_EGS << s->sew;
405
+ return s->cfg_ptr->ext_zvkned == true &&
406
+ require_rvv(s) &&
407
+ vext_check_isa_ill(s) &&
408
+ MAXSZ(s) >= egw_bytes &&
409
+ require_align(a->rd, s->lmul) &&
410
+ require_align(a->rs2, s->lmul) &&
411
+ s->sew == MO_32;
412
+}
413
+
414
+static bool vaes_check_overlap(DisasContext *s, int vd, int vs2)
415
+{
416
+ int8_t op_size = s->lmul <= 0 ? 1 : 1 << s->lmul;
417
+ return !is_overlapped(vd, op_size, vs2, 1);
418
+}
419
+
420
+static bool vaes_check_vs(DisasContext *s, arg_rmr *a)
421
+{
422
+ int egw_bytes = ZVKNED_EGS << s->sew;
423
+ return vaes_check_overlap(s, a->rd, a->rs2) &&
424
+ MAXSZ(s) >= egw_bytes &&
425
+ s->cfg_ptr->ext_zvkned == true &&
426
+ require_rvv(s) &&
427
+ vext_check_isa_ill(s) &&
428
+ require_align(a->rd, s->lmul) &&
429
+ s->sew == MO_32;
430
+}
431
+
432
+GEN_V_UNMASKED_TRANS(vaesef_vv, vaes_check_vv, ZVKNED_EGS)
433
+GEN_V_UNMASKED_TRANS(vaesef_vs, vaes_check_vs, ZVKNED_EGS)
434
+GEN_V_UNMASKED_TRANS(vaesdf_vv, vaes_check_vv, ZVKNED_EGS)
435
+GEN_V_UNMASKED_TRANS(vaesdf_vs, vaes_check_vs, ZVKNED_EGS)
436
+GEN_V_UNMASKED_TRANS(vaesdm_vv, vaes_check_vv, ZVKNED_EGS)
437
+GEN_V_UNMASKED_TRANS(vaesdm_vs, vaes_check_vs, ZVKNED_EGS)
438
+GEN_V_UNMASKED_TRANS(vaesz_vs, vaes_check_vs, ZVKNED_EGS)
439
+GEN_V_UNMASKED_TRANS(vaesem_vv, vaes_check_vv, ZVKNED_EGS)
440
+GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS)
441
+
442
+#define GEN_VI_UNMASKED_TRANS(NAME, CHECK, EGS) \
443
+ static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
444
+ { \
445
+ if (CHECK(s, a)) { \
446
+ TCGv_ptr rd_v, rs2_v; \
447
+ TCGv_i32 uimm_v, desc, egs; \
448
+ uint32_t data = 0; \
449
+ TCGLabel *over = gen_new_label(); \
450
+ \
451
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
452
+ /* save opcode for unwinding in case we throw an exception */ \
453
+ decode_save_opc(s); \
454
+ egs = tcg_constant_i32(EGS); \
455
+ gen_helper_egs_check(egs, cpu_env); \
456
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
457
+ } \
458
+ \
459
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
460
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
461
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
462
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
463
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
464
+ \
465
+ rd_v = tcg_temp_new_ptr(); \
466
+ rs2_v = tcg_temp_new_ptr(); \
467
+ uimm_v = tcg_constant_i32(a->rs1); \
468
+ desc = tcg_constant_i32( \
469
+ simd_desc(s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, data)); \
470
+ tcg_gen_addi_ptr(rd_v, cpu_env, vreg_ofs(s, a->rd)); \
471
+ tcg_gen_addi_ptr(rs2_v, cpu_env, vreg_ofs(s, a->rs2)); \
472
+ gen_helper_##NAME(rd_v, rs2_v, uimm_v, cpu_env, desc); \
473
+ mark_vs_dirty(s); \
474
+ gen_set_label(over); \
475
+ return true; \
476
+ } \
477
+ return false; \
478
+ }
479
+
480
+static bool vaeskf1_check(DisasContext *s, arg_vaeskf1_vi *a)
481
+{
482
+ int egw_bytes = ZVKNED_EGS << s->sew;
483
+ return s->cfg_ptr->ext_zvkned == true &&
484
+ require_rvv(s) &&
485
+ vext_check_isa_ill(s) &&
486
+ MAXSZ(s) >= egw_bytes &&
487
+ s->sew == MO_32 &&
488
+ require_align(a->rd, s->lmul) &&
489
+ require_align(a->rs2, s->lmul);
490
+}
491
+
492
+static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi *a)
493
+{
494
+ int egw_bytes = ZVKNED_EGS << s->sew;
495
+ return s->cfg_ptr->ext_zvkned == true &&
496
+ require_rvv(s) &&
497
+ vext_check_isa_ill(s) &&
498
+ MAXSZ(s) >= egw_bytes &&
499
+ s->sew == MO_32 &&
500
+ require_align(a->rd, s->lmul) &&
501
+ require_align(a->rs2, s->lmul);
502
+}
503
+
504
+GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, ZVKNED_EGS)
505
+GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
52
--
506
--
53
2.39.0
507
2.41.0
diff view generated by jsdifflib
New patch
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
1
2
3
This commit adds support for the Zvknh vector-crypto extension, which
4
consists of the following instructions:
5
6
* vsha2ms.vv
7
* vsha2c[hl].vv
8
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
14
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
15
[max.chou@sifive.com: Replaced vstart checking by TCG op]
16
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
17
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
18
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
19
Signed-off-by: Max Chou <max.chou@sifive.com>
20
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
21
[max.chou@sifive.com: Exposed x-zvknha & x-zvknhb properties]
22
[max.chou@sifive.com: Replaced SEW selection to happened during
23
translation]
24
Message-ID: <20230711165917.2629866-11-max.chou@sifive.com>
25
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
26
---
27
target/riscv/cpu_cfg.h | 2 +
28
target/riscv/helper.h | 6 +
29
target/riscv/insn32.decode | 5 +
30
target/riscv/cpu.c | 13 +-
31
target/riscv/vcrypto_helper.c | 238 +++++++++++++++++++++++
32
target/riscv/insn_trans/trans_rvvk.c.inc | 129 ++++++++++++
33
6 files changed, 390 insertions(+), 3 deletions(-)
34
35
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/cpu_cfg.h
38
+++ b/target/riscv/cpu_cfg.h
39
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
40
bool ext_zvbb;
41
bool ext_zvbc;
42
bool ext_zvkned;
43
+ bool ext_zvknha;
44
+ bool ext_zvknhb;
45
bool ext_zmmul;
46
bool ext_zvfbfmin;
47
bool ext_zvfbfwma;
48
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/helper.h
51
+++ b/target/riscv/helper.h
52
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
53
DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
54
DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
55
DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
56
+
57
+DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32)
58
+DEF_HELPER_5(vsha2ch32_vv, void, ptr, ptr, ptr, env, i32)
59
+DEF_HELPER_5(vsha2ch64_vv, void, ptr, ptr, ptr, env, i32)
60
+DEF_HELPER_5(vsha2cl32_vv, void, ptr, ptr, ptr, env, i32)
61
+DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
62
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
63
index XXXXXXX..XXXXXXX 100644
64
--- a/target/riscv/insn32.decode
65
+++ b/target/riscv/insn32.decode
66
@@ -XXX,XX +XXX,XX @@ vaesdm_vs 101001 1 ..... 00000 010 ..... 1110111 @r2_vm_1
67
vaesz_vs 101001 1 ..... 00111 010 ..... 1110111 @r2_vm_1
68
vaeskf1_vi 100010 1 ..... ..... 010 ..... 1110111 @r_vm_1
69
vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1
70
+
71
+# *** Zvknh vector crypto extension ***
72
+vsha2ms_vv 101101 1 ..... ..... 010 ..... 1110111 @r_vm_1
73
+vsha2ch_vv 101110 1 ..... ..... 010 ..... 1110111 @r_vm_1
74
+vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
75
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/riscv/cpu.c
78
+++ b/target/riscv/cpu.c
79
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
80
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
81
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
82
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
83
+ ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
84
+ ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
85
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
86
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
87
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
88
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
89
* In principle Zve*x would also suffice here, were they supported
90
* in qemu
91
*/
92
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) && !cpu->cfg.ext_zve32f) {
93
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
94
+ !cpu->cfg.ext_zve32f) {
95
error_setg(errp,
96
"Vector crypto extensions require V or Zve* extensions");
97
return;
98
}
99
100
- if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
101
- error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
102
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
103
+ error_setg(
104
+ errp,
105
+ "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
106
return;
107
}
108
109
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
110
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
111
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
112
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
113
+ DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
114
+ DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
115
116
DEFINE_PROP_END_OF_LIST(),
117
};
118
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
119
index XXXXXXX..XXXXXXX 100644
120
--- a/target/riscv/vcrypto_helper.c
121
+++ b/target/riscv/vcrypto_helper.c
122
@@ -XXX,XX +XXX,XX @@ void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
123
/* set tail elements to 1s */
124
vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
125
}
126
+
127
+static inline uint32_t sig0_sha256(uint32_t x)
128
+{
129
+ return ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3);
130
+}
131
+
132
+static inline uint32_t sig1_sha256(uint32_t x)
133
+{
134
+ return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
135
+}
136
+
137
+static inline uint64_t sig0_sha512(uint64_t x)
138
+{
139
+ return ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7);
140
+}
141
+
142
+static inline uint64_t sig1_sha512(uint64_t x)
143
+{
144
+ return ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6);
145
+}
146
+
147
+static inline void vsha2ms_e32(uint32_t *vd, uint32_t *vs1, uint32_t *vs2)
148
+{
149
+ uint32_t res[4];
150
+ res[0] = sig1_sha256(vs1[H4(2)]) + vs2[H4(1)] + sig0_sha256(vd[H4(1)]) +
151
+ vd[H4(0)];
152
+ res[1] = sig1_sha256(vs1[H4(3)]) + vs2[H4(2)] + sig0_sha256(vd[H4(2)]) +
153
+ vd[H4(1)];
154
+ res[2] =
155
+ sig1_sha256(res[0]) + vs2[H4(3)] + sig0_sha256(vd[H4(3)]) + vd[H4(2)];
156
+ res[3] =
157
+ sig1_sha256(res[1]) + vs1[H4(0)] + sig0_sha256(vs2[H4(0)]) + vd[H4(3)];
158
+ vd[H4(3)] = res[3];
159
+ vd[H4(2)] = res[2];
160
+ vd[H4(1)] = res[1];
161
+ vd[H4(0)] = res[0];
162
+}
163
+
164
+static inline void vsha2ms_e64(uint64_t *vd, uint64_t *vs1, uint64_t *vs2)
165
+{
166
+ uint64_t res[4];
167
+ res[0] = sig1_sha512(vs1[2]) + vs2[1] + sig0_sha512(vd[1]) + vd[0];
168
+ res[1] = sig1_sha512(vs1[3]) + vs2[2] + sig0_sha512(vd[2]) + vd[1];
169
+ res[2] = sig1_sha512(res[0]) + vs2[3] + sig0_sha512(vd[3]) + vd[2];
170
+ res[3] = sig1_sha512(res[1]) + vs1[0] + sig0_sha512(vs2[0]) + vd[3];
171
+ vd[3] = res[3];
172
+ vd[2] = res[2];
173
+ vd[1] = res[1];
174
+ vd[0] = res[0];
175
+}
176
+
177
+void HELPER(vsha2ms_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
178
+ uint32_t desc)
179
+{
180
+ uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
181
+ uint32_t esz = sew == MO_32 ? 4 : 8;
182
+ uint32_t total_elems;
183
+ uint32_t vta = vext_vta(desc);
184
+
185
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
186
+ if (sew == MO_32) {
187
+ vsha2ms_e32(((uint32_t *)vd) + i * 4, ((uint32_t *)vs1) + i * 4,
188
+ ((uint32_t *)vs2) + i * 4);
189
+ } else {
190
+ /* If not 32 then SEW should be 64 */
191
+ vsha2ms_e64(((uint64_t *)vd) + i * 4, ((uint64_t *)vs1) + i * 4,
192
+ ((uint64_t *)vs2) + i * 4);
193
+ }
194
+ }
195
+ /* set tail elements to 1s */
196
+ total_elems = vext_get_total_elems(env, desc, esz);
197
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
198
+ env->vstart = 0;
199
+}
200
+
201
+static inline uint64_t sum0_64(uint64_t x)
202
+{
203
+ return ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39);
204
+}
205
+
206
+static inline uint32_t sum0_32(uint32_t x)
207
+{
208
+ return ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22);
209
+}
210
+
211
+static inline uint64_t sum1_64(uint64_t x)
212
+{
213
+ return ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41);
214
+}
215
+
216
+static inline uint32_t sum1_32(uint32_t x)
217
+{
218
+ return ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25);
219
+}
220
+
221
+#define ch(x, y, z) ((x & y) ^ ((~x) & z))
222
+
223
+#define maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
224
+
225
+static void vsha2c_64(uint64_t *vs2, uint64_t *vd, uint64_t *vs1)
226
+{
227
+ uint64_t a = vs2[3], b = vs2[2], e = vs2[1], f = vs2[0];
228
+ uint64_t c = vd[3], d = vd[2], g = vd[1], h = vd[0];
229
+ uint64_t W0 = vs1[0], W1 = vs1[1];
230
+ uint64_t T1 = h + sum1_64(e) + ch(e, f, g) + W0;
231
+ uint64_t T2 = sum0_64(a) + maj(a, b, c);
232
+
233
+ h = g;
234
+ g = f;
235
+ f = e;
236
+ e = d + T1;
237
+ d = c;
238
+ c = b;
239
+ b = a;
240
+ a = T1 + T2;
241
+
242
+ T1 = h + sum1_64(e) + ch(e, f, g) + W1;
243
+ T2 = sum0_64(a) + maj(a, b, c);
244
+ h = g;
245
+ g = f;
246
+ f = e;
247
+ e = d + T1;
248
+ d = c;
249
+ c = b;
250
+ b = a;
251
+ a = T1 + T2;
252
+
253
+ vd[0] = f;
254
+ vd[1] = e;
255
+ vd[2] = b;
256
+ vd[3] = a;
257
+}
258
+
259
+static void vsha2c_32(uint32_t *vs2, uint32_t *vd, uint32_t *vs1)
260
+{
261
+ uint32_t a = vs2[H4(3)], b = vs2[H4(2)], e = vs2[H4(1)], f = vs2[H4(0)];
262
+ uint32_t c = vd[H4(3)], d = vd[H4(2)], g = vd[H4(1)], h = vd[H4(0)];
263
+ uint32_t W0 = vs1[H4(0)], W1 = vs1[H4(1)];
264
+ uint32_t T1 = h + sum1_32(e) + ch(e, f, g) + W0;
265
+ uint32_t T2 = sum0_32(a) + maj(a, b, c);
266
+
267
+ h = g;
268
+ g = f;
269
+ f = e;
270
+ e = d + T1;
271
+ d = c;
272
+ c = b;
273
+ b = a;
274
+ a = T1 + T2;
275
+
276
+ T1 = h + sum1_32(e) + ch(e, f, g) + W1;
277
+ T2 = sum0_32(a) + maj(a, b, c);
278
+ h = g;
279
+ g = f;
280
+ f = e;
281
+ e = d + T1;
282
+ d = c;
283
+ c = b;
284
+ b = a;
285
+ a = T1 + T2;
286
+
287
+ vd[H4(0)] = f;
288
+ vd[H4(1)] = e;
289
+ vd[H4(2)] = b;
290
+ vd[H4(3)] = a;
291
+}
292
+
293
+void HELPER(vsha2ch32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
294
+ uint32_t desc)
295
+{
296
+ const uint32_t esz = 4;
297
+ uint32_t total_elems;
298
+ uint32_t vta = vext_vta(desc);
299
+
300
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
301
+ vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i,
302
+ ((uint32_t *)vs1) + 4 * i + 2);
303
+ }
304
+
305
+ /* set tail elements to 1s */
306
+ total_elems = vext_get_total_elems(env, desc, esz);
307
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
308
+ env->vstart = 0;
309
+}
310
+
311
+void HELPER(vsha2ch64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
312
+ uint32_t desc)
313
+{
314
+ const uint32_t esz = 8;
315
+ uint32_t total_elems;
316
+ uint32_t vta = vext_vta(desc);
317
+
318
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
319
+ vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i,
320
+ ((uint64_t *)vs1) + 4 * i + 2);
321
+ }
322
+
323
+ /* set tail elements to 1s */
324
+ total_elems = vext_get_total_elems(env, desc, esz);
325
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
326
+ env->vstart = 0;
327
+}
328
+
329
+void HELPER(vsha2cl32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
330
+ uint32_t desc)
331
+{
332
+ const uint32_t esz = 4;
333
+ uint32_t total_elems;
334
+ uint32_t vta = vext_vta(desc);
335
+
336
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
337
+ vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i,
338
+ (((uint32_t *)vs1) + 4 * i));
339
+ }
340
+
341
+ /* set tail elements to 1s */
342
+ total_elems = vext_get_total_elems(env, desc, esz);
343
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
344
+ env->vstart = 0;
345
+}
346
+
347
+void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
348
+ uint32_t desc)
349
+{
350
+ uint32_t esz = 8;
351
+ uint32_t total_elems;
352
+ uint32_t vta = vext_vta(desc);
353
+
354
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
355
+ vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i,
356
+ (((uint64_t *)vs1) + 4 * i));
357
+ }
358
+
359
+ /* set tail elements to 1s */
360
+ total_elems = vext_get_total_elems(env, desc, esz);
361
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
362
+ env->vstart = 0;
363
+}
364
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
365
index XXXXXXX..XXXXXXX 100644
366
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
367
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
368
@@ -XXX,XX +XXX,XX @@ static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi *a)
369
370
GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, ZVKNED_EGS)
371
GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
372
+
373
+/*
374
+ * Zvknh
375
+ */
376
+
377
+#define ZVKNH_EGS 4
378
+
379
+#define GEN_VV_UNMASKED_TRANS(NAME, CHECK, EGS) \
380
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
381
+ { \
382
+ if (CHECK(s, a)) { \
383
+ uint32_t data = 0; \
384
+ TCGLabel *over = gen_new_label(); \
385
+ TCGv_i32 egs; \
386
+ \
387
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
388
+ /* save opcode for unwinding in case we throw an exception */ \
389
+ decode_save_opc(s); \
390
+ egs = tcg_constant_i32(EGS); \
391
+ gen_helper_egs_check(egs, cpu_env); \
392
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
393
+ } \
394
+ \
395
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
396
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
397
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
398
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
399
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
400
+ \
401
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1), \
402
+ vreg_ofs(s, a->rs2), cpu_env, \
403
+ s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, \
404
+ data, gen_helper_##NAME); \
405
+ \
406
+ mark_vs_dirty(s); \
407
+ gen_set_label(over); \
408
+ return true; \
409
+ } \
410
+ return false; \
411
+ }
412
+
413
+static bool vsha_check_sew(DisasContext *s)
414
+{
415
+ return (s->cfg_ptr->ext_zvknha == true && s->sew == MO_32) ||
416
+ (s->cfg_ptr->ext_zvknhb == true &&
417
+ (s->sew == MO_32 || s->sew == MO_64));
418
+}
419
+
420
+static bool vsha_check(DisasContext *s, arg_rmrr *a)
421
+{
422
+ int egw_bytes = ZVKNH_EGS << s->sew;
423
+ int mult = 1 << MAX(s->lmul, 0);
424
+ return opivv_check(s, a) &&
425
+ vsha_check_sew(s) &&
426
+ MAXSZ(s) >= egw_bytes &&
427
+ !is_overlapped(a->rd, mult, a->rs1, mult) &&
428
+ !is_overlapped(a->rd, mult, a->rs2, mult) &&
429
+ s->lmul >= 0;
430
+}
431
+
432
+GEN_VV_UNMASKED_TRANS(vsha2ms_vv, vsha_check, ZVKNH_EGS)
433
+
434
+static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
435
+{
436
+ if (vsha_check(s, a)) {
437
+ uint32_t data = 0;
438
+ TCGLabel *over = gen_new_label();
439
+ TCGv_i32 egs;
440
+
441
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
442
+ /* save opcode for unwinding in case we throw an exception */
443
+ decode_save_opc(s);
444
+ egs = tcg_constant_i32(ZVKNH_EGS);
445
+ gen_helper_egs_check(egs, cpu_env);
446
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
447
+ }
448
+
449
+ data = FIELD_DP32(data, VDATA, VM, a->vm);
450
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
451
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
452
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
453
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
454
+
455
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
456
+ vreg_ofs(s, a->rs2), cpu_env, s->cfg_ptr->vlen / 8,
457
+ s->cfg_ptr->vlen / 8, data,
458
+ s->sew == MO_32 ?
459
+ gen_helper_vsha2cl32_vv : gen_helper_vsha2cl64_vv);
460
+
461
+ mark_vs_dirty(s);
462
+ gen_set_label(over);
463
+ return true;
464
+ }
465
+ return false;
466
+}
467
+
468
+static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
469
+{
470
+ if (vsha_check(s, a)) {
471
+ uint32_t data = 0;
472
+ TCGLabel *over = gen_new_label();
473
+ TCGv_i32 egs;
474
+
475
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
476
+ /* save opcode for unwinding in case we throw an exception */
477
+ decode_save_opc(s);
478
+ egs = tcg_constant_i32(ZVKNH_EGS);
479
+ gen_helper_egs_check(egs, cpu_env);
480
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
481
+ }
482
+
483
+ data = FIELD_DP32(data, VDATA, VM, a->vm);
484
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
485
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
486
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
487
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
488
+
489
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
490
+ vreg_ofs(s, a->rs2), cpu_env, s->cfg_ptr->vlen / 8,
491
+ s->cfg_ptr->vlen / 8, data,
492
+ s->sew == MO_32 ?
493
+ gen_helper_vsha2ch32_vv : gen_helper_vsha2ch64_vv);
494
+
495
+ mark_vs_dirty(s);
496
+ gen_set_label(over);
497
+ return true;
498
+ }
499
+ return false;
500
+}
501
--
502
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
2
2
3
env->mhartid is currently casted to long before printed, which drops
3
This commit adds support for the Zvksh vector-crypto extension, which
4
the high 32-bit for rv64 on 32-bit host. Use TARGET_FMT_lx instead.
4
consists of the following instructions:
5
5
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
6
* vsm3me.vv
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
* vsm3c.vi
8
Message-Id: <20230109152655.340114-1-bmeng@tinylab.org>
8
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Co-authored-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
14
[max.chou@sifive.com: Replaced vstart checking by TCG op]
15
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
16
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
17
Signed-off-by: Max Chou <max.chou@sifive.com>
18
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
19
[max.chou@sifive.com: Exposed x-zvksh property]
20
Message-ID: <20230711165917.2629866-12-max.chou@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
22
---
11
target/riscv/cpu.c | 6 +++---
23
target/riscv/cpu_cfg.h | 1 +
12
1 file changed, 3 insertions(+), 3 deletions(-)
24
target/riscv/helper.h | 3 +
13
25
target/riscv/insn32.decode | 4 +
26
target/riscv/cpu.c | 6 +-
27
target/riscv/vcrypto_helper.c | 134 +++++++++++++++++++++++
28
target/riscv/insn_trans/trans_rvvk.c.inc | 31 ++++++
29
6 files changed, 177 insertions(+), 2 deletions(-)
30
31
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/cpu_cfg.h
34
+++ b/target/riscv/cpu_cfg.h
35
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
36
bool ext_zvkned;
37
bool ext_zvknha;
38
bool ext_zvknhb;
39
+ bool ext_zvksh;
40
bool ext_zmmul;
41
bool ext_zvfbfmin;
42
bool ext_zvfbfwma;
43
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/helper.h
46
+++ b/target/riscv/helper.h
47
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsha2ch32_vv, void, ptr, ptr, ptr, env, i32)
48
DEF_HELPER_5(vsha2ch64_vv, void, ptr, ptr, ptr, env, i32)
49
DEF_HELPER_5(vsha2cl32_vv, void, ptr, ptr, ptr, env, i32)
50
DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
51
+
52
+DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
53
+DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
54
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/riscv/insn32.decode
57
+++ b/target/riscv/insn32.decode
58
@@ -XXX,XX +XXX,XX @@ vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1
59
vsha2ms_vv 101101 1 ..... ..... 010 ..... 1110111 @r_vm_1
60
vsha2ch_vv 101110 1 ..... ..... 010 ..... 1110111 @r_vm_1
61
vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
62
+
63
+# *** Zvksh vector crypto extension ***
64
+vsm3me_vv 100000 1 ..... ..... 010 ..... 1110111 @r_vm_1
65
+vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
14
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
66
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu.c
68
--- a/target/riscv/cpu.c
17
+++ b/target/riscv/cpu.c
69
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
70
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
19
(env->priv_ver < isa_edata_arr[i].min_version)) {
71
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
20
isa_ext_update_enabled(cpu, &isa_edata_arr[i], false);
72
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
21
#ifndef CONFIG_USER_ONLY
73
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
22
- warn_report("disabling %s extension for hart 0x%lx because "
74
+ ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh),
23
- "privilege spec version does not match",
75
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
24
- isa_edata_arr[i].name, (unsigned long)env->mhartid);
76
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
25
+ warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx
77
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
26
+ " because privilege spec version does not match",
78
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
27
+ isa_edata_arr[i].name, env->mhartid);
79
* In principle Zve*x would also suffice here, were they supported
28
#else
80
* in qemu
29
warn_report("disabling %s extension because "
81
*/
30
"privilege spec version does not match",
82
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
83
- !cpu->cfg.ext_zve32f) {
84
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
85
+ cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
86
error_setg(errp,
87
"Vector crypto extensions require V or Zve* extensions");
88
return;
89
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
90
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
91
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
92
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
93
+ DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
94
95
DEFINE_PROP_END_OF_LIST(),
96
};
97
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
98
index XXXXXXX..XXXXXXX 100644
99
--- a/target/riscv/vcrypto_helper.c
100
+++ b/target/riscv/vcrypto_helper.c
101
@@ -XXX,XX +XXX,XX @@ void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
102
vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
103
env->vstart = 0;
104
}
105
+
106
+static inline uint32_t p1(uint32_t x)
107
+{
108
+ return x ^ rol32(x, 15) ^ rol32(x, 23);
109
+}
110
+
111
+static inline uint32_t zvksh_w(uint32_t m16, uint32_t m9, uint32_t m3,
112
+ uint32_t m13, uint32_t m6)
113
+{
114
+ return p1(m16 ^ m9 ^ rol32(m3, 15)) ^ rol32(m13, 7) ^ m6;
115
+}
116
+
117
+void HELPER(vsm3me_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
118
+ CPURISCVState *env, uint32_t desc)
119
+{
120
+ uint32_t esz = memop_size(FIELD_EX64(env->vtype, VTYPE, VSEW));
121
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
122
+ uint32_t vta = vext_vta(desc);
123
+ uint32_t *vd = vd_vptr;
124
+ uint32_t *vs1 = vs1_vptr;
125
+ uint32_t *vs2 = vs2_vptr;
126
+
127
+ for (int i = env->vstart / 8; i < env->vl / 8; i++) {
128
+ uint32_t w[24];
129
+ for (int j = 0; j < 8; j++) {
130
+ w[j] = bswap32(vs1[H4((i * 8) + j)]);
131
+ w[j + 8] = bswap32(vs2[H4((i * 8) + j)]);
132
+ }
133
+ for (int j = 0; j < 8; j++) {
134
+ w[j + 16] =
135
+ zvksh_w(w[j], w[j + 7], w[j + 13], w[j + 3], w[j + 10]);
136
+ }
137
+ for (int j = 0; j < 8; j++) {
138
+ vd[(i * 8) + j] = bswap32(w[H4(j + 16)]);
139
+ }
140
+ }
141
+ vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
142
+ env->vstart = 0;
143
+}
144
+
145
+static inline uint32_t ff1(uint32_t x, uint32_t y, uint32_t z)
146
+{
147
+ return x ^ y ^ z;
148
+}
149
+
150
+static inline uint32_t ff2(uint32_t x, uint32_t y, uint32_t z)
151
+{
152
+ return (x & y) | (x & z) | (y & z);
153
+}
154
+
155
+static inline uint32_t ff_j(uint32_t x, uint32_t y, uint32_t z, uint32_t j)
156
+{
157
+ return (j <= 15) ? ff1(x, y, z) : ff2(x, y, z);
158
+}
159
+
160
+static inline uint32_t gg1(uint32_t x, uint32_t y, uint32_t z)
161
+{
162
+ return x ^ y ^ z;
163
+}
164
+
165
+static inline uint32_t gg2(uint32_t x, uint32_t y, uint32_t z)
166
+{
167
+ return (x & y) | (~x & z);
168
+}
169
+
170
+static inline uint32_t gg_j(uint32_t x, uint32_t y, uint32_t z, uint32_t j)
171
+{
172
+ return (j <= 15) ? gg1(x, y, z) : gg2(x, y, z);
173
+}
174
+
175
+static inline uint32_t t_j(uint32_t j)
176
+{
177
+ return (j <= 15) ? 0x79cc4519 : 0x7a879d8a;
178
+}
179
+
180
+static inline uint32_t p_0(uint32_t x)
181
+{
182
+ return x ^ rol32(x, 9) ^ rol32(x, 17);
183
+}
184
+
185
+static void sm3c(uint32_t *vd, uint32_t *vs1, uint32_t *vs2, uint32_t uimm)
186
+{
187
+ uint32_t x0, x1;
188
+ uint32_t j;
189
+ uint32_t ss1, ss2, tt1, tt2;
190
+ x0 = vs2[0] ^ vs2[4];
191
+ x1 = vs2[1] ^ vs2[5];
192
+ j = 2 * uimm;
193
+ ss1 = rol32(rol32(vs1[0], 12) + vs1[4] + rol32(t_j(j), j % 32), 7);
194
+ ss2 = ss1 ^ rol32(vs1[0], 12);
195
+ tt1 = ff_j(vs1[0], vs1[1], vs1[2], j) + vs1[3] + ss2 + x0;
196
+ tt2 = gg_j(vs1[4], vs1[5], vs1[6], j) + vs1[7] + ss1 + vs2[0];
197
+ vs1[3] = vs1[2];
198
+ vd[3] = rol32(vs1[1], 9);
199
+ vs1[1] = vs1[0];
200
+ vd[1] = tt1;
201
+ vs1[7] = vs1[6];
202
+ vd[7] = rol32(vs1[5], 19);
203
+ vs1[5] = vs1[4];
204
+ vd[5] = p_0(tt2);
205
+ j = 2 * uimm + 1;
206
+ ss1 = rol32(rol32(vd[1], 12) + vd[5] + rol32(t_j(j), j % 32), 7);
207
+ ss2 = ss1 ^ rol32(vd[1], 12);
208
+ tt1 = ff_j(vd[1], vs1[1], vd[3], j) + vs1[3] + ss2 + x1;
209
+ tt2 = gg_j(vd[5], vs1[5], vd[7], j) + vs1[7] + ss1 + vs2[1];
210
+ vd[2] = rol32(vs1[1], 9);
211
+ vd[0] = tt1;
212
+ vd[6] = rol32(vs1[5], 19);
213
+ vd[4] = p_0(tt2);
214
+}
215
+
216
+void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
217
+ CPURISCVState *env, uint32_t desc)
218
+{
219
+ uint32_t esz = memop_size(FIELD_EX64(env->vtype, VTYPE, VSEW));
220
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
221
+ uint32_t vta = vext_vta(desc);
222
+ uint32_t *vd = vd_vptr;
223
+ uint32_t *vs2 = vs2_vptr;
224
+ uint32_t v1[8], v2[8], v3[8];
225
+
226
+ for (int i = env->vstart / 8; i < env->vl / 8; i++) {
227
+ for (int k = 0; k < 8; k++) {
228
+ v2[k] = bswap32(vd[H4(i * 8 + k)]);
229
+ v3[k] = bswap32(vs2[H4(i * 8 + k)]);
230
+ }
231
+ sm3c(v1, v2, v3, uimm);
232
+ for (int k = 0; k < 8; k++) {
233
+ vd[i * 8 + k] = bswap32(v1[H4(k)]);
234
+ }
235
+ }
236
+ vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
237
+ env->vstart = 0;
238
+}
239
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
240
index XXXXXXX..XXXXXXX 100644
241
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
242
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
243
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
244
}
245
return false;
246
}
247
+
248
+/*
249
+ * Zvksh
250
+ */
251
+
252
+#define ZVKSH_EGS 8
253
+
254
+static inline bool vsm3_check(DisasContext *s, arg_rmrr *a)
255
+{
256
+ int egw_bytes = ZVKSH_EGS << s->sew;
257
+ int mult = 1 << MAX(s->lmul, 0);
258
+ return s->cfg_ptr->ext_zvksh == true &&
259
+ require_rvv(s) &&
260
+ vext_check_isa_ill(s) &&
261
+ !is_overlapped(a->rd, mult, a->rs2, mult) &&
262
+ MAXSZ(s) >= egw_bytes &&
263
+ s->sew == MO_32;
264
+}
265
+
266
+static inline bool vsm3me_check(DisasContext *s, arg_rmrr *a)
267
+{
268
+ return vsm3_check(s, a) && vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm);
269
+}
270
+
271
+static inline bool vsm3c_check(DisasContext *s, arg_rmrr *a)
272
+{
273
+ return vsm3_check(s, a) && vext_check_ss(s, a->rd, a->rs2, a->vm);
274
+}
275
+
276
+GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS)
277
+GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS)
31
--
278
--
32
2.39.0
279
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
This test is used to do a quick sanity check to ensure that we're able
3
This commit adds support for the Zvkg vector-crypto extension, which
4
to run the existing QEMU FW image.
4
consists of the following instructions:
5
5
6
'sifive_u', 'spike' and 'virt' riscv64 machines, and 'sifive_u' and
6
* vgmul.vv
7
'virt' 32 bit machines are able to run the default RISCV64_BIOS_BIN |
7
* vghsh.vv
8
RISCV32_BIOS_BIN firmware with minimal options.
8
9
9
Translation functions are defined in
10
The riscv32 'spike' machine isn't bootable at this moment, requiring an
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
OpenSBI fix [1] and QEMU side changes [2]. We could just leave at that
11
`target/riscv/vcrypto_helper.c`.
12
or add a 'skip' test to remind us about it. To work as a reminder that
12
13
we have a riscv32 'spike' test that should be enabled as soon as OpenSBI
13
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
14
QEMU rom receives the fix, we're adding a 'skip' test:
14
[max.chou@sifive.com: Replaced vstart checking by TCG op]
15
15
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
16
(06/18) tests/avocado/riscv_opensbi.py:RiscvOpenSBI.test_riscv32_spike:
16
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
17
SKIP: requires OpenSBI fix to work
17
Signed-off-by: Max Chou <max.chou@sifive.com>
18
18
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
19
[1] https://patchwork.ozlabs.org/project/opensbi/patch/20221226033603.1860569-1-bmeng@tinylab.org/
19
[max.chou@sifive.com: Exposed x-zvkg property]
20
[2] https://patchwork.ozlabs.org/project/qemu-devel/list/?series=334159
20
[max.chou@sifive.com: Replaced uint by int for cross win32 build]
21
21
Message-ID: <20230711165917.2629866-13-max.chou@sifive.com>
22
Cc: Cleber Rosa <crosa@redhat.com>
23
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
24
Reviewed-by: Bin Meng <bmeng@tinylab.org>
25
Tested-by: Bin Meng <bmeng@tinylab.org>
26
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
27
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
28
Acked-by: Alistair Francis <alistair.francis@wdc.com>
29
Message-Id: <20230102115241.25733-2-dbarboza@ventanamicro.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
31
---
23
---
32
tests/avocado/riscv_opensbi.py | 65 ++++++++++++++++++++++++++++++++++
24
target/riscv/cpu_cfg.h | 1 +
33
1 file changed, 65 insertions(+)
25
target/riscv/helper.h | 3 +
34
create mode 100644 tests/avocado/riscv_opensbi.py
26
target/riscv/insn32.decode | 4 ++
35
27
target/riscv/cpu.c | 6 +-
36
diff --git a/tests/avocado/riscv_opensbi.py b/tests/avocado/riscv_opensbi.py
28
target/riscv/vcrypto_helper.c | 72 ++++++++++++++++++++++++
37
new file mode 100644
29
target/riscv/insn_trans/trans_rvvk.c.inc | 30 ++++++++++
38
index XXXXXXX..XXXXXXX
30
6 files changed, 114 insertions(+), 2 deletions(-)
39
--- /dev/null
31
40
+++ b/tests/avocado/riscv_opensbi.py
32
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
41
@@ -XXX,XX +XXX,XX @@
33
index XXXXXXX..XXXXXXX 100644
42
+# OpenSBI boot test for RISC-V machines
34
--- a/target/riscv/cpu_cfg.h
43
+#
35
+++ b/target/riscv/cpu_cfg.h
44
+# Copyright (c) 2022, Ventana Micro
36
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
45
+#
37
bool ext_zve64d;
46
+# This work is licensed under the terms of the GNU GPL, version 2 or
38
bool ext_zvbb;
47
+# later. See the COPYING file in the top-level directory.
39
bool ext_zvbc;
48
+
40
+ bool ext_zvkg;
49
+from avocado_qemu import QemuSystemTest
41
bool ext_zvkned;
50
+from avocado import skip
42
bool ext_zvknha;
51
+from avocado_qemu import wait_for_console_pattern
43
bool ext_zvknhb;
52
+
44
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
53
+class RiscvOpenSBI(QemuSystemTest):
45
index XXXXXXX..XXXXXXX 100644
54
+ """
46
--- a/target/riscv/helper.h
55
+ :avocado: tags=accel:tcg
47
+++ b/target/riscv/helper.h
56
+ """
48
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
57
+ timeout = 5
49
58
+
50
DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
59
+ def boot_opensbi(self):
51
DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
60
+ self.vm.set_console()
52
+
61
+ self.vm.launch()
53
+DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
62
+ wait_for_console_pattern(self, 'Platform Name')
54
+DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
63
+ wait_for_console_pattern(self, 'Boot HART MEDELEG')
55
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
64
+
56
index XXXXXXX..XXXXXXX 100644
65
+ @skip("requires OpenSBI fix to work")
57
--- a/target/riscv/insn32.decode
66
+ def test_riscv32_spike(self):
58
+++ b/target/riscv/insn32.decode
67
+ """
59
@@ -XXX,XX +XXX,XX @@ vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
68
+ :avocado: tags=arch:riscv32
60
# *** Zvksh vector crypto extension ***
69
+ :avocado: tags=machine:spike
61
vsm3me_vv 100000 1 ..... ..... 010 ..... 1110111 @r_vm_1
70
+ """
62
vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
71
+ self.boot_opensbi()
63
+
72
+
64
+# *** Zvkg vector crypto extension ***
73
+ def test_riscv64_spike(self):
65
+vghsh_vv 101100 1 ..... ..... 010 ..... 1110111 @r_vm_1
74
+ """
66
+vgmul_vv 101000 1 ..... 10001 010 ..... 1110111 @r2_vm_1
75
+ :avocado: tags=arch:riscv64
67
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
76
+ :avocado: tags=machine:spike
68
index XXXXXXX..XXXXXXX 100644
77
+ """
69
--- a/target/riscv/cpu.c
78
+ self.boot_opensbi()
70
+++ b/target/riscv/cpu.c
79
+
71
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
80
+ def test_riscv32_sifive_u(self):
72
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
81
+ """
73
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
82
+ :avocado: tags=arch:riscv32
74
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
83
+ :avocado: tags=machine:sifive_u
75
+ ISA_EXT_DATA_ENTRY(zvkg, PRIV_VERSION_1_12_0, ext_zvkg),
84
+ """
76
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
85
+ self.boot_opensbi()
77
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
86
+
78
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
87
+ def test_riscv64_sifive_u(self):
79
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
88
+ """
80
* In principle Zve*x would also suffice here, were they supported
89
+ :avocado: tags=arch:riscv64
81
* in qemu
90
+ :avocado: tags=machine:sifive_u
82
*/
91
+ """
83
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
92
+ self.boot_opensbi()
84
- cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
93
+
85
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
94
+ def test_riscv32_virt(self):
86
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
95
+ """
87
error_setg(errp,
96
+ :avocado: tags=arch:riscv32
88
"Vector crypto extensions require V or Zve* extensions");
97
+ :avocado: tags=machine:virt
89
return;
98
+ """
90
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
99
+ self.boot_opensbi()
91
/* Vector cryptography extensions */
100
+
92
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
101
+ def test_riscv64_virt(self):
93
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
102
+ """
94
+ DEFINE_PROP_BOOL("x-zvkg", RISCVCPU, cfg.ext_zvkg, false),
103
+ :avocado: tags=arch:riscv64
95
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
104
+ :avocado: tags=machine:virt
96
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
105
+ """
97
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
106
+ self.boot_opensbi()
98
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/riscv/vcrypto_helper.c
101
+++ b/target/riscv/vcrypto_helper.c
102
@@ -XXX,XX +XXX,XX @@ void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
103
vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
104
env->vstart = 0;
105
}
106
+
107
+void HELPER(vghsh_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
108
+ CPURISCVState *env, uint32_t desc)
109
+{
110
+ uint64_t *vd = vd_vptr;
111
+ uint64_t *vs1 = vs1_vptr;
112
+ uint64_t *vs2 = vs2_vptr;
113
+ uint32_t vta = vext_vta(desc);
114
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
115
+
116
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
117
+ uint64_t Y[2] = {vd[i * 2 + 0], vd[i * 2 + 1]};
118
+ uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
119
+ uint64_t X[2] = {vs1[i * 2 + 0], vs1[i * 2 + 1]};
120
+ uint64_t Z[2] = {0, 0};
121
+
122
+ uint64_t S[2] = {brev8(Y[0] ^ X[0]), brev8(Y[1] ^ X[1])};
123
+
124
+ for (int j = 0; j < 128; j++) {
125
+ if ((S[j / 64] >> (j % 64)) & 1) {
126
+ Z[0] ^= H[0];
127
+ Z[1] ^= H[1];
128
+ }
129
+ bool reduce = ((H[1] >> 63) & 1);
130
+ H[1] = H[1] << 1 | H[0] >> 63;
131
+ H[0] = H[0] << 1;
132
+ if (reduce) {
133
+ H[0] ^= 0x87;
134
+ }
135
+ }
136
+
137
+ vd[i * 2 + 0] = brev8(Z[0]);
138
+ vd[i * 2 + 1] = brev8(Z[1]);
139
+ }
140
+ /* set tail elements to 1s */
141
+ vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
142
+ env->vstart = 0;
143
+}
144
+
145
+void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env,
146
+ uint32_t desc)
147
+{
148
+ uint64_t *vd = vd_vptr;
149
+ uint64_t *vs2 = vs2_vptr;
150
+ uint32_t vta = vext_vta(desc);
151
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
152
+
153
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
154
+ uint64_t Y[2] = {brev8(vd[i * 2 + 0]), brev8(vd[i * 2 + 1])};
155
+ uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
156
+ uint64_t Z[2] = {0, 0};
157
+
158
+ for (int j = 0; j < 128; j++) {
159
+ if ((Y[j / 64] >> (j % 64)) & 1) {
160
+ Z[0] ^= H[0];
161
+ Z[1] ^= H[1];
162
+ }
163
+ bool reduce = ((H[1] >> 63) & 1);
164
+ H[1] = H[1] << 1 | H[0] >> 63;
165
+ H[0] = H[0] << 1;
166
+ if (reduce) {
167
+ H[0] ^= 0x87;
168
+ }
169
+ }
170
+
171
+ vd[i * 2 + 0] = brev8(Z[0]);
172
+ vd[i * 2 + 1] = brev8(Z[1]);
173
+ }
174
+ /* set tail elements to 1s */
175
+ vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
176
+ env->vstart = 0;
177
+}
178
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
179
index XXXXXXX..XXXXXXX 100644
180
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
181
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
182
@@ -XXX,XX +XXX,XX @@ static inline bool vsm3c_check(DisasContext *s, arg_rmrr *a)
183
184
GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS)
185
GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS)
186
+
187
+/*
188
+ * Zvkg
189
+ */
190
+
191
+#define ZVKG_EGS 4
192
+
193
+static bool vgmul_check(DisasContext *s, arg_rmr *a)
194
+{
195
+ int egw_bytes = ZVKG_EGS << s->sew;
196
+ return s->cfg_ptr->ext_zvkg == true &&
197
+ vext_check_isa_ill(s) &&
198
+ require_rvv(s) &&
199
+ MAXSZ(s) >= egw_bytes &&
200
+ vext_check_ss(s, a->rd, a->rs2, a->vm) &&
201
+ s->sew == MO_32;
202
+}
203
+
204
+GEN_V_UNMASKED_TRANS(vgmul_vv, vgmul_check, ZVKG_EGS)
205
+
206
+static bool vghsh_check(DisasContext *s, arg_rmrr *a)
207
+{
208
+ int egw_bytes = ZVKG_EGS << s->sew;
209
+ return s->cfg_ptr->ext_zvkg == true &&
210
+ opivv_check(s, a) &&
211
+ MAXSZ(s) >= egw_bytes &&
212
+ s->sew == MO_32;
213
+}
214
+
215
+GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
107
--
216
--
108
2.39.0
217
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
Rename previous riscv_find_firmware() to riscv_find_bios(), and
3
Allows sharing of sm4_subword between different targets.
4
introduce a new riscv_find_firmware() to implement the first half
5
part of the work done in riscv_find_and_load_firmware().
6
4
7
This new API is helpful for machine that wants to know the final
5
Signed-off-by: Max Chou <max.chou@sifive.com>
8
chosen firmware file name but does not want to load it.
6
Reviewed-by: Frank Chang <frank.chang@sifive.com>
9
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Bin Meng <bmeng@tinylab.org>
8
Signed-off-by: Max Chou <max.chou@sifive.com>
11
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Message-ID: <20230711165917.2629866-14-max.chou@sifive.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-Id: <20221229091828.1945072-12-bmeng@tinylab.org>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
11
---
16
include/hw/riscv/boot.h | 2 ++
12
include/crypto/sm4.h | 8 ++++++++
17
hw/riscv/boot.c | 39 +++++++++++++++++++++++++--------------
13
target/arm/tcg/crypto_helper.c | 10 ++--------
18
2 files changed, 27 insertions(+), 14 deletions(-)
14
2 files changed, 10 insertions(+), 8 deletions(-)
19
15
20
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
16
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/riscv/boot.h
18
--- a/include/crypto/sm4.h
23
+++ b/include/hw/riscv/boot.h
19
+++ b/include/crypto/sm4.h
24
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_find_and_load_firmware(MachineState *machine,
20
@@ -XXX,XX +XXX,XX @@
25
hwaddr firmware_load_addr,
21
26
symbol_fn_t sym_cb);
22
extern const uint8_t sm4_sbox[256];
27
const char *riscv_default_firmware_name(RISCVHartArrayState *harts);
23
28
+char *riscv_find_firmware(const char *firmware_filename,
24
+static inline uint32_t sm4_subword(uint32_t word)
29
+ const char *default_machine_firmware);
25
+{
30
target_ulong riscv_load_firmware(const char *firmware_filename,
26
+ return sm4_sbox[word & 0xff] |
31
hwaddr firmware_load_addr,
27
+ sm4_sbox[(word >> 8) & 0xff] << 8 |
32
symbol_fn_t sym_cb);
28
+ sm4_sbox[(word >> 16) & 0xff] << 16 |
33
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
29
+ sm4_sbox[(word >> 24) & 0xff] << 24;
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/riscv/boot.c
36
+++ b/hw/riscv/boot.c
37
@@ -XXX,XX +XXX,XX @@ const char *riscv_default_firmware_name(RISCVHartArrayState *harts)
38
return RISCV64_BIOS_BIN;
39
}
40
41
-static char *riscv_find_firmware(const char *firmware_filename)
42
+static char *riscv_find_bios(const char *bios_filename)
43
{
44
char *filename;
45
46
- filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware_filename);
47
+ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_filename);
48
if (filename == NULL) {
49
if (!qtest_enabled()) {
50
/*
51
@@ -XXX,XX +XXX,XX @@ static char *riscv_find_firmware(const char *firmware_filename)
52
* running QEMU test will complain hence let's suppress the error
53
* report for QEMU testing.
54
*/
55
- error_report("Unable to load the RISC-V firmware \"%s\"",
56
- firmware_filename);
57
+ error_report("Unable to find the RISC-V BIOS \"%s\"",
58
+ bios_filename);
59
exit(1);
60
}
61
}
62
@@ -XXX,XX +XXX,XX @@ static char *riscv_find_firmware(const char *firmware_filename)
63
return filename;
64
}
65
66
-target_ulong riscv_find_and_load_firmware(MachineState *machine,
67
- const char *default_machine_firmware,
68
- hwaddr firmware_load_addr,
69
- symbol_fn_t sym_cb)
70
+char *riscv_find_firmware(const char *firmware_filename,
71
+ const char *default_machine_firmware)
72
{
73
- char *firmware_filename = NULL;
74
- target_ulong firmware_end_addr = firmware_load_addr;
75
+ char *filename = NULL;
76
77
- if ((!machine->firmware) || (!strcmp(machine->firmware, "default"))) {
78
+ if ((!firmware_filename) || (!strcmp(firmware_filename, "default"))) {
79
/*
80
* The user didn't specify -bios, or has specified "-bios default".
81
* That means we are going to load the OpenSBI binary included in
82
* the QEMU source.
83
*/
84
- firmware_filename = riscv_find_firmware(default_machine_firmware);
85
- } else if (strcmp(machine->firmware, "none")) {
86
- firmware_filename = riscv_find_firmware(machine->firmware);
87
+ filename = riscv_find_bios(default_machine_firmware);
88
+ } else if (strcmp(firmware_filename, "none")) {
89
+ filename = riscv_find_bios(firmware_filename);
90
}
91
92
+ return filename;
93
+}
30
+}
94
+
31
+
95
+target_ulong riscv_find_and_load_firmware(MachineState *machine,
32
#endif
96
+ const char *default_machine_firmware,
33
diff --git a/target/arm/tcg/crypto_helper.c b/target/arm/tcg/crypto_helper.c
97
+ hwaddr firmware_load_addr,
34
index XXXXXXX..XXXXXXX 100644
98
+ symbol_fn_t sym_cb)
35
--- a/target/arm/tcg/crypto_helper.c
99
+{
36
+++ b/target/arm/tcg/crypto_helper.c
100
+ char *firmware_filename;
37
@@ -XXX,XX +XXX,XX @@ static void do_crypto_sm4e(uint64_t *rd, uint64_t *rn, uint64_t *rm)
101
+ target_ulong firmware_end_addr = firmware_load_addr;
38
CR_ST_WORD(d, (i + 3) % 4) ^
102
+
39
CR_ST_WORD(n, i);
103
+ firmware_filename = riscv_find_firmware(machine->firmware,
40
104
+ default_machine_firmware);
41
- t = sm4_sbox[t & 0xff] |
105
+
42
- sm4_sbox[(t >> 8) & 0xff] << 8 |
106
if (firmware_filename) {
43
- sm4_sbox[(t >> 16) & 0xff] << 16 |
107
/* If not "none" load the firmware */
44
- sm4_sbox[(t >> 24) & 0xff] << 24;
108
firmware_end_addr = riscv_load_firmware(firmware_filename,
45
+ t = sm4_subword(t);
46
47
CR_ST_WORD(d, i) ^= t ^ rol32(t, 2) ^ rol32(t, 10) ^ rol32(t, 18) ^
48
rol32(t, 24);
49
@@ -XXX,XX +XXX,XX @@ static void do_crypto_sm4ekey(uint64_t *rd, uint64_t *rn, uint64_t *rm)
50
CR_ST_WORD(d, (i + 3) % 4) ^
51
CR_ST_WORD(m, i);
52
53
- t = sm4_sbox[t & 0xff] |
54
- sm4_sbox[(t >> 8) & 0xff] << 8 |
55
- sm4_sbox[(t >> 16) & 0xff] << 16 |
56
- sm4_sbox[(t >> 24) & 0xff] << 24;
57
+ t = sm4_subword(t);
58
59
CR_ST_WORD(d, i) ^= t ^ rol32(t, 13) ^ rol32(t, 23);
60
}
109
--
61
--
110
2.39.0
62
2.41.0
diff view generated by jsdifflib
New patch
1
From: Max Chou <max.chou@sifive.com>
1
2
3
Adds sm4_ck constant for use in sm4 cryptography across different targets.
4
5
Signed-off-by: Max Chou <max.chou@sifive.com>
6
Reviewed-by: Frank Chang <frank.chang@sifive.com>
7
Signed-off-by: Max Chou <max.chou@sifive.com>
8
Message-ID: <20230711165917.2629866-15-max.chou@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
include/crypto/sm4.h | 1 +
12
crypto/sm4.c | 10 ++++++++++
13
2 files changed, 11 insertions(+)
14
15
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/crypto/sm4.h
18
+++ b/include/crypto/sm4.h
19
@@ -XXX,XX +XXX,XX @@
20
#define QEMU_SM4_H
21
22
extern const uint8_t sm4_sbox[256];
23
+extern const uint32_t sm4_ck[32];
24
25
static inline uint32_t sm4_subword(uint32_t word)
26
{
27
diff --git a/crypto/sm4.c b/crypto/sm4.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/crypto/sm4.c
30
+++ b/crypto/sm4.c
31
@@ -XXX,XX +XXX,XX @@ uint8_t const sm4_sbox[] = {
32
0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
33
};
34
35
+uint32_t const sm4_ck[] = {
36
+ 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
37
+ 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
38
+ 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
39
+ 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
40
+ 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
41
+ 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
42
+ 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
43
+ 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
44
+};
45
--
46
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
Spike machine now supports OpenSBI plain binary bios image, so the
3
This commit adds support for the Zvksed vector-crypto extension, which
4
comments are no longer valid.
4
consists of the following instructions:
5
5
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
6
* vsm4k.vi
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
* vsm4r.[vv,vs]
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
9
Message-Id: <20221229091828.1945072-9-bmeng@tinylab.org>
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Signed-off-by: Max Chou <max.chou@sifive.com>
14
Reviewed-by: Frank Chang <frank.chang@sifive.com>
15
[lawrence.hunter@codethink.co.uk: Moved SM4 functions from
16
crypto_helper.c to vcrypto_helper.c]
17
[nazar.kazakov@codethink.co.uk: Added alignment checks, refactored code to
18
use macros, and minor style changes]
19
Signed-off-by: Max Chou <max.chou@sifive.com>
20
Message-ID: <20230711165917.2629866-16-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
22
---
12
hw/riscv/spike.c | 5 -----
23
target/riscv/cpu_cfg.h | 1 +
13
1 file changed, 5 deletions(-)
24
target/riscv/helper.h | 4 +
14
25
target/riscv/insn32.decode | 5 +
15
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
26
target/riscv/cpu.c | 5 +-
16
index XXXXXXX..XXXXXXX 100644
27
target/riscv/vcrypto_helper.c | 127 +++++++++++++++++++++++
17
--- a/hw/riscv/spike.c
28
target/riscv/insn_trans/trans_rvvk.c.inc | 43 ++++++++
18
+++ b/hw/riscv/spike.c
29
6 files changed, 184 insertions(+), 1 deletion(-)
19
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
30
20
memory_region_add_subregion(system_memory, memmap[SPIKE_MROM].base,
31
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
21
mask_rom);
32
index XXXXXXX..XXXXXXX 100644
22
33
--- a/target/riscv/cpu_cfg.h
23
- /*
34
+++ b/target/riscv/cpu_cfg.h
24
- * Not like other RISC-V machines that use plain binary bios images,
35
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
25
- * keeping ELF files here was intentional because BIN files don't work
36
bool ext_zvkned;
26
- * for the Spike machine as HTIF emulation depends on ELF parsing.
37
bool ext_zvknha;
27
- */
38
bool ext_zvknhb;
28
if (riscv_is_32bit(&s->soc[0])) {
39
+ bool ext_zvksed;
29
firmware_end_addr = riscv_find_and_load_firmware(machine,
40
bool ext_zvksh;
30
RISCV32_BIOS_BIN, memmap[SPIKE_DRAM].base,
41
bool ext_zmmul;
42
bool ext_zvfbfmin;
43
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/helper.h
46
+++ b/target/riscv/helper.h
47
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
48
49
DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
50
DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
51
+
52
+DEF_HELPER_5(vsm4k_vi, void, ptr, ptr, i32, env, i32)
53
+DEF_HELPER_4(vsm4r_vv, void, ptr, ptr, env, i32)
54
+DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32)
55
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/riscv/insn32.decode
58
+++ b/target/riscv/insn32.decode
59
@@ -XXX,XX +XXX,XX @@ vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
60
# *** Zvkg vector crypto extension ***
61
vghsh_vv 101100 1 ..... ..... 010 ..... 1110111 @r_vm_1
62
vgmul_vv 101000 1 ..... 10001 010 ..... 1110111 @r2_vm_1
63
+
64
+# *** Zvksed vector crypto extension ***
65
+vsm4k_vi 100001 1 ..... ..... 010 ..... 1110111 @r_vm_1
66
+vsm4r_vv 101000 1 ..... 10000 010 ..... 1110111 @r2_vm_1
67
+vsm4r_vs 101001 1 ..... 10000 010 ..... 1110111 @r2_vm_1
68
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/riscv/cpu.c
71
+++ b/target/riscv/cpu.c
72
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
73
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
74
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
75
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
76
+ ISA_EXT_DATA_ENTRY(zvksed, PRIV_VERSION_1_12_0, ext_zvksed),
77
ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh),
78
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
79
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
80
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
81
* in qemu
82
*/
83
if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
84
- cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
85
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed || cpu->cfg.ext_zvksh) &&
86
+ !cpu->cfg.ext_zve32f) {
87
error_setg(errp,
88
"Vector crypto extensions require V or Zve* extensions");
89
return;
90
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
91
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
92
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
93
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
94
+ DEFINE_PROP_BOOL("x-zvksed", RISCVCPU, cfg.ext_zvksed, false),
95
DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
96
97
DEFINE_PROP_END_OF_LIST(),
98
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/riscv/vcrypto_helper.c
101
+++ b/target/riscv/vcrypto_helper.c
102
@@ -XXX,XX +XXX,XX @@
103
#include "cpu.h"
104
#include "crypto/aes.h"
105
#include "crypto/aes-round.h"
106
+#include "crypto/sm4.h"
107
#include "exec/memop.h"
108
#include "exec/exec-all.h"
109
#include "exec/helper-proto.h"
110
@@ -XXX,XX +XXX,XX @@ void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env,
111
vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
112
env->vstart = 0;
113
}
114
+
115
+void HELPER(vsm4k_vi)(void *vd, void *vs2, uint32_t uimm5, CPURISCVState *env,
116
+ uint32_t desc)
117
+{
118
+ const uint32_t egs = 4;
119
+ uint32_t rnd = uimm5 & 0x7;
120
+ uint32_t group_start = env->vstart / egs;
121
+ uint32_t group_end = env->vl / egs;
122
+ uint32_t esz = sizeof(uint32_t);
123
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
124
+
125
+ for (uint32_t i = group_start; i < group_end; ++i) {
126
+ uint32_t vstart = i * egs;
127
+ uint32_t vend = (i + 1) * egs;
128
+ uint32_t rk[4] = {0};
129
+ uint32_t tmp[8] = {0};
130
+
131
+ for (uint32_t j = vstart; j < vend; ++j) {
132
+ rk[j - vstart] = *((uint32_t *)vs2 + H4(j));
133
+ }
134
+
135
+ for (uint32_t j = 0; j < egs; ++j) {
136
+ tmp[j] = rk[j];
137
+ }
138
+
139
+ for (uint32_t j = 0; j < egs; ++j) {
140
+ uint32_t b, s;
141
+ b = tmp[j + 1] ^ tmp[j + 2] ^ tmp[j + 3] ^ sm4_ck[rnd * 4 + j];
142
+
143
+ s = sm4_subword(b);
144
+
145
+ tmp[j + 4] = tmp[j] ^ (s ^ rol32(s, 13) ^ rol32(s, 23));
146
+ }
147
+
148
+ for (uint32_t j = vstart; j < vend; ++j) {
149
+ *((uint32_t *)vd + H4(j)) = tmp[egs + (j - vstart)];
150
+ }
151
+ }
152
+
153
+ env->vstart = 0;
154
+ /* set tail elements to 1s */
155
+ vext_set_elems_1s(vd, vext_vta(desc), env->vl * esz, total_elems * esz);
156
+}
157
+
158
+static void do_sm4_round(uint32_t *rk, uint32_t *buf)
159
+{
160
+ const uint32_t egs = 4;
161
+ uint32_t s, b;
162
+
163
+ for (uint32_t j = egs; j < egs * 2; ++j) {
164
+ b = buf[j - 3] ^ buf[j - 2] ^ buf[j - 1] ^ rk[j - 4];
165
+
166
+ s = sm4_subword(b);
167
+
168
+ buf[j] = buf[j - 4] ^ (s ^ rol32(s, 2) ^ rol32(s, 10) ^ rol32(s, 18) ^
169
+ rol32(s, 24));
170
+ }
171
+}
172
+
173
+void HELPER(vsm4r_vv)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
174
+{
175
+ const uint32_t egs = 4;
176
+ uint32_t group_start = env->vstart / egs;
177
+ uint32_t group_end = env->vl / egs;
178
+ uint32_t esz = sizeof(uint32_t);
179
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
180
+
181
+ for (uint32_t i = group_start; i < group_end; ++i) {
182
+ uint32_t vstart = i * egs;
183
+ uint32_t vend = (i + 1) * egs;
184
+ uint32_t rk[4] = {0};
185
+ uint32_t tmp[8] = {0};
186
+
187
+ for (uint32_t j = vstart; j < vend; ++j) {
188
+ rk[j - vstart] = *((uint32_t *)vs2 + H4(j));
189
+ }
190
+
191
+ for (uint32_t j = vstart; j < vend; ++j) {
192
+ tmp[j - vstart] = *((uint32_t *)vd + H4(j));
193
+ }
194
+
195
+ do_sm4_round(rk, tmp);
196
+
197
+ for (uint32_t j = vstart; j < vend; ++j) {
198
+ *((uint32_t *)vd + H4(j)) = tmp[egs + (j - vstart)];
199
+ }
200
+ }
201
+
202
+ env->vstart = 0;
203
+ /* set tail elements to 1s */
204
+ vext_set_elems_1s(vd, vext_vta(desc), env->vl * esz, total_elems * esz);
205
+}
206
+
207
+void HELPER(vsm4r_vs)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
208
+{
209
+ const uint32_t egs = 4;
210
+ uint32_t group_start = env->vstart / egs;
211
+ uint32_t group_end = env->vl / egs;
212
+ uint32_t esz = sizeof(uint32_t);
213
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
214
+
215
+ for (uint32_t i = group_start; i < group_end; ++i) {
216
+ uint32_t vstart = i * egs;
217
+ uint32_t vend = (i + 1) * egs;
218
+ uint32_t rk[4] = {0};
219
+ uint32_t tmp[8] = {0};
220
+
221
+ for (uint32_t j = 0; j < egs; ++j) {
222
+ rk[j] = *((uint32_t *)vs2 + H4(j));
223
+ }
224
+
225
+ for (uint32_t j = vstart; j < vend; ++j) {
226
+ tmp[j - vstart] = *((uint32_t *)vd + H4(j));
227
+ }
228
+
229
+ do_sm4_round(rk, tmp);
230
+
231
+ for (uint32_t j = vstart; j < vend; ++j) {
232
+ *((uint32_t *)vd + H4(j)) = tmp[egs + (j - vstart)];
233
+ }
234
+ }
235
+
236
+ env->vstart = 0;
237
+ /* set tail elements to 1s */
238
+ vext_set_elems_1s(vd, vext_vta(desc), env->vl * esz, total_elems * esz);
239
+}
240
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
241
index XXXXXXX..XXXXXXX 100644
242
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
243
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
244
@@ -XXX,XX +XXX,XX @@ static bool vghsh_check(DisasContext *s, arg_rmrr *a)
245
}
246
247
GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
248
+
249
+/*
250
+ * Zvksed
251
+ */
252
+
253
+#define ZVKSED_EGS 4
254
+
255
+static bool zvksed_check(DisasContext *s)
256
+{
257
+ int egw_bytes = ZVKSED_EGS << s->sew;
258
+ return s->cfg_ptr->ext_zvksed == true &&
259
+ require_rvv(s) &&
260
+ vext_check_isa_ill(s) &&
261
+ MAXSZ(s) >= egw_bytes &&
262
+ s->sew == MO_32;
263
+}
264
+
265
+static bool vsm4k_vi_check(DisasContext *s, arg_rmrr *a)
266
+{
267
+ return zvksed_check(s) &&
268
+ require_align(a->rd, s->lmul) &&
269
+ require_align(a->rs2, s->lmul);
270
+}
271
+
272
+GEN_VI_UNMASKED_TRANS(vsm4k_vi, vsm4k_vi_check, ZVKSED_EGS)
273
+
274
+static bool vsm4r_vv_check(DisasContext *s, arg_rmr *a)
275
+{
276
+ return zvksed_check(s) &&
277
+ require_align(a->rd, s->lmul) &&
278
+ require_align(a->rs2, s->lmul);
279
+}
280
+
281
+GEN_V_UNMASKED_TRANS(vsm4r_vv, vsm4r_vv_check, ZVKSED_EGS)
282
+
283
+static bool vsm4r_vs_check(DisasContext *s, arg_rmr *a)
284
+{
285
+ return zvksed_check(s) &&
286
+ !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) &&
287
+ require_align(a->rd, s->lmul);
288
+}
289
+
290
+GEN_V_UNMASKED_TRANS(vsm4r_vs, vsm4r_vs_check, ZVKSED_EGS)
31
--
291
--
32
2.39.0
292
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Rob Bradford <rbradford@rivosinc.com>
2
2
3
'filename', 'mem_size' and 'fdt' from riscv_load_initrd() can all be
3
These are WARL fields - zero out the bits for unavailable counters and
4
retrieved by the MachineState object for all callers.
4
special case the TM bit in mcountinhibit which is hardwired to zero.
5
This patch achieves this by modifying the value written so that any use
6
of the field will see the correctly masked bits.
5
7
6
Cc: Palmer Dabbelt <palmer@dabbelt.com>
8
Tested by modifying OpenSBI to write max value to these CSRs and upon
7
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
subsequent read the appropriate number of bits for number of PMUs is
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
enabled and the TM bit is zero in mcountinhibit.
9
Reviewed-by: Bin Meng <bmeng@tinylab.org>
11
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
11
Message-Id: <20230102115241.25733-9-dbarboza@ventanamicro.com>
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Atish Patra <atishp@rivosinc.com>
15
Message-ID: <20230802124906.24197-1-rbradford@rivosinc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
17
---
14
include/hw/riscv/boot.h | 3 +--
18
target/riscv/csr.c | 11 +++++++++--
15
hw/riscv/boot.c | 6 ++++--
19
1 file changed, 9 insertions(+), 2 deletions(-)
16
hw/riscv/microchip_pfsoc.c | 3 +--
17
hw/riscv/sifive_u.c | 3 +--
18
hw/riscv/spike.c | 3 +--
19
hw/riscv/virt.c | 3 +--
20
6 files changed, 9 insertions(+), 12 deletions(-)
21
20
22
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
21
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
23
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/riscv/boot.h
23
--- a/target/riscv/csr.c
25
+++ b/include/hw/riscv/boot.h
24
+++ b/target/riscv/csr.c
26
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_firmware(const char *firmware_filename,
25
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
27
target_ulong riscv_load_kernel(const char *kernel_filename,
26
{
28
target_ulong firmware_end_addr,
27
int cidx;
29
symbol_fn_t sym_cb);
28
PMUCTRState *counter;
30
-void riscv_load_initrd(const char *filename, uint64_t mem_size,
29
+ RISCVCPU *cpu = env_archcpu(env);
31
- uint64_t kernel_entry, void *fdt);
30
32
+void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry);
31
- env->mcountinhibit = val;
33
uint64_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt);
32
+ /* WARL register - disable unavailable counters; TM bit is always 0 */
34
void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts,
33
+ env->mcountinhibit =
35
hwaddr saddr,
34
+ val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_IR);
36
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
35
37
index XXXXXXX..XXXXXXX 100644
36
/* Check if any other counter is also monitoring cycles/instructions */
38
--- a/hw/riscv/boot.c
37
for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
39
+++ b/hw/riscv/boot.c
38
@@ -XXX,XX +XXX,XX @@ static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
40
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(const char *kernel_filename,
39
static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
41
exit(1);
40
target_ulong val)
41
{
42
- env->mcounteren = val;
43
+ RISCVCPU *cpu = env_archcpu(env);
44
+
45
+ /* WARL register - disable unavailable counters */
46
+ env->mcounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
47
+ COUNTEREN_IR);
48
return RISCV_EXCP_NONE;
42
}
49
}
43
50
44
-void riscv_load_initrd(const char *filename, uint64_t mem_size,
45
- uint64_t kernel_entry, void *fdt)
46
+void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
47
{
48
+ const char *filename = machine->initrd_filename;
49
+ uint64_t mem_size = machine->ram_size;
50
+ void *fdt = machine->fdt;
51
hwaddr start, end;
52
ssize_t size;
53
54
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/riscv/microchip_pfsoc.c
57
+++ b/hw/riscv/microchip_pfsoc.c
58
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
59
kernel_start_addr, NULL);
60
61
if (machine->initrd_filename) {
62
- riscv_load_initrd(machine->initrd_filename, machine->ram_size,
63
- kernel_entry, machine->fdt);
64
+ riscv_load_initrd(machine, kernel_entry);
65
}
66
67
if (machine->kernel_cmdline && *machine->kernel_cmdline) {
68
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/riscv/sifive_u.c
71
+++ b/hw/riscv/sifive_u.c
72
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
73
kernel_start_addr, NULL);
74
75
if (machine->initrd_filename) {
76
- riscv_load_initrd(machine->initrd_filename, machine->ram_size,
77
- kernel_entry, machine->fdt);
78
+ riscv_load_initrd(machine, kernel_entry);
79
}
80
81
if (machine->kernel_cmdline && *machine->kernel_cmdline) {
82
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/riscv/spike.c
85
+++ b/hw/riscv/spike.c
86
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
87
htif_symbol_callback);
88
89
if (machine->initrd_filename) {
90
- riscv_load_initrd(machine->initrd_filename, machine->ram_size,
91
- kernel_entry, machine->fdt);
92
+ riscv_load_initrd(machine, kernel_entry);
93
}
94
95
if (machine->kernel_cmdline && *machine->kernel_cmdline) {
96
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/hw/riscv/virt.c
99
+++ b/hw/riscv/virt.c
100
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
101
kernel_start_addr, NULL);
102
103
if (machine->initrd_filename) {
104
- riscv_load_initrd(machine->initrd_filename, machine->ram_size,
105
- kernel_entry, machine->fdt);
106
+ riscv_load_initrd(machine, kernel_entry);
107
}
108
109
if (machine->kernel_cmdline && *machine->kernel_cmdline) {
110
--
51
--
111
2.39.0
52
2.41.0
diff view generated by jsdifflib
New patch
1
From: Jason Chien <jason.chien@sifive.com>
1
2
3
RVA23 Profiles states:
4
The RVA23 profiles are intended to be used for 64-bit application
5
processors that will run rich OS stacks from standard binary OS
6
distributions and with a substantial number of third-party binary user
7
applications that will be supported over a considerable length of time
8
in the field.
9
10
The chapter 4 of the unprivileged spec introduces the Zihintntl extension
11
and Zihintntl is a mandatory extension presented in RVA23 Profiles, whose
12
purpose is to enable application and operating system portability across
13
different implementations. Thus the DTS should contain the Zihintntl ISA
14
string in order to pass to software.
15
16
The unprivileged spec states:
17
Like any HINTs, these instructions may be freely ignored. Hence, although
18
they are described in terms of cache-based memory hierarchies, they do not
19
mandate the provision of caches.
20
21
These instructions are encoded with non-used opcode, e.g. ADD x0, x0, x2,
22
which QEMU already supports, and QEMU does not emulate cache. Therefore
23
these instructions can be considered as a no-op, and we only need to add
24
a new property for the Zihintntl extension.
25
26
Reviewed-by: Frank Chang <frank.chang@sifive.com>
27
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
28
Signed-off-by: Jason Chien <jason.chien@sifive.com>
29
Message-ID: <20230726074049.19505-2-jason.chien@sifive.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
31
---
32
target/riscv/cpu_cfg.h | 1 +
33
target/riscv/cpu.c | 2 ++
34
2 files changed, 3 insertions(+)
35
36
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/cpu_cfg.h
39
+++ b/target/riscv/cpu_cfg.h
40
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
41
bool ext_icbom;
42
bool ext_icboz;
43
bool ext_zicond;
44
+ bool ext_zihintntl;
45
bool ext_zihintpause;
46
bool ext_smstateen;
47
bool ext_sstc;
48
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/cpu.c
51
+++ b/target/riscv/cpu.c
52
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
53
ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
54
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
55
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
56
+ ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl),
57
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
58
ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
59
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
60
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
61
DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
62
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
63
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
64
+ DEFINE_PROP_BOOL("Zihintntl", RISCVCPU, cfg.ext_zihintntl, true),
65
DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
66
DEFINE_PROP_BOOL("Zawrs", RISCVCPU, cfg.ext_zawrs, true),
67
DEFINE_PROP_BOOL("Zfa", RISCVCPU, cfg.ext_zfa, true),
68
--
69
2.41.0
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
2
3
Commit a47842d ("riscv: Add support for the Zfa extension") implemented the zfa extension.
4
However, it has some typos for fleq.d and fltq.d. Both of them misused the fltq.s
5
helper function.
6
7
Fixes: a47842d ("riscv: Add support for the Zfa extension")
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
11
Message-ID: <20230728003906.768-1-zhiwei_liu@linux.alibaba.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/insn_trans/trans_rvzfa.c.inc | 4 ++--
15
1 file changed, 2 insertions(+), 2 deletions(-)
16
17
diff --git a/target/riscv/insn_trans/trans_rvzfa.c.inc b/target/riscv/insn_trans/trans_rvzfa.c.inc
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/insn_trans/trans_rvzfa.c.inc
20
+++ b/target/riscv/insn_trans/trans_rvzfa.c.inc
21
@@ -XXX,XX +XXX,XX @@ bool trans_fleq_d(DisasContext *ctx, arg_fleq_d *a)
22
TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
23
TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
24
25
- gen_helper_fltq_s(dest, cpu_env, src1, src2);
26
+ gen_helper_fleq_d(dest, cpu_env, src1, src2);
27
gen_set_gpr(ctx, a->rd, dest);
28
return true;
29
}
30
@@ -XXX,XX +XXX,XX @@ bool trans_fltq_d(DisasContext *ctx, arg_fltq_d *a)
31
TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
32
TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
33
34
- gen_helper_fltq_s(dest, cpu_env, src1, src2);
35
+ gen_helper_fltq_d(dest, cpu_env, src1, src2);
36
gen_set_gpr(ctx, a->rd, dest);
37
return true;
38
}
39
--
40
2.41.0
diff view generated by jsdifflib
New patch
1
From: Jason Chien <jason.chien@sifive.com>
1
2
3
When writing the upper mtime, we should keep the original lower mtime
4
whose value is given by cpu_riscv_read_rtc() instead of
5
cpu_riscv_read_rtc_raw(). The same logic applies to writes to lower mtime.
6
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20230728082502.26439-1-jason.chien@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
hw/intc/riscv_aclint.c | 5 +++--
13
1 file changed, 3 insertions(+), 2 deletions(-)
14
15
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/riscv_aclint.c
18
+++ b/hw/intc/riscv_aclint.c
19
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
20
return;
21
} else if (addr == mtimer->time_base || addr == mtimer->time_base + 4) {
22
uint64_t rtc_r = cpu_riscv_read_rtc_raw(mtimer->timebase_freq);
23
+ uint64_t rtc = cpu_riscv_read_rtc(mtimer);
24
25
if (addr == mtimer->time_base) {
26
if (size == 4) {
27
/* time_lo for RV32/RV64 */
28
- mtimer->time_delta = ((rtc_r & ~0xFFFFFFFFULL) | value) - rtc_r;
29
+ mtimer->time_delta = ((rtc & ~0xFFFFFFFFULL) | value) - rtc_r;
30
} else {
31
/* time for RV64 */
32
mtimer->time_delta = value - rtc_r;
33
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
34
} else {
35
if (size == 4) {
36
/* time_hi for RV32/RV64 */
37
- mtimer->time_delta = (value << 32 | (rtc_r & 0xFFFFFFFF)) - rtc_r;
38
+ mtimer->time_delta = (value << 32 | (rtc & 0xFFFFFFFF)) - rtc_r;
39
} else {
40
qemu_log_mask(LOG_GUEST_ERROR,
41
"aclint-mtimer: invalid time_hi write: %08x",
42
--
43
2.41.0
diff view generated by jsdifflib
New patch
1
From: Jason Chien <jason.chien@sifive.com>
1
2
3
The variables whose values are given by cpu_riscv_read_rtc() should be named
4
"rtc". The variables whose value are given by cpu_riscv_read_rtc_raw()
5
should be named "rtc_r".
6
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20230728082502.26439-2-jason.chien@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
hw/intc/riscv_aclint.c | 6 +++---
13
1 file changed, 3 insertions(+), 3 deletions(-)
14
15
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/riscv_aclint.c
18
+++ b/hw/intc/riscv_aclint.c
19
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
20
uint64_t next;
21
uint64_t diff;
22
23
- uint64_t rtc_r = cpu_riscv_read_rtc(mtimer);
24
+ uint64_t rtc = cpu_riscv_read_rtc(mtimer);
25
26
/* Compute the relative hartid w.r.t the socket */
27
hartid = hartid - mtimer->hartid_base;
28
29
mtimer->timecmp[hartid] = value;
30
- if (mtimer->timecmp[hartid] <= rtc_r) {
31
+ if (mtimer->timecmp[hartid] <= rtc) {
32
/*
33
* If we're setting an MTIMECMP value in the "past",
34
* immediately raise the timer interrupt
35
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
36
37
/* otherwise, set up the future timer interrupt */
38
qemu_irq_lower(mtimer->timer_irqs[hartid]);
39
- diff = mtimer->timecmp[hartid] - rtc_r;
40
+ diff = mtimer->timecmp[hartid] - rtc;
41
/* back to ns (note args switched in muldiv64) */
42
uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
43
44
--
45
2.41.0
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
2
3
We should not use types dependend on host arch for target_ucontext.
4
This bug is found when run rv32 applications.
5
6
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-ID: <20230811055438.1945-1-zhiwei_liu@linux.alibaba.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
linux-user/riscv/signal.c | 4 ++--
14
1 file changed, 2 insertions(+), 2 deletions(-)
15
16
diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/linux-user/riscv/signal.c
19
+++ b/linux-user/riscv/signal.c
20
@@ -XXX,XX +XXX,XX @@ struct target_sigcontext {
21
}; /* cf. riscv-linux:arch/riscv/include/uapi/asm/ptrace.h */
22
23
struct target_ucontext {
24
- unsigned long uc_flags;
25
- struct target_ucontext *uc_link;
26
+ abi_ulong uc_flags;
27
+ abi_ptr uc_link;
28
target_stack_t uc_stack;
29
target_sigset_t uc_sigmask;
30
uint8_t __unused[1024 / 8 - sizeof(target_sigset_t)];
31
--
32
2.41.0
33
34
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
create_fdt_socket_cpus() writes a different 'mmu-type' value if we're
3
In this patch, we create the APLIC and IMSIC FDT helper functions and
4
running in 32 or 64 bits. However, the flag is being calculated during
4
remove M mode AIA devices when using KVM acceleration.
5
virt_machine_init(), and is passed around in create_fdt(), then
6
create_fdt_socket(), and then finally create_fdt_socket_cpus(). None of
7
the intermediate functions are using the flag, which is a bit
8
misleading.
9
5
10
Remove 'is_32_bit' flag from create_fdt_socket_cpus() and calculate it
6
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
11
using the already available RISCVVirtState pointer. This will also
7
Reviewed-by: Jim Shu <jim.shu@sifive.com>
12
change the signature of create_fdt_socket() and create_fdt(), making it
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
clear that these functions don't do anything special when we're running
9
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
14
in 32 bit mode.
10
Message-ID: <20230727102439.22554-2-yongxuan.wang@sifive.com>
15
16
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
19
Message-Id: <20230111170948.316276-5-dbarboza@ventanamicro.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
12
---
22
hw/riscv/virt.c | 18 +++++++++---------
13
hw/riscv/virt.c | 290 +++++++++++++++++++++++-------------------------
23
1 file changed, 9 insertions(+), 9 deletions(-)
14
1 file changed, 137 insertions(+), 153 deletions(-)
24
15
25
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
16
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
26
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/riscv/virt.c
18
--- a/hw/riscv/virt.c
28
+++ b/hw/riscv/virt.c
19
+++ b/hw/riscv/virt.c
29
@@ -XXX,XX +XXX,XX @@ static void create_pcie_irq_map(RISCVVirtState *s, void *fdt, char *nodename,
20
@@ -XXX,XX +XXX,XX @@ static uint32_t imsic_num_bits(uint32_t count)
30
21
return ret;
31
static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
22
}
32
char *clust_name, uint32_t *phandle,
23
33
- bool is_32_bit, uint32_t *intc_phandles)
24
-static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
34
+ uint32_t *intc_phandles)
25
- uint32_t *phandle, uint32_t *intc_phandles,
26
- uint32_t *msi_m_phandle, uint32_t *msi_s_phandle)
27
+static void create_fdt_one_imsic(RISCVVirtState *s, hwaddr base_addr,
28
+ uint32_t *intc_phandles, uint32_t msi_phandle,
29
+ bool m_mode, uint32_t imsic_guest_bits)
30
{
31
int cpu, socket;
32
char *imsic_name;
33
MachineState *ms = MACHINE(s);
34
int socket_count = riscv_socket_count(ms);
35
- uint32_t imsic_max_hart_per_socket, imsic_guest_bits;
36
+ uint32_t imsic_max_hart_per_socket;
37
uint32_t *imsic_cells, *imsic_regs, imsic_addr, imsic_size;
38
39
- *msi_m_phandle = (*phandle)++;
40
- *msi_s_phandle = (*phandle)++;
41
imsic_cells = g_new0(uint32_t, ms->smp.cpus * 2);
42
imsic_regs = g_new0(uint32_t, socket_count * 4);
43
44
- /* M-level IMSIC node */
45
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
46
imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
47
- imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
48
+ imsic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
49
}
50
- imsic_max_hart_per_socket = 0;
51
- for (socket = 0; socket < socket_count; socket++) {
52
- imsic_addr = memmap[VIRT_IMSIC_M].base +
53
- socket * VIRT_IMSIC_GROUP_MAX_SIZE;
54
- imsic_size = IMSIC_HART_SIZE(0) * s->soc[socket].num_harts;
55
- imsic_regs[socket * 4 + 0] = 0;
56
- imsic_regs[socket * 4 + 1] = cpu_to_be32(imsic_addr);
57
- imsic_regs[socket * 4 + 2] = 0;
58
- imsic_regs[socket * 4 + 3] = cpu_to_be32(imsic_size);
59
- if (imsic_max_hart_per_socket < s->soc[socket].num_harts) {
60
- imsic_max_hart_per_socket = s->soc[socket].num_harts;
61
- }
62
- }
63
- imsic_name = g_strdup_printf("/soc/imsics@%lx",
64
- (unsigned long)memmap[VIRT_IMSIC_M].base);
65
- qemu_fdt_add_subnode(ms->fdt, imsic_name);
66
- qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
67
- "riscv,imsics");
68
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
69
- FDT_IMSIC_INT_CELLS);
70
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
71
- NULL, 0);
72
- qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
73
- NULL, 0);
74
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
75
- imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
76
- qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
77
- socket_count * sizeof(uint32_t) * 4);
78
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
79
- VIRT_IRQCHIP_NUM_MSIS);
80
- if (socket_count > 1) {
81
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
82
- imsic_num_bits(imsic_max_hart_per_socket));
83
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
84
- imsic_num_bits(socket_count));
85
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
86
- IMSIC_MMIO_GROUP_MIN_SHIFT);
87
- }
88
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_m_phandle);
89
-
90
- g_free(imsic_name);
91
92
- /* S-level IMSIC node */
93
- for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
94
- imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
95
- imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
96
- }
97
- imsic_guest_bits = imsic_num_bits(s->aia_guests + 1);
98
imsic_max_hart_per_socket = 0;
99
for (socket = 0; socket < socket_count; socket++) {
100
- imsic_addr = memmap[VIRT_IMSIC_S].base +
101
- socket * VIRT_IMSIC_GROUP_MAX_SIZE;
102
+ imsic_addr = base_addr + socket * VIRT_IMSIC_GROUP_MAX_SIZE;
103
imsic_size = IMSIC_HART_SIZE(imsic_guest_bits) *
104
s->soc[socket].num_harts;
105
imsic_regs[socket * 4 + 0] = 0;
106
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
107
imsic_max_hart_per_socket = s->soc[socket].num_harts;
108
}
109
}
110
- imsic_name = g_strdup_printf("/soc/imsics@%lx",
111
- (unsigned long)memmap[VIRT_IMSIC_S].base);
112
+
113
+ imsic_name = g_strdup_printf("/soc/imsics@%lx", (unsigned long)base_addr);
114
qemu_fdt_add_subnode(ms->fdt, imsic_name);
115
- qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
116
- "riscv,imsics");
117
+ qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible", "riscv,imsics");
118
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
119
- FDT_IMSIC_INT_CELLS);
120
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
121
- NULL, 0);
122
- qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
123
- NULL, 0);
124
+ FDT_IMSIC_INT_CELLS);
125
+ qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller", NULL, 0);
126
+ qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller", NULL, 0);
127
qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
128
- imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
129
+ imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
130
qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
131
- socket_count * sizeof(uint32_t) * 4);
132
+ socket_count * sizeof(uint32_t) * 4);
133
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
134
- VIRT_IRQCHIP_NUM_MSIS);
135
+ VIRT_IRQCHIP_NUM_MSIS);
136
+
137
if (imsic_guest_bits) {
138
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,guest-index-bits",
139
- imsic_guest_bits);
140
+ imsic_guest_bits);
141
}
142
+
143
if (socket_count > 1) {
144
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
145
- imsic_num_bits(imsic_max_hart_per_socket));
146
+ imsic_num_bits(imsic_max_hart_per_socket));
147
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
148
- imsic_num_bits(socket_count));
149
+ imsic_num_bits(socket_count));
150
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
151
- IMSIC_MMIO_GROUP_MIN_SHIFT);
152
+ IMSIC_MMIO_GROUP_MIN_SHIFT);
153
}
154
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_s_phandle);
155
- g_free(imsic_name);
156
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", msi_phandle);
157
158
+ g_free(imsic_name);
159
g_free(imsic_regs);
160
g_free(imsic_cells);
161
}
162
163
-static void create_fdt_socket_aplic(RISCVVirtState *s,
164
- const MemMapEntry *memmap, int socket,
165
- uint32_t msi_m_phandle,
166
- uint32_t msi_s_phandle,
167
- uint32_t *phandle,
168
- uint32_t *intc_phandles,
169
- uint32_t *aplic_phandles)
170
+static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
171
+ uint32_t *phandle, uint32_t *intc_phandles,
172
+ uint32_t *msi_m_phandle, uint32_t *msi_s_phandle)
173
+{
174
+ *msi_m_phandle = (*phandle)++;
175
+ *msi_s_phandle = (*phandle)++;
176
+
177
+ if (!kvm_enabled()) {
178
+ /* M-level IMSIC node */
179
+ create_fdt_one_imsic(s, memmap[VIRT_IMSIC_M].base, intc_phandles,
180
+ *msi_m_phandle, true, 0);
181
+ }
182
+
183
+ /* S-level IMSIC node */
184
+ create_fdt_one_imsic(s, memmap[VIRT_IMSIC_S].base, intc_phandles,
185
+ *msi_s_phandle, false,
186
+ imsic_num_bits(s->aia_guests + 1));
187
+
188
+}
189
+
190
+static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
191
+ unsigned long aplic_addr, uint32_t aplic_size,
192
+ uint32_t msi_phandle,
193
+ uint32_t *intc_phandles,
194
+ uint32_t aplic_phandle,
195
+ uint32_t aplic_child_phandle,
196
+ bool m_mode)
35
{
197
{
36
int cpu;
198
int cpu;
37
uint32_t cpu_phandle;
199
char *aplic_name;
38
MachineState *mc = MACHINE(s);
200
uint32_t *aplic_cells;
39
char *name, *cpu_name, *core_name, *intc_name;
201
- unsigned long aplic_addr;
40
+ bool is_32_bit = riscv_is_32bit(&s->soc[0]);
202
MachineState *ms = MACHINE(s);
41
203
- uint32_t aplic_m_phandle, aplic_s_phandle;
42
for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) {
204
43
cpu_phandle = (*phandle)++;
205
- aplic_m_phandle = (*phandle)++;
44
@@ -XXX,XX +XXX,XX @@ static void create_fdt_pmu(RISCVVirtState *s)
206
- aplic_s_phandle = (*phandle)++;
207
aplic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
208
209
- /* M-level APLIC node */
210
for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
211
aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
212
- aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
213
+ aplic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
214
}
215
- aplic_addr = memmap[VIRT_APLIC_M].base +
216
- (memmap[VIRT_APLIC_M].size * socket);
217
+
218
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
219
qemu_fdt_add_subnode(ms->fdt, aplic_name);
220
qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
221
qemu_fdt_setprop_cell(ms->fdt, aplic_name,
222
- "#interrupt-cells", FDT_APLIC_INT_CELLS);
223
+ "#interrupt-cells", FDT_APLIC_INT_CELLS);
224
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
225
+
226
if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
227
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
228
- aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2);
229
+ aplic_cells,
230
+ s->soc[socket].num_harts * sizeof(uint32_t) * 2);
231
} else {
232
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent",
233
- msi_m_phandle);
234
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent", msi_phandle);
235
}
236
+
237
qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
238
- 0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_M].size);
239
+ 0x0, aplic_addr, 0x0, aplic_size);
240
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
241
- VIRT_IRQCHIP_NUM_SOURCES);
242
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,children",
243
- aplic_s_phandle);
244
- qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate",
245
- aplic_s_phandle, 0x1, VIRT_IRQCHIP_NUM_SOURCES);
246
+ VIRT_IRQCHIP_NUM_SOURCES);
247
+
248
+ if (aplic_child_phandle) {
249
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,children",
250
+ aplic_child_phandle);
251
+ qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate",
252
+ aplic_child_phandle, 0x1,
253
+ VIRT_IRQCHIP_NUM_SOURCES);
254
+ }
255
+
256
riscv_socket_fdt_write_id(ms, aplic_name, socket);
257
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_m_phandle);
258
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_phandle);
259
+
260
g_free(aplic_name);
261
+ g_free(aplic_cells);
262
+}
263
264
- /* S-level APLIC node */
265
- for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
266
- aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
267
- aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
268
+static void create_fdt_socket_aplic(RISCVVirtState *s,
269
+ const MemMapEntry *memmap, int socket,
270
+ uint32_t msi_m_phandle,
271
+ uint32_t msi_s_phandle,
272
+ uint32_t *phandle,
273
+ uint32_t *intc_phandles,
274
+ uint32_t *aplic_phandles)
275
+{
276
+ char *aplic_name;
277
+ unsigned long aplic_addr;
278
+ MachineState *ms = MACHINE(s);
279
+ uint32_t aplic_m_phandle, aplic_s_phandle;
280
+
281
+ aplic_m_phandle = (*phandle)++;
282
+ aplic_s_phandle = (*phandle)++;
283
+
284
+ if (!kvm_enabled()) {
285
+ /* M-level APLIC node */
286
+ aplic_addr = memmap[VIRT_APLIC_M].base +
287
+ (memmap[VIRT_APLIC_M].size * socket);
288
+ create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_M].size,
289
+ msi_m_phandle, intc_phandles,
290
+ aplic_m_phandle, aplic_s_phandle,
291
+ true);
292
}
293
+
294
+ /* S-level APLIC node */
295
aplic_addr = memmap[VIRT_APLIC_S].base +
296
(memmap[VIRT_APLIC_S].size * socket);
297
+ create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_S].size,
298
+ msi_s_phandle, intc_phandles,
299
+ aplic_s_phandle, 0,
300
+ false);
301
+
302
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
303
- qemu_fdt_add_subnode(ms->fdt, aplic_name);
304
- qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
305
- qemu_fdt_setprop_cell(ms->fdt, aplic_name,
306
- "#interrupt-cells", FDT_APLIC_INT_CELLS);
307
- qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
308
- if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
309
- qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
310
- aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2);
311
- } else {
312
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent",
313
- msi_s_phandle);
314
- }
315
- qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
316
- 0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_S].size);
317
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
318
- VIRT_IRQCHIP_NUM_SOURCES);
319
- riscv_socket_fdt_write_id(ms, aplic_name, socket);
320
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_s_phandle);
321
322
if (!socket) {
323
platform_bus_add_all_fdt_nodes(ms->fdt, aplic_name,
324
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
325
326
g_free(aplic_name);
327
328
- g_free(aplic_cells);
329
aplic_phandles[socket] = aplic_s_phandle;
45
}
330
}
46
331
47
static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
332
@@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
48
- bool is_32_bit, uint32_t *phandle,
333
int i;
49
+ uint32_t *phandle,
334
hwaddr addr;
50
uint32_t *irq_mmio_phandle,
335
uint32_t guest_bits;
51
uint32_t *irq_pcie_phandle,
336
- DeviceState *aplic_m;
52
uint32_t *irq_virtio_phandle,
337
- bool msimode = (aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) ? true : false;
53
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
338
+ DeviceState *aplic_s = NULL;
54
qemu_fdt_add_subnode(mc->fdt, clust_name);
339
+ DeviceState *aplic_m = NULL;
55
340
+ bool msimode = aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
56
create_fdt_socket_cpus(s, socket, clust_name, phandle,
341
57
- is_32_bit, &intc_phandles[phandle_pos]);
342
if (msimode) {
58
+ &intc_phandles[phandle_pos]);
343
- /* Per-socket M-level IMSICs */
59
344
- addr = memmap[VIRT_IMSIC_M].base + socket * VIRT_IMSIC_GROUP_MAX_SIZE;
60
create_fdt_socket_memory(s, memmap, socket);
345
- for (i = 0; i < hart_count; i++) {
61
346
- riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0),
62
@@ -XXX,XX +XXX,XX @@ static void create_fdt_fw_cfg(RISCVVirtState *s, const MemMapEntry *memmap)
347
- base_hartid + i, true, 1,
63
g_free(nodename);
348
- VIRT_IRQCHIP_NUM_MSIS);
349
+ if (!kvm_enabled()) {
350
+ /* Per-socket M-level IMSICs */
351
+ addr = memmap[VIRT_IMSIC_M].base +
352
+ socket * VIRT_IMSIC_GROUP_MAX_SIZE;
353
+ for (i = 0; i < hart_count; i++) {
354
+ riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0),
355
+ base_hartid + i, true, 1,
356
+ VIRT_IRQCHIP_NUM_MSIS);
357
+ }
358
}
359
360
/* Per-socket S-level IMSICs */
361
@@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
362
}
363
}
364
365
- /* Per-socket M-level APLIC */
366
- aplic_m = riscv_aplic_create(
367
- memmap[VIRT_APLIC_M].base + socket * memmap[VIRT_APLIC_M].size,
368
- memmap[VIRT_APLIC_M].size,
369
- (msimode) ? 0 : base_hartid,
370
- (msimode) ? 0 : hart_count,
371
- VIRT_IRQCHIP_NUM_SOURCES,
372
- VIRT_IRQCHIP_NUM_PRIO_BITS,
373
- msimode, true, NULL);
374
-
375
- if (aplic_m) {
376
- /* Per-socket S-level APLIC */
377
- riscv_aplic_create(
378
- memmap[VIRT_APLIC_S].base + socket * memmap[VIRT_APLIC_S].size,
379
- memmap[VIRT_APLIC_S].size,
380
- (msimode) ? 0 : base_hartid,
381
- (msimode) ? 0 : hart_count,
382
- VIRT_IRQCHIP_NUM_SOURCES,
383
- VIRT_IRQCHIP_NUM_PRIO_BITS,
384
- msimode, false, aplic_m);
385
+ if (!kvm_enabled()) {
386
+ /* Per-socket M-level APLIC */
387
+ aplic_m = riscv_aplic_create(memmap[VIRT_APLIC_M].base +
388
+ socket * memmap[VIRT_APLIC_M].size,
389
+ memmap[VIRT_APLIC_M].size,
390
+ (msimode) ? 0 : base_hartid,
391
+ (msimode) ? 0 : hart_count,
392
+ VIRT_IRQCHIP_NUM_SOURCES,
393
+ VIRT_IRQCHIP_NUM_PRIO_BITS,
394
+ msimode, true, NULL);
395
}
396
397
- return aplic_m;
398
+ /* Per-socket S-level APLIC */
399
+ aplic_s = riscv_aplic_create(memmap[VIRT_APLIC_S].base +
400
+ socket * memmap[VIRT_APLIC_S].size,
401
+ memmap[VIRT_APLIC_S].size,
402
+ (msimode) ? 0 : base_hartid,
403
+ (msimode) ? 0 : hart_count,
404
+ VIRT_IRQCHIP_NUM_SOURCES,
405
+ VIRT_IRQCHIP_NUM_PRIO_BITS,
406
+ msimode, false, aplic_m);
407
+
408
+ return kvm_enabled() ? aplic_s : aplic_m;
64
}
409
}
65
410
66
-static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
411
static void create_platform_bus(RISCVVirtState *s, DeviceState *irqchip)
67
- bool is_32_bit)
68
+static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap)
69
{
70
MachineState *mc = MACHINE(s);
71
uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1;
72
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
73
qemu_fdt_setprop_cell(mc->fdt, "/soc", "#size-cells", 0x2);
74
qemu_fdt_setprop_cell(mc->fdt, "/soc", "#address-cells", 0x2);
75
76
- create_fdt_sockets(s, memmap, is_32_bit, &phandle,
77
- &irq_mmio_phandle, &irq_pcie_phandle, &irq_virtio_phandle,
78
- &msi_pcie_phandle);
79
+ create_fdt_sockets(s, memmap, &phandle, &irq_mmio_phandle,
80
+ &irq_pcie_phandle, &irq_virtio_phandle,
81
+ &msi_pcie_phandle);
82
83
create_fdt_virtio(s, memmap, irq_virtio_phandle);
84
85
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
86
virt_flash_map(s, system_memory);
87
88
/* create device tree */
89
- create_fdt(s, memmap, riscv_is_32bit(&s->soc[0]));
90
+ create_fdt(s, memmap);
91
92
s->machine_done.notify = virt_machine_done;
93
qemu_add_machine_init_done_notifier(&s->machine_done);
94
--
412
--
95
2.39.0
413
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
The sifive_u, spike and virt machines are writing the 'bootargs' FDT
3
We check the in-kernel irqchip support when using KVM acceleration.
4
node during their respective create_fdt().
5
4
6
Given that bootargs is written only when '-append' is used, and this
5
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
7
option is only allowed with the '-kernel' option, which in turn is
6
Reviewed-by: Jim Shu <jim.shu@sifive.com>
8
already being check before executing riscv_load_kernel(), write
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
'bootargs' in the same code path as riscv_load_kernel().
8
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
10
9
Message-ID: <20230727102439.22554-3-yongxuan.wang@sifive.com>
11
Cc: Palmer Dabbelt <palmer@dabbelt.com>
12
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Reviewed-by: Bin Meng <bmeng@tinylab.org>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-Id: <20230102115241.25733-8-dbarboza@ventanamicro.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
11
---
19
hw/riscv/sifive_u.c | 11 +++++------
12
target/riscv/kvm.c | 10 +++++++++-
20
hw/riscv/spike.c | 9 +++++----
13
1 file changed, 9 insertions(+), 1 deletion(-)
21
hw/riscv/virt.c | 11 +++++------
22
3 files changed, 15 insertions(+), 16 deletions(-)
23
14
24
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
15
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
25
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/riscv/sifive_u.c
17
--- a/target/riscv/kvm.c
27
+++ b/hw/riscv/sifive_u.c
18
+++ b/target/riscv/kvm.c
28
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
19
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
29
error_report("load_device_tree() failed");
20
30
exit(1);
21
int kvm_arch_irqchip_create(KVMState *s)
31
}
22
{
32
- goto update_bootargs;
23
- return 0;
33
} else {
24
+ if (kvm_kernel_irqchip_split()) {
34
fdt = ms->fdt = create_device_tree(&fdt_size);
25
+ error_report("-machine kernel_irqchip=split is not supported on RISC-V.");
35
if (!fdt) {
26
+ exit(1);
36
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
27
+ }
37
qemu_fdt_setprop_string(fdt, "/aliases", "serial0", nodename);
28
+
38
29
+ /*
39
g_free(nodename);
30
+ * We can create the VAIA using the newer device control API.
40
-
31
+ */
41
-update_bootargs:
32
+ return kvm_check_extension(s, KVM_CAP_DEVICE_CTRL);
42
- if (cmdline && *cmdline) {
43
- qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
44
- }
45
}
33
}
46
34
47
static void sifive_u_machine_reset(void *opaque, int n, int level)
35
int kvm_arch_process_async_events(CPUState *cs)
48
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
49
riscv_load_initrd(machine->initrd_filename, machine->ram_size,
50
kernel_entry, machine->fdt);
51
}
52
+
53
+ if (machine->kernel_cmdline && *machine->kernel_cmdline) {
54
+ qemu_fdt_setprop_string(machine->fdt, "/chosen", "bootargs",
55
+ machine->kernel_cmdline);
56
+ }
57
} else {
58
/*
59
* If dynamic firmware is used, it doesn't know where is the next mode
60
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/riscv/spike.c
63
+++ b/hw/riscv/spike.c
64
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
65
66
qemu_fdt_add_subnode(fdt, "/chosen");
67
qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", "/htif");
68
-
69
- if (cmdline && *cmdline) {
70
- qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
71
- }
72
}
73
74
static bool spike_test_elf_image(char *filename)
75
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
76
riscv_load_initrd(machine->initrd_filename, machine->ram_size,
77
kernel_entry, machine->fdt);
78
}
79
+
80
+ if (machine->kernel_cmdline && *machine->kernel_cmdline) {
81
+ qemu_fdt_setprop_string(machine->fdt, "/chosen", "bootargs",
82
+ machine->kernel_cmdline);
83
+ }
84
} else {
85
/*
86
* If dynamic firmware is used, it doesn't know where is the next mode
87
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/riscv/virt.c
90
+++ b/hw/riscv/virt.c
91
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
92
error_report("load_device_tree() failed");
93
exit(1);
94
}
95
- goto update_bootargs;
96
} else {
97
mc->fdt = create_device_tree(&s->fdt_size);
98
if (!mc->fdt) {
99
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
100
create_fdt_fw_cfg(s, memmap);
101
create_fdt_pmu(s);
102
103
-update_bootargs:
104
- if (cmdline && *cmdline) {
105
- qemu_fdt_setprop_string(mc->fdt, "/chosen", "bootargs", cmdline);
106
- }
107
-
108
/* Pass seed to RNG */
109
qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
110
qemu_fdt_setprop(mc->fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed));
111
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
112
riscv_load_initrd(machine->initrd_filename, machine->ram_size,
113
kernel_entry, machine->fdt);
114
}
115
+
116
+ if (machine->kernel_cmdline && *machine->kernel_cmdline) {
117
+ qemu_fdt_setprop_string(machine->fdt, "/chosen", "bootargs",
118
+ machine->kernel_cmdline);
119
+ }
120
} else {
121
/*
122
* If dynamic firmware is used, it doesn't know where is the next mode
123
--
36
--
124
2.39.0
37
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
struct HTIFState has 3 members for address space and memory region,
3
We create a vAIA chip by using the KVM_DEV_TYPE_RISCV_AIA and then set up
4
and are initialized during htif_mm_init(). But they are actually
4
the chip with the KVM_DEV_RISCV_AIA_GRP_* APIs.
5
useless. Drop them.
5
We also extend KVM accelerator to specify the KVM AIA mode. The "riscv-aia"
6
parameter is passed along with --accel in QEMU command-line.
7
1) "riscv-aia=emul": IMSIC is emulated by hypervisor
8
2) "riscv-aia=hwaccel": use hardware guest IMSIC
9
3) "riscv-aia=auto": use the hardware guest IMSICs whenever available
10
otherwise we fallback to software emulation.
6
11
7
Signed-off-by: Bin Meng <bmeng@tinylab.org>
12
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
13
Reviewed-by: Jim Shu <jim.shu@sifive.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
10
Message-Id: <20221229091828.1945072-4-bmeng@tinylab.org>
16
Message-ID: <20230727102439.22554-4-yongxuan.wang@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
18
---
13
include/hw/char/riscv_htif.h | 7 ++-----
19
target/riscv/kvm_riscv.h | 4 +
14
hw/char/riscv_htif.c | 7 ++-----
20
target/riscv/kvm.c | 186 +++++++++++++++++++++++++++++++++++++++
15
hw/riscv/spike.c | 5 ++---
21
2 files changed, 190 insertions(+)
16
3 files changed, 6 insertions(+), 13 deletions(-)
17
22
18
diff --git a/include/hw/char/riscv_htif.h b/include/hw/char/riscv_htif.h
23
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
19
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/char/riscv_htif.h
25
--- a/target/riscv/kvm_riscv.h
21
+++ b/include/hw/char/riscv_htif.h
26
+++ b/target/riscv/kvm_riscv.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct HTIFState {
27
@@ -XXX,XX +XXX,XX @@
23
hwaddr tohost_offset;
28
void kvm_riscv_init_user_properties(Object *cpu_obj);
24
hwaddr fromhost_offset;
29
void kvm_riscv_reset_vcpu(RISCVCPU *cpu);
25
MemoryRegion mmio;
30
void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level);
26
- MemoryRegion *address_space;
31
+void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
27
- MemoryRegion *main_mem;
32
+ uint64_t aia_irq_num, uint64_t aia_msi_num,
28
- void *main_mem_ram_ptr;
33
+ uint64_t aplic_base, uint64_t imsic_base,
29
34
+ uint64_t guest_num);
30
CPURISCVState *env;
31
CharBackend chr;
32
@@ -XXX,XX +XXX,XX @@ void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value,
33
bool htif_uses_elf_symbols(void);
34
35
/* legacy pre qom */
36
-HTIFState *htif_mm_init(MemoryRegion *address_space, MemoryRegion *main_mem,
37
- CPURISCVState *env, Chardev *chr, uint64_t nonelf_base);
38
+HTIFState *htif_mm_init(MemoryRegion *address_space, CPURISCVState *env,
39
+ Chardev *chr, uint64_t nonelf_base);
40
35
41
#endif
36
#endif
42
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
37
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
43
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/char/riscv_htif.c
39
--- a/target/riscv/kvm.c
45
+++ b/hw/char/riscv_htif.c
40
+++ b/target/riscv/kvm.c
46
@@ -XXX,XX +XXX,XX @@ bool htif_uses_elf_symbols(void)
41
@@ -XXX,XX +XXX,XX @@
47
return (address_symbol_set == 3) ? true : false;
42
#include "exec/address-spaces.h"
43
#include "hw/boards.h"
44
#include "hw/irq.h"
45
+#include "hw/intc/riscv_imsic.h"
46
#include "qemu/log.h"
47
#include "hw/loader.h"
48
#include "kvm_riscv.h"
49
@@ -XXX,XX +XXX,XX @@
50
#include "chardev/char-fe.h"
51
#include "migration/migration.h"
52
#include "sysemu/runstate.h"
53
+#include "hw/riscv/numa.h"
54
55
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
56
uint64_t idx)
57
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_cpu_check_are_resettable(void)
58
return true;
48
}
59
}
49
60
50
-HTIFState *htif_mm_init(MemoryRegion *address_space, MemoryRegion *main_mem,
61
+static int aia_mode;
51
- CPURISCVState *env, Chardev *chr, uint64_t nonelf_base)
62
+
52
+HTIFState *htif_mm_init(MemoryRegion *address_space, CPURISCVState *env,
63
+static const char *kvm_aia_mode_str(uint64_t mode)
53
+ Chardev *chr, uint64_t nonelf_base)
64
+{
65
+ switch (mode) {
66
+ case KVM_DEV_RISCV_AIA_MODE_EMUL:
67
+ return "emul";
68
+ case KVM_DEV_RISCV_AIA_MODE_HWACCEL:
69
+ return "hwaccel";
70
+ case KVM_DEV_RISCV_AIA_MODE_AUTO:
71
+ default:
72
+ return "auto";
73
+ };
74
+}
75
+
76
+static char *riscv_get_kvm_aia(Object *obj, Error **errp)
77
+{
78
+ return g_strdup(kvm_aia_mode_str(aia_mode));
79
+}
80
+
81
+static void riscv_set_kvm_aia(Object *obj, const char *val, Error **errp)
82
+{
83
+ if (!strcmp(val, "emul")) {
84
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_EMUL;
85
+ } else if (!strcmp(val, "hwaccel")) {
86
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_HWACCEL;
87
+ } else if (!strcmp(val, "auto")) {
88
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_AUTO;
89
+ } else {
90
+ error_setg(errp, "Invalid KVM AIA mode");
91
+ error_append_hint(errp, "Valid values are emul, hwaccel, and auto.\n");
92
+ }
93
+}
94
+
95
void kvm_arch_accel_class_init(ObjectClass *oc)
54
{
96
{
55
uint64_t base, size, tohost_offset, fromhost_offset;
97
+ object_class_property_add_str(oc, "riscv-aia", riscv_get_kvm_aia,
56
98
+ riscv_set_kvm_aia);
57
@@ -XXX,XX +XXX,XX @@ HTIFState *htif_mm_init(MemoryRegion *address_space, MemoryRegion *main_mem,
99
+ object_class_property_set_description(oc, "riscv-aia",
58
fromhost_offset = fromhost_addr - base;
100
+ "Set KVM AIA mode. Valid values are "
59
101
+ "emul, hwaccel, and auto. Default "
60
HTIFState *s = g_new0(HTIFState, 1);
102
+ "is auto.");
61
- s->address_space = address_space;
103
+ object_property_set_default_str(object_class_property_find(oc, "riscv-aia"),
62
- s->main_mem = main_mem;
104
+ "auto");
63
- s->main_mem_ram_ptr = memory_region_get_ram_ptr(main_mem);
105
+}
64
s->env = env;
106
+
65
s->tohost_offset = tohost_offset;
107
+void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
66
s->fromhost_offset = fromhost_offset;
108
+ uint64_t aia_irq_num, uint64_t aia_msi_num,
67
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
109
+ uint64_t aplic_base, uint64_t imsic_base,
68
index XXXXXXX..XXXXXXX 100644
110
+ uint64_t guest_num)
69
--- a/hw/riscv/spike.c
111
+{
70
+++ b/hw/riscv/spike.c
112
+ int ret, i;
71
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
113
+ int aia_fd = -1;
72
fdt_load_addr);
114
+ uint64_t default_aia_mode;
73
115
+ uint64_t socket_count = riscv_socket_count(machine);
74
/* initialize HTIF using symbols found in load_kernel */
116
+ uint64_t max_hart_per_socket = 0;
75
- htif_mm_init(system_memory, mask_rom,
117
+ uint64_t socket, base_hart, hart_count, socket_imsic_base, imsic_addr;
76
- &s->soc[0].harts[0].env, serial_hd(0),
118
+ uint64_t socket_bits, hart_bits, guest_bits;
77
- memmap[SPIKE_HTIF].base);
119
+
78
+ htif_mm_init(system_memory, &s->soc[0].harts[0].env,
120
+ aia_fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_RISCV_AIA, false);
79
+ serial_hd(0), memmap[SPIKE_HTIF].base);
121
+
122
+ if (aia_fd < 0) {
123
+ error_report("Unable to create in-kernel irqchip");
124
+ exit(1);
125
+ }
126
+
127
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
128
+ KVM_DEV_RISCV_AIA_CONFIG_MODE,
129
+ &default_aia_mode, false, NULL);
130
+ if (ret < 0) {
131
+ error_report("KVM AIA: failed to get current KVM AIA mode");
132
+ exit(1);
133
+ }
134
+ qemu_log("KVM AIA: default mode is %s\n",
135
+ kvm_aia_mode_str(default_aia_mode));
136
+
137
+ if (default_aia_mode != aia_mode) {
138
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
139
+ KVM_DEV_RISCV_AIA_CONFIG_MODE,
140
+ &aia_mode, true, NULL);
141
+ if (ret < 0)
142
+ warn_report("KVM AIA: failed to set KVM AIA mode");
143
+ else
144
+ qemu_log("KVM AIA: set current mode to %s\n",
145
+ kvm_aia_mode_str(aia_mode));
146
+ }
147
+
148
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
149
+ KVM_DEV_RISCV_AIA_CONFIG_SRCS,
150
+ &aia_irq_num, true, NULL);
151
+ if (ret < 0) {
152
+ error_report("KVM AIA: failed to set number of input irq lines");
153
+ exit(1);
154
+ }
155
+
156
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
157
+ KVM_DEV_RISCV_AIA_CONFIG_IDS,
158
+ &aia_msi_num, true, NULL);
159
+ if (ret < 0) {
160
+ error_report("KVM AIA: failed to set number of msi");
161
+ exit(1);
162
+ }
163
+
164
+ socket_bits = find_last_bit(&socket_count, BITS_PER_LONG) + 1;
165
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
166
+ KVM_DEV_RISCV_AIA_CONFIG_GROUP_BITS,
167
+ &socket_bits, true, NULL);
168
+ if (ret < 0) {
169
+ error_report("KVM AIA: failed to set group_bits");
170
+ exit(1);
171
+ }
172
+
173
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
174
+ KVM_DEV_RISCV_AIA_CONFIG_GROUP_SHIFT,
175
+ &group_shift, true, NULL);
176
+ if (ret < 0) {
177
+ error_report("KVM AIA: failed to set group_shift");
178
+ exit(1);
179
+ }
180
+
181
+ guest_bits = guest_num == 0 ? 0 :
182
+ find_last_bit(&guest_num, BITS_PER_LONG) + 1;
183
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
184
+ KVM_DEV_RISCV_AIA_CONFIG_GUEST_BITS,
185
+ &guest_bits, true, NULL);
186
+ if (ret < 0) {
187
+ error_report("KVM AIA: failed to set guest_bits");
188
+ exit(1);
189
+ }
190
+
191
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_ADDR,
192
+ KVM_DEV_RISCV_AIA_ADDR_APLIC,
193
+ &aplic_base, true, NULL);
194
+ if (ret < 0) {
195
+ error_report("KVM AIA: failed to set the base address of APLIC");
196
+ exit(1);
197
+ }
198
+
199
+ for (socket = 0; socket < socket_count; socket++) {
200
+ socket_imsic_base = imsic_base + socket * (1U << group_shift);
201
+ hart_count = riscv_socket_hart_count(machine, socket);
202
+ base_hart = riscv_socket_first_hartid(machine, socket);
203
+
204
+ if (max_hart_per_socket < hart_count) {
205
+ max_hart_per_socket = hart_count;
206
+ }
207
+
208
+ for (i = 0; i < hart_count; i++) {
209
+ imsic_addr = socket_imsic_base + i * IMSIC_HART_SIZE(guest_bits);
210
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_ADDR,
211
+ KVM_DEV_RISCV_AIA_ADDR_IMSIC(i + base_hart),
212
+ &imsic_addr, true, NULL);
213
+ if (ret < 0) {
214
+ error_report("KVM AIA: failed to set the IMSIC address for hart %d", i);
215
+ exit(1);
216
+ }
217
+ }
218
+ }
219
+
220
+ hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
221
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
222
+ KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
223
+ &hart_bits, true, NULL);
224
+ if (ret < 0) {
225
+ error_report("KVM AIA: failed to set hart_bits");
226
+ exit(1);
227
+ }
228
+
229
+ if (kvm_has_gsi_routing()) {
230
+ for (uint64_t idx = 0; idx < aia_irq_num + 1; ++idx) {
231
+ /* KVM AIA only has one APLIC instance */
232
+ kvm_irqchip_add_irq_route(kvm_state, idx, 0, idx);
233
+ }
234
+ kvm_gsi_routing_allowed = true;
235
+ kvm_irqchip_commit_routes(kvm_state);
236
+ }
237
+
238
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CTRL,
239
+ KVM_DEV_RISCV_AIA_CTRL_INIT,
240
+ NULL, true, NULL);
241
+ if (ret < 0) {
242
+ error_report("KVM AIA: initialized fail");
243
+ exit(1);
244
+ }
245
+
246
+ kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();
80
}
247
}
81
82
static void spike_machine_instance_init(Object *obj)
83
--
248
--
84
2.39.0
249
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
The MachineState object provides a 'fdt' pointer that is already being
3
KVM AIA can't emulate APLIC only. When "aia=aplic" parameter is passed,
4
used by other RISC-V machines, and it's also used by the 'dumpdtb' QMP
4
APLIC devices is emulated by QEMU. For "aia=aplic-imsic", remove the
5
command.
5
mmio operations of APLIC when using KVM AIA and send wired interrupt
6
signal via KVM_IRQ_LINE API.
7
After KVM AIA enabled, MSI messages are delivered by KVM_SIGNAL_MSI API
8
when the IMSICs receive mmio write requests.
6
9
7
Remove the 'fdt' pointer from SiFiveUState and use MachineState::fdt
10
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
8
instead.
11
Reviewed-by: Jim Shu <jim.shu@sifive.com>
9
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Cc: Palmer Dabbelt <palmer@dabbelt.com>
13
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
11
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
Message-ID: <20230727102439.22554-5-yongxuan.wang@sifive.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Bin Meng <bmeng@tinylab.org>
15
Message-Id: <20230102115241.25733-4-dbarboza@ventanamicro.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
16
---
18
include/hw/riscv/sifive_u.h | 3 ---
17
hw/intc/riscv_aplic.c | 56 ++++++++++++++++++++++++++++++-------------
19
hw/riscv/sifive_u.c | 15 ++++++---------
18
hw/intc/riscv_imsic.c | 25 +++++++++++++++----
20
2 files changed, 6 insertions(+), 12 deletions(-)
19
2 files changed, 61 insertions(+), 20 deletions(-)
21
20
22
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
21
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
23
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/riscv/sifive_u.h
23
--- a/hw/intc/riscv_aplic.c
25
+++ b/include/hw/riscv/sifive_u.h
24
+++ b/hw/intc/riscv_aplic.c
26
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveUState {
25
@@ -XXX,XX +XXX,XX @@
27
/*< public >*/
26
#include "hw/irq.h"
28
SiFiveUSoCState soc;
27
#include "target/riscv/cpu.h"
29
28
#include "sysemu/sysemu.h"
30
- void *fdt;
29
+#include "sysemu/kvm.h"
31
- int fdt_size;
30
#include "migration/vmstate.h"
32
-
31
33
bool start_in_flash;
32
#define APLIC_MAX_IDC (1UL << 14)
34
uint32_t msel;
33
@@ -XXX,XX +XXX,XX @@
35
uint32_t serial;
34
36
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
35
#define APLIC_IDC_CLAIMI 0x1c
36
37
+/*
38
+ * KVM AIA only supports APLIC MSI, fallback to QEMU emulation if we want to use
39
+ * APLIC Wired.
40
+ */
41
+static bool is_kvm_aia(bool msimode)
42
+{
43
+ return kvm_irqchip_in_kernel() && msimode;
44
+}
45
+
46
static uint32_t riscv_aplic_read_input_word(RISCVAPLICState *aplic,
47
uint32_t word)
48
{
49
@@ -XXX,XX +XXX,XX @@ static uint32_t riscv_aplic_idc_claimi(RISCVAPLICState *aplic, uint32_t idc)
50
return topi;
51
}
52
53
+static void riscv_kvm_aplic_request(void *opaque, int irq, int level)
54
+{
55
+ kvm_set_irq(kvm_state, irq, !!level);
56
+}
57
+
58
static void riscv_aplic_request(void *opaque, int irq, int level)
59
{
60
bool update = false;
61
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
62
uint32_t i;
63
RISCVAPLICState *aplic = RISCV_APLIC(dev);
64
65
- aplic->bitfield_words = (aplic->num_irqs + 31) >> 5;
66
- aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs);
67
- aplic->state = g_new0(uint32_t, aplic->num_irqs);
68
- aplic->target = g_new0(uint32_t, aplic->num_irqs);
69
- if (!aplic->msimode) {
70
- for (i = 0; i < aplic->num_irqs; i++) {
71
- aplic->target[i] = 1;
72
+ if (!is_kvm_aia(aplic->msimode)) {
73
+ aplic->bitfield_words = (aplic->num_irqs + 31) >> 5;
74
+ aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs);
75
+ aplic->state = g_new0(uint32_t, aplic->num_irqs);
76
+ aplic->target = g_new0(uint32_t, aplic->num_irqs);
77
+ if (!aplic->msimode) {
78
+ for (i = 0; i < aplic->num_irqs; i++) {
79
+ aplic->target[i] = 1;
80
+ }
81
}
82
- }
83
- aplic->idelivery = g_new0(uint32_t, aplic->num_harts);
84
- aplic->iforce = g_new0(uint32_t, aplic->num_harts);
85
- aplic->ithreshold = g_new0(uint32_t, aplic->num_harts);
86
+ aplic->idelivery = g_new0(uint32_t, aplic->num_harts);
87
+ aplic->iforce = g_new0(uint32_t, aplic->num_harts);
88
+ aplic->ithreshold = g_new0(uint32_t, aplic->num_harts);
89
90
- memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops, aplic,
91
- TYPE_RISCV_APLIC, aplic->aperture_size);
92
- sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio);
93
+ memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops,
94
+ aplic, TYPE_RISCV_APLIC, aplic->aperture_size);
95
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio);
96
+ }
97
98
/*
99
* Only root APLICs have hardware IRQ lines. All non-root APLICs
100
* have IRQ lines delegated by their parent APLIC.
101
*/
102
if (!aplic->parent) {
103
- qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
104
+ if (is_kvm_aia(aplic->msimode)) {
105
+ qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs);
106
+ } else {
107
+ qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
108
+ }
109
}
110
111
/* Create output IRQ lines for non-MSI mode */
112
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
113
qdev_prop_set_bit(dev, "mmode", mmode);
114
115
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
116
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
117
+
118
+ if (!is_kvm_aia(msimode)) {
119
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
120
+ }
121
122
if (parent) {
123
riscv_aplic_add_child(parent, dev);
124
diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c
37
index XXXXXXX..XXXXXXX 100644
125
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/riscv/sifive_u.c
126
--- a/hw/intc/riscv_imsic.c
39
+++ b/hw/riscv/sifive_u.c
127
+++ b/hw/intc/riscv_imsic.c
40
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
128
@@ -XXX,XX +XXX,XX @@
41
{
129
#include "target/riscv/cpu.h"
42
MachineState *ms = MACHINE(qdev_get_machine());
130
#include "target/riscv/cpu_bits.h"
43
void *fdt;
131
#include "sysemu/sysemu.h"
44
- int cpu;
132
+#include "sysemu/kvm.h"
45
+ int cpu, fdt_size;
133
#include "migration/vmstate.h"
46
uint32_t *cells;
134
47
char *nodename;
135
#define IMSIC_MMIO_PAGE_LE 0x00
48
uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1;
136
@@ -XXX,XX +XXX,XX @@ static void riscv_imsic_write(void *opaque, hwaddr addr, uint64_t value,
49
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
137
goto err;
50
};
51
52
if (ms->dtb) {
53
- fdt = s->fdt = load_device_tree(ms->dtb, &s->fdt_size);
54
+ fdt = ms->fdt = load_device_tree(ms->dtb, &fdt_size);
55
if (!fdt) {
56
error_report("load_device_tree() failed");
57
exit(1);
58
}
59
goto update_bootargs;
60
} else {
61
- fdt = s->fdt = create_device_tree(&s->fdt_size);
62
+ fdt = ms->fdt = create_device_tree(&fdt_size);
63
if (!fdt) {
64
error_report("create_device_tree() failed");
65
exit(1);
66
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
67
hwaddr end = riscv_load_initrd(machine->initrd_filename,
68
machine->ram_size, kernel_entry,
69
&start);
70
- qemu_fdt_setprop_cell(s->fdt, "/chosen",
71
+ qemu_fdt_setprop_cell(machine->fdt, "/chosen",
72
"linux,initrd-start", start);
73
- qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
74
+ qemu_fdt_setprop_cell(machine->fdt, "/chosen", "linux,initrd-end",
75
end);
76
}
77
} else {
78
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
79
80
/* Compute the fdt load address in dram */
81
fdt_load_addr = riscv_load_fdt(memmap[SIFIVE_U_DEV_DRAM].base,
82
- machine->ram_size, s->fdt);
83
+ machine->ram_size, machine->fdt);
84
if (!riscv_is_32bit(&s->soc.u_cpus)) {
85
start_addr_hi32 = (uint64_t)start_addr >> 32;
86
}
138
}
87
139
88
- /* Set machine->fdt for 'dumpdtb' QMP/HMP command */
140
+#if defined(CONFIG_KVM)
89
- machine->fdt = s->fdt;
141
+ if (kvm_irqchip_in_kernel()) {
90
-
142
+ struct kvm_msi msi;
91
/* reset vector */
143
+
92
uint32_t reset_vec[12] = {
144
+ msi.address_lo = extract64(imsic->mmio.addr + addr, 0, 32);
93
s->msel, /* MSEL pin state */
145
+ msi.address_hi = extract64(imsic->mmio.addr + addr, 32, 32);
146
+ msi.data = le32_to_cpu(value);
147
+
148
+ kvm_vm_ioctl(kvm_state, KVM_SIGNAL_MSI, &msi);
149
+
150
+ return;
151
+ }
152
+#endif
153
+
154
/* Writes only supported for MSI little-endian registers */
155
page = addr >> IMSIC_MMIO_PAGE_SHIFT;
156
if ((addr & (IMSIC_MMIO_PAGE_SZ - 1)) == IMSIC_MMIO_PAGE_LE) {
157
@@ -XXX,XX +XXX,XX @@ static void riscv_imsic_realize(DeviceState *dev, Error **errp)
158
CPUState *cpu = cpu_by_arch_id(imsic->hartid);
159
CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
160
161
- imsic->num_eistate = imsic->num_pages * imsic->num_irqs;
162
- imsic->eidelivery = g_new0(uint32_t, imsic->num_pages);
163
- imsic->eithreshold = g_new0(uint32_t, imsic->num_pages);
164
- imsic->eistate = g_new0(uint32_t, imsic->num_eistate);
165
+ if (!kvm_irqchip_in_kernel()) {
166
+ imsic->num_eistate = imsic->num_pages * imsic->num_irqs;
167
+ imsic->eidelivery = g_new0(uint32_t, imsic->num_pages);
168
+ imsic->eithreshold = g_new0(uint32_t, imsic->num_pages);
169
+ imsic->eistate = g_new0(uint32_t, imsic->num_eistate);
170
+ }
171
172
memory_region_init_io(&imsic->mmio, OBJECT(dev), &riscv_imsic_ops,
173
imsic, TYPE_RISCV_IMSIC,
94
--
174
--
95
2.39.0
175
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
Some boards are duplicating the 'riscv_find_and_load_firmware' call
3
Select KVM AIA when the host kernel has in-kernel AIA chip support.
4
because the 32 and 64 bits images have different names. Create
4
Since KVM AIA only has one APLIC instance, we map the QEMU APLIC
5
a function to handle this detail instead of hardcoding it in the boards.
5
devices to KVM APLIC.
6
6
7
Ideally we would bake this logic inside riscv_find_and_load_firmware(),
7
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
8
or even create a riscv_load_default_firmware(), but at this moment we
8
Reviewed-by: Jim Shu <jim.shu@sifive.com>
9
cannot infer whether the machine is running 32 or 64 bits without
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
accessing RISCVHartArrayState, which in turn can't be accessed via the
10
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
11
common code from boot.c. In the end we would exchange 'firmware_name'
11
Message-ID: <20230727102439.22554-6-yongxuan.wang@sifive.com>
12
for a flag with riscv_is_32bit(), which isn't much better than what we
13
already have today.
14
15
Cc: Palmer Dabbelt <palmer@dabbelt.com>
16
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Reviewed-by: Bin Meng <bmeng@tinylab.org>
19
Signed-off-by: Bin Meng <bmeng@tinylab.org>
20
Message-Id: <20221221182300.307900-6-dbarboza@ventanamicro.com>
21
Message-Id: <20221229091828.1945072-11-bmeng@tinylab.org>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
13
---
24
include/hw/riscv/boot.h | 1 +
14
hw/riscv/virt.c | 94 +++++++++++++++++++++++++++++++++----------------
25
hw/riscv/boot.c | 9 +++++++++
15
1 file changed, 63 insertions(+), 31 deletions(-)
26
hw/riscv/sifive_u.c | 11 ++++-------
27
hw/riscv/spike.c | 14 +++++---------
28
hw/riscv/virt.c | 10 +++-------
29
5 files changed, 22 insertions(+), 23 deletions(-)
30
16
31
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/include/hw/riscv/boot.h
34
+++ b/include/hw/riscv/boot.h
35
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_find_and_load_firmware(MachineState *machine,
36
const char *default_machine_firmware,
37
hwaddr firmware_load_addr,
38
symbol_fn_t sym_cb);
39
+const char *riscv_default_firmware_name(RISCVHartArrayState *harts);
40
target_ulong riscv_load_firmware(const char *firmware_filename,
41
hwaddr firmware_load_addr,
42
symbol_fn_t sym_cb);
43
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/riscv/boot.c
46
+++ b/hw/riscv/boot.c
47
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState *harts,
48
}
49
}
50
51
+const char *riscv_default_firmware_name(RISCVHartArrayState *harts)
52
+{
53
+ if (riscv_is_32bit(harts)) {
54
+ return RISCV32_BIOS_BIN;
55
+ }
56
+
57
+ return RISCV64_BIOS_BIN;
58
+}
59
+
60
static char *riscv_find_firmware(const char *firmware_filename)
61
{
62
char *filename;
63
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/riscv/sifive_u.c
66
+++ b/hw/riscv/sifive_u.c
67
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
68
MemoryRegion *flash0 = g_new(MemoryRegion, 1);
69
target_ulong start_addr = memmap[SIFIVE_U_DEV_DRAM].base;
70
target_ulong firmware_end_addr, kernel_start_addr;
71
+ const char *firmware_name;
72
uint32_t start_addr_hi32 = 0x00000000;
73
int i;
74
uint32_t fdt_load_addr;
75
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
76
break;
77
}
78
79
- if (riscv_is_32bit(&s->soc.u_cpus)) {
80
- firmware_end_addr = riscv_find_and_load_firmware(machine,
81
- RISCV32_BIOS_BIN, start_addr, NULL);
82
- } else {
83
- firmware_end_addr = riscv_find_and_load_firmware(machine,
84
- RISCV64_BIOS_BIN, start_addr, NULL);
85
- }
86
+ firmware_name = riscv_default_firmware_name(&s->soc.u_cpus);
87
+ firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name,
88
+ start_addr, NULL);
89
90
if (machine->kernel_filename) {
91
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc.u_cpus,
92
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/riscv/spike.c
95
+++ b/hw/riscv/spike.c
96
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
97
MemoryRegion *system_memory = get_system_memory();
98
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
99
target_ulong firmware_end_addr, kernel_start_addr;
100
+ const char *firmware_name;
101
uint32_t fdt_load_addr;
102
uint64_t kernel_entry;
103
char *soc_name;
104
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
105
memory_region_add_subregion(system_memory, memmap[SPIKE_MROM].base,
106
mask_rom);
107
108
- if (riscv_is_32bit(&s->soc[0])) {
109
- firmware_end_addr = riscv_find_and_load_firmware(machine,
110
- RISCV32_BIOS_BIN, memmap[SPIKE_DRAM].base,
111
- htif_symbol_callback);
112
- } else {
113
- firmware_end_addr = riscv_find_and_load_firmware(machine,
114
- RISCV64_BIOS_BIN, memmap[SPIKE_DRAM].base,
115
- htif_symbol_callback);
116
- }
117
+ firmware_name = riscv_default_firmware_name(&s->soc[0]);
118
+ firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name,
119
+ memmap[SPIKE_DRAM].base,
120
+ htif_symbol_callback);
121
122
/* Load kernel */
123
if (machine->kernel_filename) {
124
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
17
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
125
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
126
--- a/hw/riscv/virt.c
19
--- a/hw/riscv/virt.c
127
+++ b/hw/riscv/virt.c
20
+++ b/hw/riscv/virt.c
128
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
21
@@ -XXX,XX +XXX,XX @@
129
MachineState *machine = MACHINE(s);
22
#include "hw/riscv/virt.h"
130
target_ulong start_addr = memmap[VIRT_DRAM].base;
23
#include "hw/riscv/boot.h"
131
target_ulong firmware_end_addr, kernel_start_addr;
24
#include "hw/riscv/numa.h"
132
+ const char *firmware_name = riscv_default_firmware_name(&s->soc[0]);
25
+#include "kvm_riscv.h"
133
uint32_t fdt_load_addr;
26
#include "hw/intc/riscv_aclint.h"
134
uint64_t kernel_entry;
27
#include "hw/intc/riscv_aplic.h"
135
28
#include "hw/intc/riscv_imsic.h"
136
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
29
@@ -XXX,XX +XXX,XX @@
30
#error "Can't accommodate all IMSIC groups in address space"
31
#endif
32
33
+/* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU. */
34
+static bool virt_use_kvm_aia(RISCVVirtState *s)
35
+{
36
+ return kvm_irqchip_in_kernel() && s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
37
+}
38
+
39
static const MemMapEntry virt_memmap[] = {
40
[VIRT_DEBUG] = { 0x0, 0x100 },
41
[VIRT_MROM] = { 0x1000, 0xf000 },
42
@@ -XXX,XX +XXX,XX @@ static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
43
uint32_t *intc_phandles,
44
uint32_t aplic_phandle,
45
uint32_t aplic_child_phandle,
46
- bool m_mode)
47
+ bool m_mode, int num_harts)
48
{
49
int cpu;
50
char *aplic_name;
51
uint32_t *aplic_cells;
52
MachineState *ms = MACHINE(s);
53
54
- aplic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
55
+ aplic_cells = g_new0(uint32_t, num_harts * 2);
56
57
- for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
58
+ for (cpu = 0; cpu < num_harts; cpu++) {
59
aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
60
aplic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
61
}
62
@@ -XXX,XX +XXX,XX @@ static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
63
64
if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
65
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
66
- aplic_cells,
67
- s->soc[socket].num_harts * sizeof(uint32_t) * 2);
68
+ aplic_cells, num_harts * sizeof(uint32_t) * 2);
69
} else {
70
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent", msi_phandle);
71
}
72
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
73
uint32_t msi_s_phandle,
74
uint32_t *phandle,
75
uint32_t *intc_phandles,
76
- uint32_t *aplic_phandles)
77
+ uint32_t *aplic_phandles,
78
+ int num_harts)
79
{
80
char *aplic_name;
81
unsigned long aplic_addr;
82
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
83
create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_M].size,
84
msi_m_phandle, intc_phandles,
85
aplic_m_phandle, aplic_s_phandle,
86
- true);
87
+ true, num_harts);
88
}
89
90
/* S-level APLIC node */
91
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
92
create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_S].size,
93
msi_s_phandle, intc_phandles,
94
aplic_s_phandle, 0,
95
- false);
96
+ false, num_harts);
97
98
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
99
100
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
101
*msi_pcie_phandle = msi_s_phandle;
102
}
103
104
- phandle_pos = ms->smp.cpus;
105
- for (socket = (socket_count - 1); socket >= 0; socket--) {
106
- phandle_pos -= s->soc[socket].num_harts;
107
-
108
- if (s->aia_type == VIRT_AIA_TYPE_NONE) {
109
- create_fdt_socket_plic(s, memmap, socket, phandle,
110
- &intc_phandles[phandle_pos], xplic_phandles);
111
- } else {
112
- create_fdt_socket_aplic(s, memmap, socket,
113
- msi_m_phandle, msi_s_phandle, phandle,
114
- &intc_phandles[phandle_pos], xplic_phandles);
115
+ /* KVM AIA only has one APLIC instance */
116
+ if (virt_use_kvm_aia(s)) {
117
+ create_fdt_socket_aplic(s, memmap, 0,
118
+ msi_m_phandle, msi_s_phandle, phandle,
119
+ &intc_phandles[0], xplic_phandles,
120
+ ms->smp.cpus);
121
+ } else {
122
+ phandle_pos = ms->smp.cpus;
123
+ for (socket = (socket_count - 1); socket >= 0; socket--) {
124
+ phandle_pos -= s->soc[socket].num_harts;
125
+
126
+ if (s->aia_type == VIRT_AIA_TYPE_NONE) {
127
+ create_fdt_socket_plic(s, memmap, socket, phandle,
128
+ &intc_phandles[phandle_pos],
129
+ xplic_phandles);
130
+ } else {
131
+ create_fdt_socket_aplic(s, memmap, socket,
132
+ msi_m_phandle, msi_s_phandle, phandle,
133
+ &intc_phandles[phandle_pos],
134
+ xplic_phandles,
135
+ s->soc[socket].num_harts);
136
+ }
137
}
137
}
138
}
138
}
139
139
140
- if (riscv_is_32bit(&s->soc[0])) {
140
g_free(intc_phandles);
141
- firmware_end_addr = riscv_find_and_load_firmware(machine,
141
142
- RISCV32_BIOS_BIN, start_addr, NULL);
142
- for (socket = 0; socket < socket_count; socket++) {
143
- } else {
143
- if (socket == 0) {
144
- firmware_end_addr = riscv_find_and_load_firmware(machine,
144
- *irq_mmio_phandle = xplic_phandles[socket];
145
- RISCV64_BIOS_BIN, start_addr, NULL);
145
- *irq_virtio_phandle = xplic_phandles[socket];
146
- }
146
- *irq_pcie_phandle = xplic_phandles[socket];
147
+ firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name,
147
- }
148
+ start_addr, NULL);
148
- if (socket == 1) {
149
149
- *irq_virtio_phandle = xplic_phandles[socket];
150
/*
150
- *irq_pcie_phandle = xplic_phandles[socket];
151
* Init fw_cfg. Must be done before riscv_load_fdt, otherwise the device
151
- }
152
- if (socket == 2) {
153
- *irq_pcie_phandle = xplic_phandles[socket];
154
+ if (virt_use_kvm_aia(s)) {
155
+ *irq_mmio_phandle = xplic_phandles[0];
156
+ *irq_virtio_phandle = xplic_phandles[0];
157
+ *irq_pcie_phandle = xplic_phandles[0];
158
+ } else {
159
+ for (socket = 0; socket < socket_count; socket++) {
160
+ if (socket == 0) {
161
+ *irq_mmio_phandle = xplic_phandles[socket];
162
+ *irq_virtio_phandle = xplic_phandles[socket];
163
+ *irq_pcie_phandle = xplic_phandles[socket];
164
+ }
165
+ if (socket == 1) {
166
+ *irq_virtio_phandle = xplic_phandles[socket];
167
+ *irq_pcie_phandle = xplic_phandles[socket];
168
+ }
169
+ if (socket == 2) {
170
+ *irq_pcie_phandle = xplic_phandles[socket];
171
+ }
172
}
173
}
174
175
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
176
}
177
}
178
179
+ if (virt_use_kvm_aia(s)) {
180
+ kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT,
181
+ VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS,
182
+ memmap[VIRT_APLIC_S].base,
183
+ memmap[VIRT_IMSIC_S].base,
184
+ s->aia_guests);
185
+ }
186
+
187
if (riscv_is_32bit(&s->soc[0])) {
188
#if HOST_LONG_BITS == 64
189
/* limit RAM size in a 32-bit system */
152
--
190
--
153
2.39.0
191
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Conor Dooley <conor.dooley@microchip.com>
2
2
3
Commit 1c20d3ff6004 ("hw/riscv: virt: Add a machine done notifier")
3
On a dtb dumped from the virt machine, dt-validate complains:
4
moved the initialization of fw_cfg to the virt_machine_done() callback.
4
soc: pmu: {'riscv,event-to-mhpmcounters': [[1, 1, 524281], [2, 2, 524284], [65561, 65561, 524280], [65563, 65563, 524280], [65569, 65569, 524280]], 'compatible': ['riscv,pmu']} should not be valid under {'type': 'object'}
5
from schema $id: http://devicetree.org/schemas/simple-bus.yaml#
6
That's pretty cryptic, but running the dtb back through dtc produces
7
something a lot more reasonable:
8
Warning (simple_bus_reg): /soc/pmu: missing or empty reg/ranges property
5
9
6
Problem is that the validation of fw_cfg by devices such as ramfb is
10
Moving the riscv,pmu node out of the soc bus solves the problem.
7
done before the machine done notifier is called. Moving create_fw_cfg()
8
to machine_done() results in QEMU failing to boot when using a ramfb
9
device:
10
11
11
./qemu-system-riscv64 -machine virt -device ramfb -serial stdio
12
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
12
qemu-system-riscv64: -device ramfb: ramfb device requires fw_cfg with DMA
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
13
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
The fix is simple: move create_fw_cfg() config back to
15
Message-ID: <20230727-groom-decline-2c57ce42841c@spud>
15
virt_machine_init(). This happens to be the same way the ARM 'virt'
16
machine deals with fw_cfg (see machvirt_init() and virt_machine_done()
17
in hw/arm/virt.c), so we're keeping consistency with how other machines
18
handle this device.
19
20
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1343
21
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
22
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Message-Id: <20230117132751.229738-2-dbarboza@ventanamicro.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
17
---
26
hw/riscv/virt.c | 14 +++++++-------
18
hw/riscv/virt.c | 2 +-
27
1 file changed, 7 insertions(+), 7 deletions(-)
19
1 file changed, 1 insertion(+), 1 deletion(-)
28
20
29
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
21
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
30
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/riscv/virt.c
23
--- a/hw/riscv/virt.c
32
+++ b/hw/riscv/virt.c
24
+++ b/hw/riscv/virt.c
33
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
25
@@ -XXX,XX +XXX,XX @@ static void create_fdt_pmu(RISCVVirtState *s)
34
firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name,
26
MachineState *ms = MACHINE(s);
35
start_addr, NULL);
27
RISCVCPU hart = s->soc[0].harts[0];
36
28
37
- /*
29
- pmu_name = g_strdup_printf("/soc/pmu");
38
- * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the device
30
+ pmu_name = g_strdup_printf("/pmu");
39
- * tree cannot be altered and we get FDT_ERR_NOSPACE.
31
qemu_fdt_add_subnode(ms->fdt, pmu_name);
40
- */
32
qemu_fdt_setprop_string(ms->fdt, pmu_name, "compatible", "riscv,pmu");
41
- s->fw_cfg = create_fw_cfg(machine);
33
riscv_pmu_generate_fdt_node(ms->fdt, hart.cfg.pmu_num, pmu_name);
42
- rom_set_fw(s->fw_cfg);
43
-
44
if (drive_get(IF_PFLASH, 0, 1)) {
45
/*
46
* S-mode FW like EDK2 will be kept in second plash (unit 1).
47
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
48
memory_region_add_subregion(system_memory, memmap[VIRT_MROM].base,
49
mask_rom);
50
51
+ /*
52
+ * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the
53
+ * device tree cannot be altered and we get FDT_ERR_NOSPACE.
54
+ */
55
+ s->fw_cfg = create_fw_cfg(machine);
56
+ rom_set_fw(s->fw_cfg);
57
+
58
/* SiFive Test MMIO device */
59
sifive_test_create(memmap[VIRT_TEST].base);
60
61
--
34
--
62
2.39.0
35
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
2
2
3
This will make the code more in line with what the other boards are
3
The Svadu specification updated the name of the *envcfg bit from
4
doing. We'll also avoid an extra check to machine->kernel_filename since
4
HADE to ADUE.
5
we already checked that before executing riscv_load_kernel().
6
5
7
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
6
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Reviewed-by: Bin Meng <bmeng@tinylab.org>
9
Message-ID: <20230816141916.66898-1-liweiwei@iscas.ac.cn>
11
Message-Id: <20230102115241.25733-6-dbarboza@ventanamicro.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
11
---
14
hw/riscv/spike.c | 31 +++++++++++++++----------------
12
target/riscv/cpu_bits.h | 8 ++++----
15
1 file changed, 15 insertions(+), 16 deletions(-)
13
target/riscv/cpu.c | 4 ++--
14
target/riscv/cpu_helper.c | 6 +++---
15
target/riscv/csr.c | 12 ++++++------
16
4 files changed, 15 insertions(+), 15 deletions(-)
16
17
17
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
18
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/riscv/spike.c
20
--- a/target/riscv/cpu_bits.h
20
+++ b/hw/riscv/spike.c
21
+++ b/target/riscv/cpu_bits.h
21
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
22
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
22
g_free(firmware_name);
23
#define MENVCFG_CBIE (3UL << 4)
24
#define MENVCFG_CBCFE BIT(6)
25
#define MENVCFG_CBZE BIT(7)
26
-#define MENVCFG_HADE (1ULL << 61)
27
+#define MENVCFG_ADUE (1ULL << 61)
28
#define MENVCFG_PBMTE (1ULL << 62)
29
#define MENVCFG_STCE (1ULL << 63)
30
31
/* For RV32 */
32
-#define MENVCFGH_HADE BIT(29)
33
+#define MENVCFGH_ADUE BIT(29)
34
#define MENVCFGH_PBMTE BIT(30)
35
#define MENVCFGH_STCE BIT(31)
36
37
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
38
#define HENVCFG_CBIE MENVCFG_CBIE
39
#define HENVCFG_CBCFE MENVCFG_CBCFE
40
#define HENVCFG_CBZE MENVCFG_CBZE
41
-#define HENVCFG_HADE MENVCFG_HADE
42
+#define HENVCFG_ADUE MENVCFG_ADUE
43
#define HENVCFG_PBMTE MENVCFG_PBMTE
44
#define HENVCFG_STCE MENVCFG_STCE
45
46
/* For RV32 */
47
-#define HENVCFGH_HADE MENVCFGH_HADE
48
+#define HENVCFGH_ADUE MENVCFGH_ADUE
49
#define HENVCFGH_PBMTE MENVCFGH_PBMTE
50
#define HENVCFGH_STCE MENVCFGH_STCE
51
52
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/riscv/cpu.c
55
+++ b/target/riscv/cpu.c
56
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj)
57
env->two_stage_lookup = false;
58
59
env->menvcfg = (cpu->cfg.ext_svpbmt ? MENVCFG_PBMTE : 0) |
60
- (cpu->cfg.ext_svadu ? MENVCFG_HADE : 0);
61
+ (cpu->cfg.ext_svadu ? MENVCFG_ADUE : 0);
62
env->henvcfg = (cpu->cfg.ext_svpbmt ? HENVCFG_PBMTE : 0) |
63
- (cpu->cfg.ext_svadu ? HENVCFG_HADE : 0);
64
+ (cpu->cfg.ext_svadu ? HENVCFG_ADUE : 0);
65
66
/* Initialized default priorities of local interrupts. */
67
for (i = 0; i < ARRAY_SIZE(env->miprio); i++) {
68
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/riscv/cpu_helper.c
71
+++ b/target/riscv/cpu_helper.c
72
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
23
}
73
}
24
74
25
+ /* Create device tree */
75
bool pbmte = env->menvcfg & MENVCFG_PBMTE;
26
+ create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
76
- bool hade = env->menvcfg & MENVCFG_HADE;
27
+ riscv_is_32bit(&s->soc[0]), htif_custom_base);
77
+ bool adue = env->menvcfg & MENVCFG_ADUE;
28
+
78
29
/* Load kernel */
79
if (first_stage && two_stage && env->virt_enabled) {
30
if (machine->kernel_filename) {
80
pbmte = pbmte && (env->henvcfg & HENVCFG_PBMTE);
31
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0],
81
- hade = hade && (env->henvcfg & HENVCFG_HADE);
32
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
82
+ adue = adue && (env->henvcfg & HENVCFG_ADUE);
33
kernel_entry = riscv_load_kernel(machine->kernel_filename,
34
kernel_start_addr,
35
htif_symbol_callback);
36
+
37
+ if (machine->initrd_filename) {
38
+ hwaddr start;
39
+ hwaddr end = riscv_load_initrd(machine->initrd_filename,
40
+ machine->ram_size, kernel_entry,
41
+ &start);
42
+ qemu_fdt_setprop_cell(machine->fdt, "/chosen",
43
+ "linux,initrd-start", start);
44
+ qemu_fdt_setprop_cell(machine->fdt, "/chosen", "linux,initrd-end",
45
+ end);
46
+ }
47
} else {
48
/*
49
* If dynamic firmware is used, it doesn't know where is the next mode
50
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
51
kernel_entry = 0;
52
}
83
}
53
84
54
- /* Create device tree */
85
int ptshift = (levels - 1) * ptidxbits;
55
- create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
86
@@ -XXX,XX +XXX,XX @@ restart:
56
- riscv_is_32bit(&s->soc[0]), htif_custom_base);
87
57
-
88
/* Page table updates need to be atomic with MTTCG enabled */
58
- /* Load initrd */
89
if (updated_pte != pte && !is_debug) {
59
- if (machine->kernel_filename && machine->initrd_filename) {
90
- if (!hade) {
60
- hwaddr start;
91
+ if (!adue) {
61
- hwaddr end = riscv_load_initrd(machine->initrd_filename,
92
return TRANSLATE_FAIL;
62
- machine->ram_size, kernel_entry,
93
}
63
- &start);
94
64
- qemu_fdt_setprop_cell(machine->fdt, "/chosen",
95
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
65
- "linux,initrd-start", start);
96
index XXXXXXX..XXXXXXX 100644
66
- qemu_fdt_setprop_cell(machine->fdt, "/chosen", "linux,initrd-end",
97
--- a/target/riscv/csr.c
67
- end);
98
+++ b/target/riscv/csr.c
68
- }
99
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
69
-
100
if (riscv_cpu_mxl(env) == MXL_RV64) {
70
/* Compute the fdt load address in dram */
101
mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
71
fdt_load_addr = riscv_load_fdt(memmap[SPIKE_DRAM].base,
102
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
72
machine->ram_size, machine->fdt);
103
- (cfg->ext_svadu ? MENVCFG_HADE : 0);
104
+ (cfg->ext_svadu ? MENVCFG_ADUE : 0);
105
}
106
env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
107
108
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
109
const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
110
uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
111
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
112
- (cfg->ext_svadu ? MENVCFG_HADE : 0);
113
+ (cfg->ext_svadu ? MENVCFG_ADUE : 0);
114
uint64_t valh = (uint64_t)val << 32;
115
116
env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
117
@@ -XXX,XX +XXX,XX @@ static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
118
* henvcfg.stce is read_only 0 when menvcfg.stce = 0
119
* henvcfg.hade is read_only 0 when menvcfg.hade = 0
120
*/
121
- *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) |
122
+ *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
123
env->menvcfg);
124
return RISCV_EXCP_NONE;
125
}
126
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
127
}
128
129
if (riscv_cpu_mxl(env) == MXL_RV64) {
130
- mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE);
131
+ mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE);
132
}
133
134
env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
135
@@ -XXX,XX +XXX,XX @@ static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
136
return ret;
137
}
138
139
- *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) |
140
+ *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
141
env->menvcfg)) >> 32;
142
return RISCV_EXCP_NONE;
143
}
144
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
145
target_ulong val)
146
{
147
uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE |
148
- HENVCFG_HADE);
149
+ HENVCFG_ADUE);
150
uint64_t valh = (uint64_t)val << 32;
151
RISCVException ret;
152
73
--
153
--
74
2.39.0
154
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
There is an informal contract between the cpu_init() functions and
3
In the same emulated RISC-V host, the 'host' KVM CPU takes 4 times
4
riscv_cpu_realize(): if cpu->env.misa_ext is zero, assume that the
4
longer to boot than the 'rv64' KVM CPU.
5
default settings were loaded via register_cpu_props() and do validations
6
to set env.misa_ext. If it's not zero, skip this whole process and
7
assume that the board somehow did everything.
8
5
9
At this moment, all SiFive CPUs are setting a non-zero misa_ext during
6
The reason is an unintended behavior of riscv_cpu_satp_mode_finalize()
10
their cpu_init() and skipping a good chunk of riscv_cpu_realize(). This
7
when satp_mode.supported = 0, i.e. when cpu_init() does not set
11
causes problems when the code being skipped in riscv_cpu_realize()
8
satp_mode_max_supported(). satp_mode_max_from_map(map) does:
12
contains fixes or assumptions that affects all CPUs, meaning that SiFive
13
CPUs are missing out.
14
9
15
To allow this code to not be skipped anymore, all the cpu->cfg.ext_*
10
31 - __builtin_clz(map)
16
attributes needs to be set during cpu_init() time. At this moment this
17
is being done in register_cpu_props(). The SiFive boards are setting
18
their own extensions during cpu_init() though, meaning that they don't
19
want all the defaults from register_cpu_props().
20
11
21
Let's move the contract between *_cpu_init() and riscv_cpu_realize() to
12
This means that, if satp_mode.supported = 0, satp_mode_supported_max
22
register_cpu_props(). Inside this function we'll check if
13
wil be '31 - 32'. But this is C, so satp_mode_supported_max will gladly
23
cpu->env.misa_ext was set and, if that's the case, set all relevant
14
set it to UINT_MAX (4294967295). After that, if the user didn't set a
24
cpu->cfg.ext_* attributes, and only that. Leave the 'misa_ext' = 0 case
15
satp_mode, set_satp_mode_default_map(cpu) will make
25
as is today, i.e. loading all the defaults from riscv_cpu_extensions[].
26
16
27
register_cpu_props() can then be called by all the cpu_init() functions,
17
cfg.satp_mode.map = cfg.satp_mode.supported
28
including the SiFive ones. This will make all CPUs behave more in line
29
with what riscv_cpu_realize() expects.
30
18
31
This will also make the cpu_init() functions even more alike, but at this
19
So satp_mode.map = 0. And then satp_mode_map_max will be set to
32
moment we would need some design changes in how we're initializing
20
satp_mode_max_from_map(cpu->cfg.satp_mode.map), i.e. also UINT_MAX. The
33
extensions/attributes (e.g. some CPUs are setting cfg options after
21
guard "satp_mode_map_max > satp_mode_supported_max" doesn't protect us
34
register_cpu_props(), so we can't simply add the function to a common
22
here since both are UINT_MAX.
35
post_init() hook) to make a common cpu_init() code across all CPUs.
36
23
24
And finally we have 2 loops:
25
26
for (int i = satp_mode_map_max - 1; i >= 0; --i) {
27
28
Which are, in fact, 2 loops from UINT_MAX -1 to -1. This is where the
29
extra delay when booting the 'host' CPU is coming from.
30
31
Commit 43d1de32f8 already set a precedence for satp_mode.supported = 0
32
in a different manner. We're doing the same here. If supported == 0,
33
interpret as 'the CPU wants the OS to handle satp mode alone' and skip
34
satp_mode_finalize().
35
36
We'll also put a guard in satp_mode_max_from_map() to assert out if map
37
is 0 since the function is not ready to deal with it.
38
39
Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
40
Fixes: 6f23aaeb9b ("riscv: Allow user to set the satp mode")
37
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
41
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
38
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
42
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
39
Message-Id: <20230113175230.473975-2-dbarboza@ventanamicro.com>
43
Message-ID: <20230817152903.694926-1-dbarboza@ventanamicro.com>
40
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
44
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
41
---
45
---
42
target/riscv/cpu.h | 4 ++++
46
target/riscv/cpu.c | 23 ++++++++++++++++++++---
43
target/riscv/cpu.c | 40 ++++++++++++++++++++++++++++++++++++++++
47
1 file changed, 20 insertions(+), 3 deletions(-)
44
2 files changed, 44 insertions(+)
45
48
46
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/cpu.h
49
+++ b/target/riscv/cpu.h
50
@@ -XXX,XX +XXX,XX @@
51
52
#define RV(x) ((target_ulong)1 << (x - 'A'))
53
54
+/*
55
+ * Consider updating register_cpu_props() when adding
56
+ * new MISA bits here.
57
+ */
58
#define RVI RV('I')
59
#define RVE RV('E') /* E and I are mutually exclusive */
60
#define RVM RV('M')
61
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
49
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
62
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
63
--- a/target/riscv/cpu.c
51
--- a/target/riscv/cpu.c
64
+++ b/target/riscv/cpu.c
52
+++ b/target/riscv/cpu.c
65
@@ -XXX,XX +XXX,XX @@ static void rv64_sifive_u_cpu_init(Object *obj)
53
@@ -XXX,XX +XXX,XX @@ static uint8_t satp_mode_from_str(const char *satp_mode_str)
54
55
uint8_t satp_mode_max_from_map(uint32_t map)
66
{
56
{
67
CPURISCVState *env = &RISCV_CPU(obj)->env;
57
+ /*
68
set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
58
+ * 'map = 0' will make us return (31 - 32), which C will
69
+ register_cpu_props(DEVICE(obj));
59
+ * happily overflow to UINT_MAX. There's no good result to
70
set_priv_version(env, PRIV_VERSION_1_10_0);
60
+ * return if 'map = 0' (e.g. returning 0 will be ambiguous
61
+ * with the result for 'map = 1').
62
+ *
63
+ * Assert out if map = 0. Callers will have to deal with
64
+ * it outside of this function.
65
+ */
66
+ g_assert(map > 0);
67
+
68
/* map here has at least one bit set, so no problem with clz */
69
return 31 - __builtin_clz(map);
71
}
70
}
72
71
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
73
@@ -XXX,XX +XXX,XX @@ static void rv64_sifive_e_cpu_init(Object *obj)
72
static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
74
RISCVCPU *cpu = RISCV_CPU(obj);
75
76
set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
77
+ register_cpu_props(DEVICE(obj));
78
set_priv_version(env, PRIV_VERSION_1_10_0);
79
cpu->cfg.mmu = false;
80
}
81
@@ -XXX,XX +XXX,XX @@ static void rv32_sifive_u_cpu_init(Object *obj)
82
{
73
{
83
CPURISCVState *env = &RISCV_CPU(obj)->env;
74
bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
84
set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
75
- uint8_t satp_mode_map_max;
85
+ register_cpu_props(DEVICE(obj));
76
- uint8_t satp_mode_supported_max =
86
set_priv_version(env, PRIV_VERSION_1_10_0);
77
- satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
87
}
78
+ uint8_t satp_mode_map_max, satp_mode_supported_max;
88
89
@@ -XXX,XX +XXX,XX @@ static void rv32_sifive_e_cpu_init(Object *obj)
90
RISCVCPU *cpu = RISCV_CPU(obj);
91
92
set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
93
+ register_cpu_props(DEVICE(obj));
94
set_priv_version(env, PRIV_VERSION_1_10_0);
95
cpu->cfg.mmu = false;
96
}
97
@@ -XXX,XX +XXX,XX @@ static void rv32_ibex_cpu_init(Object *obj)
98
RISCVCPU *cpu = RISCV_CPU(obj);
99
100
set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
101
+ register_cpu_props(DEVICE(obj));
102
set_priv_version(env, PRIV_VERSION_1_11_0);
103
cpu->cfg.mmu = false;
104
cpu->cfg.epmp = true;
105
@@ -XXX,XX +XXX,XX @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
106
RISCVCPU *cpu = RISCV_CPU(obj);
107
108
set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
109
+ register_cpu_props(DEVICE(obj));
110
set_priv_version(env, PRIV_VERSION_1_10_0);
111
cpu->cfg.mmu = false;
112
}
113
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
114
DEFINE_PROP_END_OF_LIST(),
115
};
116
117
+/*
118
+ * Register CPU props based on env.misa_ext. If a non-zero
119
+ * value was set, register only the required cpu->cfg.ext_*
120
+ * properties and leave. env.misa_ext = 0 means that we want
121
+ * all the default properties to be registered.
122
+ */
123
static void register_cpu_props(DeviceState *dev)
124
{
125
+ RISCVCPU *cpu = RISCV_CPU(OBJECT(dev));
126
+ uint32_t misa_ext = cpu->env.misa_ext;
127
Property *prop;
128
129
+ /*
130
+ * If misa_ext is not zero, set cfg properties now to
131
+ * allow them to be read during riscv_cpu_realize()
132
+ * later on.
133
+ */
134
+ if (cpu->env.misa_ext != 0) {
135
+ cpu->cfg.ext_i = misa_ext & RVI;
136
+ cpu->cfg.ext_e = misa_ext & RVE;
137
+ cpu->cfg.ext_m = misa_ext & RVM;
138
+ cpu->cfg.ext_a = misa_ext & RVA;
139
+ cpu->cfg.ext_f = misa_ext & RVF;
140
+ cpu->cfg.ext_d = misa_ext & RVD;
141
+ cpu->cfg.ext_v = misa_ext & RVV;
142
+ cpu->cfg.ext_c = misa_ext & RVC;
143
+ cpu->cfg.ext_s = misa_ext & RVS;
144
+ cpu->cfg.ext_u = misa_ext & RVU;
145
+ cpu->cfg.ext_h = misa_ext & RVH;
146
+ cpu->cfg.ext_j = misa_ext & RVJ;
147
+
79
+
148
+ /*
80
+ /* The CPU wants the OS to decide which satp mode to use */
149
+ * We don't want to set the default riscv_cpu_extensions
81
+ if (cpu->cfg.satp_mode.supported == 0) {
150
+ * in this case.
151
+ */
152
+ return;
82
+ return;
153
+ }
83
+ }
154
+
84
+
155
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
85
+ satp_mode_supported_max =
156
qdev_property_add_static(dev, prop);
86
+ satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
157
}
87
88
if (cpu->cfg.satp_mode.map == 0) {
89
if (cpu->cfg.satp_mode.init == 0) {
158
--
90
--
159
2.39.0
91
2.41.0
diff view generated by jsdifflib
1
From: Dongxue Zhang <elta.era@gmail.com>
1
From: Vineet Gupta <vineetg@rivosinc.com>
2
2
3
The elen check should be cpu->cfg.elen in range [8, 64].
3
zicond is now codegen supported in both llvm and gcc.
4
4
5
Signed-off-by: Dongxue Zhang <elta.era@gmail.com>
5
This change allows seamless enabling/testing of zicond in downstream
6
Reviewed-by: LIU Zhiwei <zhiwe_liu@linux.alibaba.com>
6
projects. e.g. currently riscv-gnu-toolchain parses elf attributes
7
Reviewed-by: Frank Chang <frank.chang@sifive.com>
7
to create a cmdline for qemu but fails short of enabling it because of
8
the "x-" prefix.
9
10
Signed-off-by: Vineet Gupta <vineetg@rivosinc.com>
11
Message-ID: <20230808181715.436395-1-vineetg@rivosinc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <167236721596.15277.2653405273227256289-0@git.sr.ht>
10
[ Changes by AF:
11
- Tidy up commit message
12
]
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
14
---
15
target/riscv/cpu.c | 2 +-
15
target/riscv/cpu.c | 2 +-
16
1 file changed, 1 insertion(+), 1 deletion(-)
16
1 file changed, 1 insertion(+), 1 deletion(-)
17
17
18
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
18
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/cpu.c
20
--- a/target/riscv/cpu.c
21
+++ b/target/riscv/cpu.c
21
+++ b/target/riscv/cpu.c
22
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
22
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
23
"Vector extension ELEN must be power of 2");
23
DEFINE_PROP_BOOL("zcf", RISCVCPU, cfg.ext_zcf, false),
24
return;
24
DEFINE_PROP_BOOL("zcmp", RISCVCPU, cfg.ext_zcmp, false),
25
}
25
DEFINE_PROP_BOOL("zcmt", RISCVCPU, cfg.ext_zcmt, false),
26
- if (cpu->cfg.elen > 64 || cpu->cfg.vlen < 8) {
26
+ DEFINE_PROP_BOOL("zicond", RISCVCPU, cfg.ext_zicond, false),
27
+ if (cpu->cfg.elen > 64 || cpu->cfg.elen < 8) {
27
28
error_setg(errp,
28
/* Vendor-specific custom extensions */
29
"Vector extension implementation only supports ELEN "
29
DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
30
"in the range [8, 64]");
30
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
31
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
32
33
/* These are experimental so mark with 'x-' */
34
- DEFINE_PROP_BOOL("x-zicond", RISCVCPU, cfg.ext_zicond, false),
35
36
/* ePMP 0.9.3 */
37
DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
31
--
38
--
32
2.39.0
39
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
There's no need to use a MachineState pointer and a fdt pointer now that
3
A build with --enable-debug and without KVM will fail as follows:
4
all RISC-V machines are using the FDT from the MachineState.
5
4
5
/usr/bin/ld: libqemu-riscv64-softmmu.fa.p/hw_riscv_virt.c.o: in function `virt_machine_init':
6
./qemu/build/../hw/riscv/virt.c:1465: undefined reference to `kvm_riscv_aia_create'
7
8
This happens because the code block with "if virt_use_kvm_aia(s)" isn't
9
being ignored by the debug build, resulting in an undefined reference to
10
a KVM only function.
11
12
Add a 'kvm_enabled()' conditional together with virt_use_kvm_aia() will
13
make the compiler crop the kvm_riscv_aia_create() call entirely from a
14
non-KVM build. Note that adding the 'kvm_enabled()' conditional inside
15
virt_use_kvm_aia() won't fix the build because this function would need
16
to be inlined multiple times to make the compiler zero out the entire
17
block.
18
19
While we're at it, use kvm_enabled() in all instances where
20
virt_use_kvm_aia() is checked to allow the compiler to elide these other
21
kvm-only instances as well.
22
23
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
24
Fixes: dbdb99948e ("target/riscv: select KVM AIA in riscv virt machine")
6
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
25
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
26
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
27
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-Id: <20230111170948.316276-7-dbarboza@ventanamicro.com>
29
Message-ID: <20230830133503.711138-2-dbarboza@ventanamicro.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
31
---
12
include/hw/riscv/numa.h | 4 ++--
32
hw/riscv/virt.c | 6 +++---
13
hw/riscv/numa.c | 8 ++++----
33
1 file changed, 3 insertions(+), 3 deletions(-)
14
hw/riscv/spike.c | 2 +-
15
hw/riscv/virt.c | 2 +-
16
4 files changed, 8 insertions(+), 8 deletions(-)
17
34
18
diff --git a/include/hw/riscv/numa.h b/include/hw/riscv/numa.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/riscv/numa.h
21
+++ b/include/hw/riscv/numa.h
22
@@ -XXX,XX +XXX,XX @@ void riscv_socket_fdt_write_id(const MachineState *ms, const char *node_name,
23
* @ms: pointer to machine state
24
* @socket_id: socket index
25
*
26
- * Write NUMA distance matrix in FDT for given machine
27
+ * Write NUMA distance matrix in MachineState->fdt
28
*/
29
-void riscv_socket_fdt_write_distance_matrix(const MachineState *ms, void *fdt);
30
+void riscv_socket_fdt_write_distance_matrix(const MachineState *ms);
31
32
CpuInstanceProperties
33
riscv_numa_cpu_index_to_props(MachineState *ms, unsigned cpu_index);
34
diff --git a/hw/riscv/numa.c b/hw/riscv/numa.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/riscv/numa.c
37
+++ b/hw/riscv/numa.c
38
@@ -XXX,XX +XXX,XX @@ void riscv_socket_fdt_write_id(const MachineState *ms, const char *node_name,
39
}
40
}
41
42
-void riscv_socket_fdt_write_distance_matrix(const MachineState *ms, void *fdt)
43
+void riscv_socket_fdt_write_distance_matrix(const MachineState *ms)
44
{
45
int i, j, idx;
46
uint32_t *dist_matrix, dist_matrix_size;
47
@@ -XXX,XX +XXX,XX @@ void riscv_socket_fdt_write_distance_matrix(const MachineState *ms, void *fdt)
48
}
49
}
50
51
- qemu_fdt_add_subnode(fdt, "/distance-map");
52
- qemu_fdt_setprop_string(fdt, "/distance-map", "compatible",
53
+ qemu_fdt_add_subnode(ms->fdt, "/distance-map");
54
+ qemu_fdt_setprop_string(ms->fdt, "/distance-map", "compatible",
55
"numa-distance-map-v1");
56
- qemu_fdt_setprop(fdt, "/distance-map", "distance-matrix",
57
+ qemu_fdt_setprop(ms->fdt, "/distance-map", "distance-matrix",
58
dist_matrix, dist_matrix_size);
59
g_free(dist_matrix);
60
}
61
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/riscv/spike.c
64
+++ b/hw/riscv/spike.c
65
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
66
g_free(clust_name);
67
}
68
69
- riscv_socket_fdt_write_distance_matrix(mc, fdt);
70
+ riscv_socket_fdt_write_distance_matrix(mc);
71
72
qemu_fdt_add_subnode(fdt, "/chosen");
73
qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", "/htif");
74
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
35
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
75
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
76
--- a/hw/riscv/virt.c
37
--- a/hw/riscv/virt.c
77
+++ b/hw/riscv/virt.c
38
+++ b/hw/riscv/virt.c
78
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
39
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
40
}
41
42
/* KVM AIA only has one APLIC instance */
43
- if (virt_use_kvm_aia(s)) {
44
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
45
create_fdt_socket_aplic(s, memmap, 0,
46
msi_m_phandle, msi_s_phandle, phandle,
47
&intc_phandles[0], xplic_phandles,
48
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
49
50
g_free(intc_phandles);
51
52
- if (virt_use_kvm_aia(s)) {
53
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
54
*irq_mmio_phandle = xplic_phandles[0];
55
*irq_virtio_phandle = xplic_phandles[0];
56
*irq_pcie_phandle = xplic_phandles[0];
57
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
79
}
58
}
80
}
59
}
81
60
82
- riscv_socket_fdt_write_distance_matrix(mc, mc->fdt);
61
- if (virt_use_kvm_aia(s)) {
83
+ riscv_socket_fdt_write_distance_matrix(mc);
62
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
84
}
63
kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT,
85
64
VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS,
86
static void create_fdt_virtio(RISCVVirtState *s, const MemMapEntry *memmap,
65
memmap[VIRT_APLIC_S].base,
87
--
66
--
88
2.39.0
67
2.41.0
68
69
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
'mem_size' and 'cmdline' aren't being used. Remove them.
3
Commit 6df0b37e2ab breaks a --enable-debug build in a non-KVM
4
environment with the following error:
5
6
/usr/bin/ld: libqemu-riscv64-softmmu.fa.p/hw_intc_riscv_aplic.c.o: in function `riscv_kvm_aplic_request':
7
./qemu/build/../hw/intc/riscv_aplic.c:486: undefined reference to `kvm_set_irq'
8
collect2: error: ld returned 1 exit status
9
10
This happens because the debug build will poke into the
11
'if (is_kvm_aia(aplic->msimode))' block and fail to find a reference to
12
the KVM only function riscv_kvm_aplic_request().
13
14
There are multiple solutions to fix this. We'll go with the same
15
solution from the previous patch, i.e. add a kvm_enabled() conditional
16
to filter out the block. But there's a catch: riscv_kvm_aplic_request()
17
is a local function that would end up being used if the compiler crops
18
the block, and this won't work. Quoting Richard Henderson's explanation
19
in [1]:
20
21
"(...) the compiler won't eliminate entire unused functions with -O0"
22
23
We'll solve it by moving riscv_kvm_aplic_request() to kvm.c and add its
24
declaration in kvm_riscv.h, where all other KVM specific public
25
functions are already declared. Other archs handles KVM specific code in
26
this manner and we expect to do the same from now on.
27
28
[1] https://lore.kernel.org/qemu-riscv/d2f1ad02-eb03-138f-9d08-db676deeed05@linaro.org/
4
29
5
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
30
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
31
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
32
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-Id: <20230111170948.316276-3-dbarboza@ventanamicro.com>
34
Message-ID: <20230830133503.711138-3-dbarboza@ventanamicro.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
36
---
11
hw/riscv/virt.c | 5 ++---
37
target/riscv/kvm_riscv.h | 1 +
12
1 file changed, 2 insertions(+), 3 deletions(-)
38
hw/intc/riscv_aplic.c | 8 ++------
39
target/riscv/kvm.c | 5 +++++
40
3 files changed, 8 insertions(+), 6 deletions(-)
13
41
14
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
42
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
15
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/virt.c
44
--- a/target/riscv/kvm_riscv.h
17
+++ b/hw/riscv/virt.c
45
+++ b/target/riscv/kvm_riscv.h
18
@@ -XXX,XX +XXX,XX @@ static void create_fdt_fw_cfg(RISCVVirtState *s, const MemMapEntry *memmap)
46
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
47
uint64_t aia_irq_num, uint64_t aia_msi_num,
48
uint64_t aplic_base, uint64_t imsic_base,
49
uint64_t guest_num);
50
+void riscv_kvm_aplic_request(void *opaque, int irq, int level);
51
52
#endif
53
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/intc/riscv_aplic.c
56
+++ b/hw/intc/riscv_aplic.c
57
@@ -XXX,XX +XXX,XX @@
58
#include "target/riscv/cpu.h"
59
#include "sysemu/sysemu.h"
60
#include "sysemu/kvm.h"
61
+#include "kvm_riscv.h"
62
#include "migration/vmstate.h"
63
64
#define APLIC_MAX_IDC (1UL << 14)
65
@@ -XXX,XX +XXX,XX @@ static uint32_t riscv_aplic_idc_claimi(RISCVAPLICState *aplic, uint32_t idc)
66
return topi;
19
}
67
}
20
68
21
static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap,
69
-static void riscv_kvm_aplic_request(void *opaque, int irq, int level)
22
- uint64_t mem_size, const char *cmdline, bool is_32_bit)
70
-{
23
+ bool is_32_bit)
71
- kvm_set_irq(kvm_state, irq, !!level);
72
-}
73
-
74
static void riscv_aplic_request(void *opaque, int irq, int level)
24
{
75
{
25
MachineState *mc = MACHINE(s);
76
bool update = false;
26
uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1;
77
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
27
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
78
* have IRQ lines delegated by their parent APLIC.
28
virt_flash_map(s, system_memory);
79
*/
29
80
if (!aplic->parent) {
30
/* create device tree */
81
- if (is_kvm_aia(aplic->msimode)) {
31
- create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
82
+ if (kvm_enabled() && is_kvm_aia(aplic->msimode)) {
32
- riscv_is_32bit(&s->soc[0]));
83
qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs);
33
+ create_fdt(s, memmap, riscv_is_32bit(&s->soc[0]));
84
} else {
34
85
qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
35
s->machine_done.notify = virt_machine_done;
86
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
36
qemu_add_machine_init_done_notifier(&s->machine_done);
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/riscv/kvm.c
89
+++ b/target/riscv/kvm.c
90
@@ -XXX,XX +XXX,XX @@
91
#include "sysemu/runstate.h"
92
#include "hw/riscv/numa.h"
93
94
+void riscv_kvm_aplic_request(void *opaque, int irq, int level)
95
+{
96
+ kvm_set_irq(kvm_state, irq, !!level);
97
+}
98
+
99
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
100
uint64_t idx)
101
{
37
--
102
--
38
2.39.0
103
2.41.0
104
105
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Robbin Ehn <rehn@rivosinc.com>
2
2
3
There are forward declarations for 'vmstate_htif' and 'htif_io_ops'
3
This patch adds the new extensions in
4
in riscv_htif.h however there are no definitions in the C codes.
4
linux 6.5 to the hwprobe syscall.
5
5
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
6
And fixes RVC check to OR with correct value.
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
The previous variable contains 0 therefore it
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
did work.
9
Message-Id: <20221229091828.1945072-7-bmeng@tinylab.org>
9
10
Signed-off-by: Robbin Ehn <rehn@rivosinc.com>
11
Acked-by: Richard Henderson <richard.henderson@linaro.org>
12
Acked-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <bc82203b72d7efb30f1b4a8f9eb3d94699799dc8.camel@rivosinc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
15
---
12
include/hw/char/riscv_htif.h | 3 ---
16
linux-user/syscall.c | 14 +++++++++++++-
13
1 file changed, 3 deletions(-)
17
1 file changed, 13 insertions(+), 1 deletion(-)
14
18
15
diff --git a/include/hw/char/riscv_htif.h b/include/hw/char/riscv_htif.h
19
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/char/riscv_htif.h
21
--- a/linux-user/syscall.c
18
+++ b/include/hw/char/riscv_htif.h
22
+++ b/linux-user/syscall.c
19
@@ -XXX,XX +XXX,XX @@ typedef struct HTIFState {
23
@@ -XXX,XX +XXX,XX @@ static int do_getdents64(abi_long dirfd, abi_long arg2, abi_long count)
20
uint64_t pending_read;
24
#define RISCV_HWPROBE_KEY_IMA_EXT_0 4
21
} HTIFState;
25
#define RISCV_HWPROBE_IMA_FD (1 << 0)
22
26
#define RISCV_HWPROBE_IMA_C (1 << 1)
23
-extern const VMStateDescription vmstate_htif;
27
+#define RISCV_HWPROBE_IMA_V (1 << 2)
24
-extern const MemoryRegionOps htif_io_ops;
28
+#define RISCV_HWPROBE_EXT_ZBA (1 << 3)
25
-
29
+#define RISCV_HWPROBE_EXT_ZBB (1 << 4)
26
/* HTIF symbol callback */
30
+#define RISCV_HWPROBE_EXT_ZBS (1 << 5)
27
void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value,
31
28
uint64_t st_size);
32
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
33
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
34
@@ -XXX,XX +XXX,XX @@ static void risc_hwprobe_fill_pairs(CPURISCVState *env,
35
riscv_has_ext(env, RVD) ?
36
RISCV_HWPROBE_IMA_FD : 0;
37
value |= riscv_has_ext(env, RVC) ?
38
- RISCV_HWPROBE_IMA_C : pair->value;
39
+ RISCV_HWPROBE_IMA_C : 0;
40
+ value |= riscv_has_ext(env, RVV) ?
41
+ RISCV_HWPROBE_IMA_V : 0;
42
+ value |= cfg->ext_zba ?
43
+ RISCV_HWPROBE_EXT_ZBA : 0;
44
+ value |= cfg->ext_zbb ?
45
+ RISCV_HWPROBE_EXT_ZBB : 0;
46
+ value |= cfg->ext_zbs ?
47
+ RISCV_HWPROBE_EXT_ZBS : 0;
48
__put_user(value, &pair->value);
49
break;
50
case RISCV_HWPROBE_KEY_CPUPERF_0:
29
--
51
--
30
2.39.0
52
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Ard Biesheuvel <ardb@kernel.org>
2
2
3
The Spike HTIF is poorly documented. The only relevant info we can
3
Use the accelerated SubBytes/ShiftRows/AddRoundKey AES helper to
4
get from the internet is from Andrew Waterman at [1].
4
implement the first half of the key schedule derivation. This does not
5
actually involve shifting rows, so clone the same value into all four
6
columns of the AES vector to counter that operation.
5
7
6
Add a comment block before htif_handle_tohost_write() to explain
8
Cc: Richard Henderson <richard.henderson@linaro.org>
7
the tohost register format, and use meaningful macros instead of
9
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
8
magic numbers in the codes.
10
Cc: Palmer Dabbelt <palmer@dabbelt.com>
9
11
Cc: Alistair Francis <alistair.francis@wdc.com>
10
While we are here, correct 2 multi-line comment blocks that have
12
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
11
wrong format.
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Link: https://github.com/riscv-software-src/riscv-isa-sim/issues/364#issuecomment-607657754 [1]
15
Message-ID: <20230831154118.138727-1-ardb@kernel.org>
14
Signed-off-by: Bin Meng <bmeng@tinylab.org>
15
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-Id: <20221229091828.1945072-2-bmeng@tinylab.org>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
17
---
20
hw/char/riscv_htif.c | 72 ++++++++++++++++++++++++++++++++------------
18
target/riscv/crypto_helper.c | 17 +++++------------
21
1 file changed, 52 insertions(+), 20 deletions(-)
19
1 file changed, 5 insertions(+), 12 deletions(-)
22
20
23
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
21
diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c
24
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/char/riscv_htif.c
23
--- a/target/riscv/crypto_helper.c
26
+++ b/hw/char/riscv_htif.c
24
+++ b/target/riscv/crypto_helper.c
27
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(aes64ks1i)(target_ulong rs1, target_ulong rnum)
28
} \
26
29
} while (0)
27
uint8_t enc_rnum = rnum;
30
28
uint32_t temp = (RS1 >> 32) & 0xFFFFFFFF;
31
+#define HTIF_DEV_SHIFT 56
29
- uint8_t rcon_ = 0;
32
+#define HTIF_CMD_SHIFT 48
30
- target_ulong result;
33
+
31
+ AESState t, rc = {};
34
+#define HTIF_DEV_SYSTEM 0
32
35
+#define HTIF_DEV_CONSOLE 1
33
if (enc_rnum != 0xA) {
36
+
34
temp = ror32(temp, 8); /* Rotate right by 8 */
37
+#define HTIF_SYSTEM_CMD_SYSCALL 0
35
- rcon_ = round_consts[enc_rnum];
38
+#define HTIF_CONSOLE_CMD_GETC 0
36
+ rc.w[0] = rc.w[1] = round_consts[enc_rnum];
39
+#define HTIF_CONSOLE_CMD_PUTC 1
40
+
41
static uint64_t fromhost_addr, tohost_addr;
42
static int address_symbol_set;
43
44
@@ -XXX,XX +XXX,XX @@ static void htif_recv(void *opaque, const uint8_t *buf, int size)
45
return;
46
}
37
}
47
38
48
- /* TODO - we need to check whether mfromhost is zero which indicates
39
- temp = ((uint32_t)AES_sbox[(temp >> 24) & 0xFF] << 24) |
49
- the device is ready to receive. The current implementation
40
- ((uint32_t)AES_sbox[(temp >> 16) & 0xFF] << 16) |
50
- will drop characters */
41
- ((uint32_t)AES_sbox[(temp >> 8) & 0xFF] << 8) |
51
+ /*
42
- ((uint32_t)AES_sbox[(temp >> 0) & 0xFF] << 0);
52
+ * TODO - we need to check whether mfromhost is zero which indicates
43
+ t.w[0] = t.w[1] = t.w[2] = t.w[3] = temp;
53
+ * the device is ready to receive. The current implementation
44
+ aesenc_SB_SR_AK(&t, &t, &rc, false);
54
+ * will drop characters
45
55
+ */
46
- temp ^= rcon_;
56
47
-
57
uint64_t val_written = htifstate->pending_read;
48
- result = ((uint64_t)temp << 32) | temp;
58
uint64_t resp = 0x100 | *buf;
49
-
59
@@ -XXX,XX +XXX,XX @@ static int htif_be_change(void *opaque)
50
- return result;
60
return 0;
51
+ return t.d[0];
61
}
52
}
62
53
63
+/*
54
target_ulong HELPER(aes64im)(target_ulong rs1)
64
+ * See below the tohost register format.
65
+ *
66
+ * Bits 63:56 indicate the "device".
67
+ * Bits 55:48 indicate the "command".
68
+ *
69
+ * Device 0 is the syscall device, which is used to emulate Unixy syscalls.
70
+ * It only implements command 0, which has two subfunctions:
71
+ * - If bit 0 is clear, then bits 47:0 represent a pointer to a struct
72
+ * describing the syscall.
73
+ * - If bit 1 is set, then bits 47:1 represent an exit code, with a zero
74
+ * value indicating success and other values indicating failure.
75
+ *
76
+ * Device 1 is the blocking character device.
77
+ * - Command 0 reads a character
78
+ * - Command 1 writes a character from the 8 LSBs of tohost
79
+ *
80
+ * For RV32, the tohost register is zero-extended, so only device=0 and
81
+ * command=0 (i.e. HTIF syscalls/exit codes) are supported.
82
+ */
83
static void htif_handle_tohost_write(HTIFState *htifstate, uint64_t val_written)
84
{
85
- uint8_t device = val_written >> 56;
86
- uint8_t cmd = val_written >> 48;
87
+ uint8_t device = val_written >> HTIF_DEV_SHIFT;
88
+ uint8_t cmd = val_written >> HTIF_CMD_SHIFT;
89
uint64_t payload = val_written & 0xFFFFFFFFFFFFULL;
90
int resp = 0;
91
92
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *htifstate, uint64_t val_written)
93
* 0: riscv-tests Pass/Fail Reporting Only (no syscall proxy)
94
* 1: Console
95
*/
96
- if (unlikely(device == 0x0)) {
97
+ if (unlikely(device == HTIF_DEV_SYSTEM)) {
98
/* frontend syscall handler, shutdown and exit code support */
99
- if (cmd == 0x0) {
100
+ if (cmd == HTIF_SYSTEM_CMD_SYSCALL) {
101
if (payload & 0x1) {
102
/* exit code */
103
int exit_code = payload >> 1;
104
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *htifstate, uint64_t val_written)
105
} else {
106
qemu_log("HTIF device %d: unknown command\n", device);
107
}
108
- } else if (likely(device == 0x1)) {
109
+ } else if (likely(device == HTIF_DEV_CONSOLE)) {
110
/* HTIF Console */
111
- if (cmd == 0x0) {
112
+ if (cmd == HTIF_CONSOLE_CMD_GETC) {
113
/* this should be a queue, but not yet implemented as such */
114
htifstate->pending_read = val_written;
115
htifstate->env->mtohost = 0; /* clear to indicate we read */
116
return;
117
- } else if (cmd == 0x1) {
118
+ } else if (cmd == HTIF_CONSOLE_CMD_PUTC) {
119
qemu_chr_fe_write(&htifstate->chr, (uint8_t *)&payload, 1);
120
resp = 0x100 | (uint8_t)payload;
121
} else {
122
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *htifstate, uint64_t val_written)
123
" payload: %016" PRIx64, device, cmd, payload & 0xFF, payload);
124
}
125
/*
126
- * - latest bbl does not set fromhost to 0 if there is a value in tohost
127
- * - with this code enabled, qemu hangs waiting for fromhost to go to 0
128
- * - with this code disabled, qemu works with bbl priv v1.9.1 and v1.10
129
- * - HTIF needs protocol documentation and a more complete state machine
130
-
131
- while (!htifstate->fromhost_inprogress &&
132
- htifstate->env->mfromhost != 0x0) {
133
- }
134
- */
135
+ * Latest bbl does not set fromhost to 0 if there is a value in tohost.
136
+ * With this code enabled, qemu hangs waiting for fromhost to go to 0.
137
+ * With this code disabled, qemu works with bbl priv v1.9.1 and v1.10.
138
+ * HTIF needs protocol documentation and a more complete state machine.
139
+ *
140
+ * while (!htifstate->fromhost_inprogress &&
141
+ * htifstate->env->mfromhost != 0x0) {
142
+ * }
143
+ */
144
htifstate->env->mfromhost = (val_written >> 48 << 48) | (resp << 16 >> 16);
145
htifstate->env->mtohost = 0; /* clear to indicate we read */
146
}
147
@@ -XXX,XX +XXX,XX @@ static uint64_t htif_mm_read(void *opaque, hwaddr addr, unsigned size)
148
149
/* CPU wrote to an HTIF register */
150
static void htif_mm_write(void *opaque, hwaddr addr,
151
- uint64_t value, unsigned size)
152
+ uint64_t value, unsigned size)
153
{
154
HTIFState *htifstate = opaque;
155
if (addr == TOHOST_OFFSET1) {
156
--
55
--
157
2.39.0
56
2.41.0
57
58
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
At present create_fdt() calls htif_uses_elf_symbols() to determine
3
riscv_trigger_init() had been called on reset events that can happen
4
whether to insert a <reg> property for the HTIF. This unfortunately
4
several times for a CPU and it allocated timers for itrigger. If old
5
creates a hidden dependency to riscv_load_{firmware,kernel} that
5
timers were present, they were simply overwritten by the new timers,
6
create_fdt() must be called after the ELF {firmware,kernel} image
6
resulting in a memory leak.
7
has been loaded.
8
7
9
Decouple such dependency be adding a new parameter to create_fdt(),
8
Divide riscv_trigger_init() into two functions, namely
10
whether custom HTIF base address is used. The flag will be set if
9
riscv_trigger_realize() and riscv_trigger_reset() and call them in
11
non ELF {firmware,kernel} image is given by user.
10
appropriate timing. The timer allocation will happen only once for a
11
CPU in riscv_trigger_realize().
12
12
13
Signed-off-by: Bin Meng <bmeng@tinylab.org>
13
Fixes: 5a4ae64cac ("target/riscv: Add itrigger support when icount is enabled")
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
15
Message-Id: <20221229091828.1945072-13-bmeng@tinylab.org>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-ID: <20230818034059.9146-1-akihiko.odaki@daynix.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
20
---
18
include/hw/char/riscv_htif.h | 5 +--
21
target/riscv/debug.h | 3 ++-
19
hw/char/riscv_htif.c | 17 +++++-----
22
target/riscv/cpu.c | 8 +++++++-
20
hw/riscv/spike.c | 61 ++++++++++++++++++++++++++++++------
23
target/riscv/debug.c | 15 ++++++++++++---
21
3 files changed, 59 insertions(+), 24 deletions(-)
24
3 files changed, 21 insertions(+), 5 deletions(-)
22
25
23
diff --git a/include/hw/char/riscv_htif.h b/include/hw/char/riscv_htif.h
26
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
24
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/char/riscv_htif.h
28
--- a/target/riscv/debug.h
26
+++ b/include/hw/char/riscv_htif.h
29
+++ b/target/riscv/debug.h
27
@@ -XXX,XX +XXX,XX @@ typedef struct HTIFState {
30
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_debug_excp_handler(CPUState *cs);
28
void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value,
31
bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
29
uint64_t st_size);
32
bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
30
33
31
-/* Check if HTIF uses ELF symbols */
34
-void riscv_trigger_init(CPURISCVState *env);
32
-bool htif_uses_elf_symbols(void);
35
+void riscv_trigger_realize(CPURISCVState *env);
33
-
36
+void riscv_trigger_reset_hold(CPURISCVState *env);
34
/* legacy pre qom */
37
35
HTIFState *htif_mm_init(MemoryRegion *address_space, Chardev *chr,
38
bool riscv_itrigger_enabled(CPURISCVState *env);
36
- uint64_t nonelf_base);
39
void riscv_itrigger_update_priv(CPURISCVState *env);
37
+ uint64_t nonelf_base, bool custom_base);
40
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
38
39
#endif
40
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
41
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/char/riscv_htif.c
42
--- a/target/riscv/cpu.c
43
+++ b/hw/char/riscv_htif.c
43
+++ b/target/riscv/cpu.c
44
@@ -XXX,XX +XXX,XX @@
44
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj)
45
#define PK_SYS_WRITE 64
45
46
46
#ifndef CONFIG_USER_ONLY
47
static uint64_t fromhost_addr, tohost_addr;
47
if (cpu->cfg.debug) {
48
-static int address_symbol_set;
48
- riscv_trigger_init(env);
49
49
+ riscv_trigger_reset_hold(env);
50
void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value,
51
uint64_t st_size)
52
{
53
if (strcmp("fromhost", st_name) == 0) {
54
- address_symbol_set |= 1;
55
fromhost_addr = st_value;
56
if (st_size != 8) {
57
error_report("HTIF fromhost must be 8 bytes");
58
exit(1);
59
}
60
} else if (strcmp("tohost", st_name) == 0) {
61
- address_symbol_set |= 2;
62
tohost_addr = st_value;
63
if (st_size != 8) {
64
error_report("HTIF tohost must be 8 bytes");
65
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps htif_mm_ops = {
66
.write = htif_mm_write,
67
};
68
69
-bool htif_uses_elf_symbols(void)
70
-{
71
- return (address_symbol_set == 3) ? true : false;
72
-}
73
-
74
HTIFState *htif_mm_init(MemoryRegion *address_space, Chardev *chr,
75
- uint64_t nonelf_base)
76
+ uint64_t nonelf_base, bool custom_base)
77
{
78
uint64_t base, size, tohost_offset, fromhost_offset;
79
80
- if (!htif_uses_elf_symbols()) {
81
+ if (custom_base) {
82
fromhost_addr = nonelf_base;
83
tohost_addr = nonelf_base + 8;
84
+ } else {
85
+ if (!fromhost_addr || !tohost_addr) {
86
+ error_report("Invalid HTIF fromhost or tohost address");
87
+ exit(1);
88
+ }
89
}
50
}
90
51
91
base = MIN(tohost_addr, fromhost_addr);
52
if (kvm_enabled()) {
92
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
53
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
54
55
riscv_cpu_register_gdb_regs_for_features(cs);
56
57
+#ifndef CONFIG_USER_ONLY
58
+ if (cpu->cfg.debug) {
59
+ riscv_trigger_realize(&cpu->env);
60
+ }
61
+#endif
62
+
63
qemu_init_vcpu(cs);
64
cpu_reset(cs);
65
66
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
93
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/riscv/spike.c
68
--- a/target/riscv/debug.c
95
+++ b/hw/riscv/spike.c
69
+++ b/target/riscv/debug.c
96
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry spike_memmap[] = {
70
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
97
};
71
return false;
98
99
static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
100
- uint64_t mem_size, const char *cmdline, bool is_32_bit)
101
+ uint64_t mem_size, const char *cmdline,
102
+ bool is_32_bit, bool htif_custom_base)
103
{
104
void *fdt;
105
uint64_t addr, size;
106
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
107
108
qemu_fdt_add_subnode(fdt, "/htif");
109
qemu_fdt_setprop_string(fdt, "/htif", "compatible", "ucb,htif0");
110
- if (!htif_uses_elf_symbols()) {
111
+ if (htif_custom_base) {
112
qemu_fdt_setprop_cells(fdt, "/htif", "reg",
113
0x0, memmap[SPIKE_HTIF].base, 0x0, memmap[SPIKE_HTIF].size);
114
}
115
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
116
}
117
}
72
}
118
73
119
+static bool spike_test_elf_image(char *filename)
74
-void riscv_trigger_init(CPURISCVState *env)
75
+void riscv_trigger_realize(CPURISCVState *env)
120
+{
76
+{
121
+ Error *err = NULL;
77
+ int i;
122
+
78
+
123
+ load_elf_hdr(filename, NULL, NULL, &err);
79
+ for (i = 0; i < RV_MAX_TRIGGERS; i++) {
124
+ if (err) {
80
+ env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
125
+ error_free(err);
81
+ riscv_itrigger_timer_cb, env);
126
+ return false;
127
+ } else {
128
+ return true;
129
+ }
82
+ }
130
+}
83
+}
131
+
84
+
132
static void spike_board_init(MachineState *machine)
85
+void riscv_trigger_reset_hold(CPURISCVState *env)
133
{
86
{
134
const MemMapEntry *memmap = spike_memmap;
87
target_ulong tdata1 = build_tdata1(env, TRIGGER_TYPE_AD_MATCH, 0, 0);
135
SpikeState *s = SPIKE_MACHINE(machine);
88
int i;
136
MemoryRegion *system_memory = get_system_memory();
89
@@ -XXX,XX +XXX,XX @@ void riscv_trigger_init(CPURISCVState *env)
137
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
90
env->tdata3[i] = 0;
138
- target_ulong firmware_end_addr, kernel_start_addr;
91
env->cpu_breakpoint[i] = NULL;
139
- const char *firmware_name;
92
env->cpu_watchpoint[i] = NULL;
140
+ target_ulong firmware_end_addr = memmap[SPIKE_DRAM].base;
93
- env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
141
+ target_ulong kernel_start_addr;
94
- riscv_itrigger_timer_cb, env);
142
+ char *firmware_name;
95
+ timer_del(env->itrigger_timer[i]);
143
uint32_t fdt_load_addr;
96
}
144
uint64_t kernel_entry;
145
char *soc_name;
146
int i, base_hartid, hart_count;
147
+ bool htif_custom_base = false;
148
149
/* Check socket count limit */
150
if (SPIKE_SOCKETS_MAX < riscv_socket_count(machine)) {
151
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
152
memory_region_add_subregion(system_memory, memmap[SPIKE_MROM].base,
153
mask_rom);
154
155
- firmware_name = riscv_default_firmware_name(&s->soc[0]);
156
- firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name,
157
- memmap[SPIKE_DRAM].base,
158
- htif_symbol_callback);
159
+ /* Find firmware */
160
+ firmware_name = riscv_find_firmware(machine->firmware,
161
+ riscv_default_firmware_name(&s->soc[0]));
162
+
163
+ /*
164
+ * Test the given firmware or kernel file to see if it is an ELF image.
165
+ * If it is an ELF, we assume it contains the symbols required for
166
+ * the HTIF console, otherwise we fall back to use the custom base
167
+ * passed from device tree for the HTIF console.
168
+ */
169
+ if (!firmware_name && !machine->kernel_filename) {
170
+ htif_custom_base = true;
171
+ } else {
172
+ if (firmware_name) {
173
+ htif_custom_base = !spike_test_elf_image(firmware_name);
174
+ }
175
+ if (!htif_custom_base && machine->kernel_filename) {
176
+ htif_custom_base = !spike_test_elf_image(machine->kernel_filename);
177
+ }
178
+ }
179
+
180
+ /* Load firmware */
181
+ if (firmware_name) {
182
+ firmware_end_addr = riscv_load_firmware(firmware_name,
183
+ memmap[SPIKE_DRAM].base,
184
+ htif_symbol_callback);
185
+ g_free(firmware_name);
186
+ }
187
188
/* Load kernel */
189
if (machine->kernel_filename) {
190
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
191
192
/* Create device tree */
193
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
194
- riscv_is_32bit(&s->soc[0]));
195
+ riscv_is_32bit(&s->soc[0]), htif_custom_base);
196
197
/* Load initrd */
198
if (machine->kernel_filename && machine->initrd_filename) {
199
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
200
fdt_load_addr);
201
202
/* initialize HTIF using symbols found in load_kernel */
203
- htif_mm_init(system_memory, serial_hd(0), memmap[SPIKE_HTIF].base);
204
+ htif_mm_init(system_memory, serial_hd(0), memmap[SPIKE_HTIF].base,
205
+ htif_custom_base);
206
}
97
}
207
208
static void spike_machine_instance_init(Object *obj)
209
--
98
--
210
2.39.0
99
2.41.0
100
101
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Leon Schuermann <leons@opentitan.org>
2
2
3
These are not used anywhere. Drop them.
3
When the rule-lock bypass (RLB) bit is set in the mseccfg CSR, the PMP
4
configuration lock bits must not apply. While this behavior is
5
implemented for the pmpcfgX CSRs, this bit is not respected for
6
changes to the pmpaddrX CSRs. This patch ensures that pmpaddrX CSR
7
writes work even on locked regions when the global rule-lock bypass is
8
enabled.
4
9
5
Signed-off-by: Bin Meng <bmeng@tinylab.org>
10
Signed-off-by: Leon Schuermann <leons@opentitan.org>
6
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Reviewed-by: Mayuresh Chitale <mchitale@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20221229091828.1945072-3-bmeng@tinylab.org>
13
Message-ID: <20230829215046.1430463-1-leon@is.currently.online>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
15
---
11
include/hw/char/riscv_htif.h | 2 --
16
target/riscv/pmp.c | 4 ++++
12
1 file changed, 2 deletions(-)
17
1 file changed, 4 insertions(+)
13
18
14
diff --git a/include/hw/char/riscv_htif.h b/include/hw/char/riscv_htif.h
19
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/char/riscv_htif.h
21
--- a/target/riscv/pmp.c
17
+++ b/include/hw/char/riscv_htif.h
22
+++ b/target/riscv/pmp.c
18
@@ -XXX,XX +XXX,XX @@ typedef struct HTIFState {
23
@@ -XXX,XX +XXX,XX @@ static inline uint8_t pmp_get_a_field(uint8_t cfg)
19
24
*/
20
hwaddr tohost_offset;
25
static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
21
hwaddr fromhost_offset;
26
{
22
- uint64_t tohost_size;
27
+ /* mseccfg.RLB is set */
23
- uint64_t fromhost_size;
28
+ if (MSECCFG_RLB_ISSET(env)) {
24
MemoryRegion mmio;
29
+ return 0;
25
MemoryRegion *address_space;
30
+ }
26
MemoryRegion *main_mem;
31
32
if (env->pmp_state.pmp[pmp_index].cfg_reg & PMP_LOCK) {
33
return 1;
27
--
34
--
28
2.39.0
35
2.41.0
diff view generated by jsdifflib
1
From: Andrew Bresticker <abrestic@rivosinc.com>
1
From: Tommy Wu <tommy.wu@sifive.com>
2
2
3
Per the AIA specification, writes to stimecmp from VS level should
3
According to the new spec, when vsiselect has a reserved value, attempts
4
trap when hvictl.VTI is set since the write may cause vsip.STIP to
4
from M-mode or HS-mode to access vsireg, or from VS-mode to access
5
become unset.
5
sireg, should preferably raise an illegal instruction exception.
6
6
7
Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp support")
7
Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
8
Signed-off-by: Andrew Bresticker <abrestic@rivosinc.com>
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20230816061647.600672-1-tommy.wu@sifive.com>
10
Message-Id: <20221215224541.1423431-2-abrestic@rivosinc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
11
---
13
target/riscv/csr.c | 6 ++++++
12
target/riscv/csr.c | 7 +++++--
14
1 file changed, 6 insertions(+)
13
1 file changed, 5 insertions(+), 2 deletions(-)
15
14
16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/csr.c
17
--- a/target/riscv/csr.c
19
+++ b/target/riscv/csr.c
18
+++ b/target/riscv/csr.c
20
@@ -XXX,XX +XXX,XX @@ static RISCVException write_stimecmp(CPURISCVState *env, int csrno,
19
@@ -XXX,XX +XXX,XX @@ static int rmw_iprio(target_ulong xlen,
21
RISCVCPU *cpu = env_archcpu(env);
20
static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
22
21
target_ulong new_val, target_ulong wr_mask)
23
if (riscv_cpu_virt_enabled(env)) {
22
{
24
+ if (env->hvictl & HVICTL_VTI) {
23
- bool virt;
25
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
24
+ bool virt, isel_reserved;
26
+ }
25
uint8_t *iprio;
27
return write_vstimecmp(env, csrno, val);
26
int ret = -EINVAL;
27
target_ulong priv, isel, vgein;
28
@@ -XXX,XX +XXX,XX @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
29
30
/* Decode register details from CSR number */
31
virt = false;
32
+ isel_reserved = false;
33
switch (csrno) {
34
case CSR_MIREG:
35
iprio = env->miprio;
36
@@ -XXX,XX +XXX,XX @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
37
riscv_cpu_mxl_bits(env)),
38
val, new_val, wr_mask);
39
}
40
+ } else {
41
+ isel_reserved = true;
28
}
42
}
29
43
30
@@ -XXX,XX +XXX,XX @@ static RISCVException write_stimecmph(CPURISCVState *env, int csrno,
44
done:
31
RISCVCPU *cpu = env_archcpu(env);
45
if (ret) {
32
46
- return (env->virt_enabled && virt) ?
33
if (riscv_cpu_virt_enabled(env)) {
47
+ return (env->virt_enabled && virt && !isel_reserved) ?
34
+ if (env->hvictl & HVICTL_VTI) {
48
RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
35
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
36
+ }
37
return write_vstimecmph(env, csrno, val);
38
}
49
}
39
50
return RISCV_EXCP_NONE;
40
--
51
--
41
2.39.0
52
2.41.0
diff view generated by jsdifflib
1
From: Andrew Bresticker <abrestic@rivosinc.com>
1
From: Nikita Shubin <n.shubin@yadro.com>
2
2
3
The current logic attempts to shift the VS-level bits into their correct
3
As per ISA:
4
position in mip while leaving the remaining bits in-tact. This is both
5
pointless and likely incorrect since one would expect that any new, future
6
VS-level interrupts will get their own position in mip rather than sharing
7
with their (H)S-level equivalent. Fix this, and make the logic more
8
readable, by just making off the VS-level bits and shifting them into
9
position.
10
4
11
This also fixes reads of vsip, which would only ever report vsip.VSSIP
5
"For CSRRWI, if rd=x0, then the instruction shall not read the CSR and
12
since the non-writable bits got masked off as well.
6
shall not cause any of the side effects that might occur on a CSR read."
13
7
14
Fixes: d028ac7512f1 ("arget/riscv: Implement AIA CSRs for 64 local interrupts on RV32")
8
trans_csrrwi() and trans_csrrw() call do_csrw() if rd=x0, do_csrw() calls
15
Signed-off-by: Andrew Bresticker <abrestic@rivosinc.com>
9
riscv_csrrw_do64(), via helper_csrw() passing NULL as *ret_value.
10
11
Signed-off-by: Nikita Shubin <n.shubin@yadro.com>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-Id: <20221215224541.1423431-1-abrestic@rivosinc.com>
13
Message-ID: <20230808090914.17634-1-nikita.shubin@maquefel.me>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
15
---
20
target/riscv/csr.c | 35 +++++++++++------------------------
16
target/riscv/csr.c | 24 +++++++++++++++---------
21
1 file changed, 11 insertions(+), 24 deletions(-)
17
1 file changed, 15 insertions(+), 9 deletions(-)
22
18
23
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
19
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
24
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
25
--- a/target/riscv/csr.c
21
--- a/target/riscv/csr.c
26
+++ b/target/riscv/csr.c
22
+++ b/target/riscv/csr.c
27
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_vsie64(CPURISCVState *env, int csrno,
23
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
28
uint64_t new_val, uint64_t wr_mask)
24
target_ulong write_mask)
29
{
25
{
30
RISCVException ret;
26
RISCVException ret;
31
- uint64_t rval, vsbits, mask = env->hideleg & VS_MODE_INTERRUPTS;
27
- target_ulong old_value;
32
+ uint64_t rval, mask = env->hideleg & VS_MODE_INTERRUPTS;
28
+ target_ulong old_value = 0;
33
29
34
/* Bring VS-level bits to correct position */
30
/* execute combined read/write operation if it exists */
35
- vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
31
if (csr_ops[csrno].op) {
36
- new_val &= ~(VS_MODE_INTERRUPTS >> 1);
32
return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
37
- new_val |= vsbits << 1;
38
- vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
39
- wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
40
- wr_mask |= vsbits << 1;
41
+ new_val = (new_val & (VS_MODE_INTERRUPTS >> 1)) << 1;
42
+ wr_mask = (wr_mask & (VS_MODE_INTERRUPTS >> 1)) << 1;
43
44
ret = rmw_mie64(env, csrno, &rval, new_val, wr_mask & mask);
45
if (ret_val) {
46
- rval &= mask;
47
- vsbits = rval & VS_MODE_INTERRUPTS;
48
- rval &= ~VS_MODE_INTERRUPTS;
49
- *ret_val = rval | (vsbits >> 1);
50
+ *ret_val = (rval & mask) >> 1;
51
}
33
}
52
34
53
return ret;
35
- /* if no accessor exists then return failure */
54
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_vsip64(CPURISCVState *env, int csrno,
36
- if (!csr_ops[csrno].read) {
55
uint64_t new_val, uint64_t wr_mask)
37
- return RISCV_EXCP_ILLEGAL_INST;
56
{
38
- }
57
RISCVException ret;
39
- /* read old value */
58
- uint64_t rval, vsbits, mask = env->hideleg & vsip_writable_mask;
40
- ret = csr_ops[csrno].read(env, csrno, &old_value);
59
+ uint64_t rval, mask = env->hideleg & VS_MODE_INTERRUPTS;
41
- if (ret != RISCV_EXCP_NONE) {
60
42
- return ret;
61
/* Bring VS-level bits to correct position */
43
+ /*
62
- vsbits = new_val & (VS_MODE_INTERRUPTS >> 1);
44
+ * ret_value == NULL means that rd=x0 and we're coming from helper_csrw()
63
- new_val &= ~(VS_MODE_INTERRUPTS >> 1);
45
+ * and we can't throw side effects caused by CSR reads.
64
- new_val |= vsbits << 1;
46
+ */
65
- vsbits = wr_mask & (VS_MODE_INTERRUPTS >> 1);
47
+ if (ret_value) {
66
- wr_mask &= ~(VS_MODE_INTERRUPTS >> 1);
48
+ /* if no accessor exists then return failure */
67
- wr_mask |= vsbits << 1;
49
+ if (!csr_ops[csrno].read) {
68
-
50
+ return RISCV_EXCP_ILLEGAL_INST;
69
- ret = rmw_mip64(env, csrno, &rval, new_val, wr_mask & mask);
51
+ }
70
+ new_val = (new_val & (VS_MODE_INTERRUPTS >> 1)) << 1;
52
+ /* read old value */
71
+ wr_mask = (wr_mask & (VS_MODE_INTERRUPTS >> 1)) << 1;
53
+ ret = csr_ops[csrno].read(env, csrno, &old_value);
72
+
54
+ if (ret != RISCV_EXCP_NONE) {
73
+ ret = rmw_mip64(env, csrno, &rval, new_val,
55
+ return ret;
74
+ wr_mask & mask & vsip_writable_mask);
56
+ }
75
if (ret_val) {
76
- rval &= mask;
77
- vsbits = rval & VS_MODE_INTERRUPTS;
78
- rval &= ~VS_MODE_INTERRUPTS;
79
- *ret_val = rval | (vsbits >> 1);
80
+ *ret_val = (rval & mask) >> 1;
81
}
57
}
82
58
83
return ret;
59
/* write value if writable and write mask set, otherwise drop writes */
84
--
60
--
85
2.39.0
61
2.41.0
diff view generated by jsdifflib