1
The following changes since commit ad10b4badc1dd5b28305f9b9f1168cf0aa3ae946:
1
The following changes since commit c5ea91da443b458352c1b629b490ee6631775cb4:
2
2
3
Merge tag 'pull-error-2024-05-27' of https://repo.or.cz/qemu/armbru into staging (2024-05-27 06:40:42 -0700)
3
Merge tag 'pull-trivial-patches' of https://gitlab.com/mjt0k/qemu into staging (2023-09-08 10:06:25 -0400)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20240528
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20230911
8
8
9
for you to fetch changes up to 1806da76cb81088ea026ca3441551782b850e393:
9
for you to fetch changes up to e7a03409f29e2da59297d55afbaec98c96e43e3a:
10
10
11
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR (2024-05-28 12:20:27 +1000)
11
target/riscv: don't read CSR in riscv_csrrw_do64 (2023-09-11 11:45:55 +1000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
RISC-V PR for 9.1
14
First RISC-V PR for 8.2
15
15
16
* APLICs add child earlier than realize
16
* Remove 'host' CPU from TCG
17
* Fix exposure of Zkr
17
* riscv_htif Fixup printing on big endian hosts
18
* Raise exceptions on wrs.nto
18
* Add zmmul isa string
19
* Implement SBI debug console (DBCN) calls for KVM
19
* Add smepmp isa string
20
* Support 64-bit addresses for initrd
20
* Fix page_check_range use in fault-only-first
21
* Change RISCV_EXCP_SEMIHOST exception number to 63
21
* Use existing lookup tables for MixColumns
22
* Tolerate KVM disable ext errors
22
* Add RISC-V vector cryptographic instruction set support
23
* Set tval in breakpoints
23
* Implement WARL behaviour for mcountinhibit/mcounteren
24
* Add support for Zve32x extension
24
* Add Zihintntl extension ISA string to DTS
25
* Add support for Zve64x extension
25
* Fix zfa fleq.d and fltq.d
26
* Relax vector register check in RISCV gdbstub
26
* Fix upper/lower mtime write calculation
27
* Fix the element agnostic Vector function problem
27
* Make rtc variable names consistent
28
* Fix Zvkb extension config
28
* Use abi type for linux-user target_ucontext
29
* Implement dynamic establishment of custom decoder
29
* Add RISC-V KVM AIA Support
30
* Add th.sxstatus CSR emulation
30
* Fix riscv,pmu DT node path in the virt machine
31
* Fix Zvfhmin checking for vfwcvt.f.f.v and vfncvt.f.f.w instructions
31
* Update CSR bits name for svadu extension
32
* Check single width operator for vector fp widen instructions
32
* Mark zicond non-experimental
33
* Check single width operator for vfncvt.rod.f.f.w
33
* Fix satp_mode_finalize() when satp_mode.supported = 0
34
* Remove redudant SEW checking for vector fp narrow/widen instructions
34
* Fix non-KVM --enable-debug build
35
* Prioritize pmp errors in raise_mmu_exception()
35
* Add new extensions to hwprobe
36
* Do not set mtval2 for non guest-page faults
36
* Use accelerated helper for AES64KS1I
37
* Remove experimental prefix from "B" extension
37
* Allocate itrigger timers only once
38
* Fixup CBO extension register calculation
38
* Respect mseccfg.RLB for pmpaddrX changes
39
* Fix the hart bit setting of AIA
39
* Align the AIA model to v1.0 ratified spec
40
* Fix reg_width in ricsv_gen_dynamic_vector_feature()
40
* Don't read the CSR in riscv_csrrw_do64
41
* Decode all of the pmpcfg and pmpaddr CSRs
42
* Raise an exception when CSRRS/CSRRC writes a read-only CSR
43
41
44
----------------------------------------------------------------
42
----------------------------------------------------------------
45
Alexei Filippov (1):
43
Akihiko Odaki (1):
46
target/riscv: do not set mtval2 for non guest-page faults
44
target/riscv: Allocate itrigger timers only once
47
45
48
Alistair Francis (2):
46
Ard Biesheuvel (2):
49
target/riscv: rvzicbo: Fixup CBO extension register calculation
47
target/riscv: Use existing lookup tables for MixColumns
50
disas/riscv: Decode all of the pmpcfg and pmpaddr CSRs
48
target/riscv: Use accelerated helper for AES64KS1I
51
49
52
Andrew Jones (2):
50
Conor Dooley (1):
53
target/riscv/kvm: Fix exposure of Zkr
51
hw/riscv: virt: Fix riscv,pmu DT node path
54
target/riscv: Raise exceptions on wrs.nto
55
56
Cheng Yang (1):
57
hw/riscv/boot.c: Support 64-bit address for initrd
58
59
Christoph Müllner (1):
60
riscv: thead: Add th.sxstatus CSR emulation
61
62
Clément Léger (1):
63
target/riscv: change RISCV_EXCP_SEMIHOST exception number to 63
64
52
65
Daniel Henrique Barboza (6):
53
Daniel Henrique Barboza (6):
66
target/riscv/kvm: implement SBI debug console (DBCN) calls
54
target/riscv/cpu.c: do not run 'host' CPU with TCG
67
target/riscv/kvm: tolerate KVM disable ext errors
55
target/riscv/cpu.c: add zmmul isa string
68
target/riscv/debug: set tval=pc in breakpoint exceptions
56
target/riscv/cpu.c: add smepmp isa string
69
trans_privileged.c.inc: set (m|s)tval on ebreak breakpoint
57
target/riscv: fix satp_mode_finalize() when satp_mode.supported = 0
70
target/riscv: prioritize pmp errors in raise_mmu_exception()
58
hw/riscv/virt.c: fix non-KVM --enable-debug build
71
riscv, gdbstub.c: fix reg_width in ricsv_gen_dynamic_vector_feature()
59
hw/intc/riscv_aplic.c fix non-KVM --enable-debug build
72
60
73
Huang Tao (2):
61
Dickon Hood (2):
74
target/riscv: Fix the element agnostic function problem
62
target/riscv: Refactor translation of vector-widening instruction
75
target/riscv: Implement dynamic establishment of custom decoder
63
target/riscv: Add Zvbb ISA extension support
76
64
77
Jason Chien (3):
65
Jason Chien (3):
78
target/riscv: Add support for Zve32x extension
66
target/riscv: Add Zihintntl extension ISA string to DTS
79
target/riscv: Add support for Zve64x extension
67
hw/intc: Fix upper/lower mtime write calculation
80
target/riscv: Relax vector register check in RISCV gdbstub
68
hw/intc: Make rtc variable names consistent
81
69
82
Max Chou (4):
70
Kiran Ostrolenk (4):
83
target/riscv: rvv: Fix Zvfhmin checking for vfwcvt.f.f.v and vfncvt.f.f.w instructions
71
target/riscv: Refactor some of the generic vector functionality
84
target/riscv: rvv: Check single width operator for vector fp widen instructions
72
target/riscv: Refactor vector-vector translation macro
85
target/riscv: rvv: Check single width operator for vfncvt.rod.f.f.w
73
target/riscv: Refactor some of the generic vector functionality
86
target/riscv: rvv: Remove redudant SEW checking for vector fp narrow/widen instructions
74
target/riscv: Add Zvknh ISA extension support
75
76
LIU Zhiwei (3):
77
target/riscv: Fix page_check_range use in fault-only-first
78
target/riscv: Fix zfa fleq.d and fltq.d
79
linux-user/riscv: Use abi type for target_ucontext
80
81
Lawrence Hunter (2):
82
target/riscv: Add Zvbc ISA extension support
83
target/riscv: Add Zvksh ISA extension support
84
85
Leon Schuermann (1):
86
target/riscv/pmp.c: respect mseccfg.RLB for pmpaddrX changes
87
88
Max Chou (3):
89
crypto: Create sm4_subword
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
87
101
88
Rob Bradford (1):
102
Rob Bradford (1):
89
target/riscv: Remove experimental prefix from "B" extension
103
target/riscv: Implement WARL behaviour for mcountinhibit/mcounteren
90
104
91
Yangyu Chen (1):
105
Robbin Ehn (1):
92
target/riscv/cpu.c: fix Zvkb extension config
106
linux-user/riscv: Add new extensions to hwprobe
93
107
94
Yong-Xuan Wang (1):
108
Thomas Huth (2):
95
target/riscv/kvm.c: Fix the hart bit setting of AIA
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
96
111
97
Yu-Ming Chang (1):
112
Tommy Wu (1):
98
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR
113
target/riscv: Align the AIA model to v1.0 ratified spec
99
114
100
yang.zhang (1):
115
Vineet Gupta (1):
101
hw/intc/riscv_aplic: APLICs should add child earlier than realize
116
riscv: zicond: make non-experimental
102
117
103
MAINTAINERS | 1 +
118
Weiwei Li (1):
104
target/riscv/cpu.h | 11 ++
119
target/riscv: Update CSR bits name for svadu extension
105
target/riscv/cpu_bits.h | 2 +-
106
target/riscv/cpu_cfg.h | 2 +
107
target/riscv/helper.h | 1 +
108
target/riscv/sbi_ecall_interface.h | 17 +++
109
target/riscv/tcg/tcg-cpu.h | 15 +++
110
disas/riscv.c | 65 +++++++++-
111
hw/intc/riscv_aplic.c | 8 +-
112
hw/riscv/boot.c | 4 +-
113
target/riscv/cpu.c | 10 +-
114
target/riscv/cpu_helper.c | 37 +++---
115
target/riscv/csr.c | 71 +++++++++--
116
target/riscv/debug.c | 3 +
117
target/riscv/gdbstub.c | 8 +-
118
target/riscv/kvm/kvm-cpu.c | 157 ++++++++++++++++++++++++-
119
target/riscv/op_helper.c | 17 ++-
120
target/riscv/tcg/tcg-cpu.c | 50 +++++---
121
target/riscv/th_csr.c | 79 +++++++++++++
122
target/riscv/translate.c | 31 +++--
123
target/riscv/vector_internals.c | 22 ++++
124
target/riscv/insn_trans/trans_privileged.c.inc | 2 +
125
target/riscv/insn_trans/trans_rvv.c.inc | 46 +++++---
126
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 +++--
127
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++-
128
target/riscv/meson.build | 1 +
129
26 files changed, 596 insertions(+), 109 deletions(-)
130
create mode 100644 target/riscv/th_csr.c
131
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
raise_mmu_exception(), as is today, is prioritizing guest page faults by
3
The 'host' CPU is available in a CONFIG_KVM build and it's currently
4
checking first if virt_enabled && !first_stage, and then considering the
4
available for all accels, but is a KVM only CPU. This means that in a
5
regular inst/load/store faults.
5
RISC-V KVM capable host we can do things like this:
6
6
7
There's no mention in the spec about guest page fault being a higher
7
$ ./build/qemu-system-riscv64 -M virt,accel=tcg -cpu host --nographic
8
priority that PMP faults. In fact, privileged spec section 3.7.1 says:
8
qemu-system-riscv64: H extension requires priv spec 1.12.0
9
9
10
"Attempting to fetch an instruction from a PMP region that does not have
10
This CPU does not have a priv spec because we don't filter its extensions
11
execute permissions raises an instruction access-fault exception.
11
via priv spec. We shouldn't be reaching riscv_cpu_realize_tcg() at all
12
Attempting to execute a load or load-reserved instruction which accesses
12
with the 'host' CPU.
13
a physical address within a PMP region without read permissions raises a
14
load access-fault exception. Attempting to execute a store,
15
store-conditional, or AMO instruction which accesses a physical address
16
within a PMP region without write permissions raises a store
17
access-fault exception."
18
13
19
So, in fact, we're doing it wrong - PMP faults should always be thrown,
14
We don't have a way to filter the 'host' CPU out of the available CPU
20
regardless of also being a first or second stage fault.
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:
21
18
22
The way riscv_cpu_tlb_fill() and get_physical_address() work is
19
$ ./build/qemu-system-riscv64 -M virt,accel=tcg -cpu host --nographic
23
adequate: a TRANSLATE_PMP_FAIL error is immediately reported and
20
qemu-system-riscv64: 'host' CPU is not compatible with TCG acceleration
24
reflected in the 'pmp_violation' flag. What we need is to change
25
raise_mmu_exception() to prioritize it.
26
21
27
Reported-by: Joseph Chan <jchan@ventanamicro.com>
28
Fixes: 82d53adfbb ("target/riscv/cpu_helper.c: Invalid exception on MMU translation stage")
29
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
30
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
31
Message-ID: <20240413105929.7030-1-alexei.filippov@syntacore.com>
24
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
32
Cc: qemu-stable <qemu-stable@nongnu.org>
25
Message-Id: <20230721133411.474105-1-dbarboza@ventanamicro.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
26
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
34
---
27
---
35
target/riscv/cpu_helper.c | 22 ++++++++++++----------
28
target/riscv/cpu.c | 5 +++++
36
1 file changed, 12 insertions(+), 10 deletions(-)
29
1 file changed, 5 insertions(+)
37
30
38
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
31
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
39
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/cpu_helper.c
33
--- a/target/riscv/cpu.c
41
+++ b/target/riscv/cpu_helper.c
34
+++ b/target/riscv/cpu.c
42
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
35
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize_tcg(DeviceState *dev, Error **errp)
43
36
CPURISCVState *env = &cpu->env;
44
switch (access_type) {
37
Error *local_err = NULL;
45
case MMU_INST_FETCH:
38
46
- if (env->virt_enabled && !first_stage) {
39
+ if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_CPU_HOST)) {
47
+ if (pmp_violation) {
40
+ error_setg(errp, "'host' CPU is not compatible with TCG acceleration");
48
+ cs->exception_index = RISCV_EXCP_INST_ACCESS_FAULT;
41
+ return;
49
+ } else if (env->virt_enabled && !first_stage) {
42
+ }
50
cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT;
43
+
51
} else {
44
riscv_cpu_validate_misa_mxl(cpu, &local_err);
52
- cs->exception_index = pmp_violation ?
45
if (local_err != NULL) {
53
- RISCV_EXCP_INST_ACCESS_FAULT : RISCV_EXCP_INST_PAGE_FAULT;
46
error_propagate(errp, local_err);
54
+ cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT;
55
}
56
break;
57
case MMU_DATA_LOAD:
58
- if (two_stage && !first_stage) {
59
+ if (pmp_violation) {
60
+ cs->exception_index = RISCV_EXCP_LOAD_ACCESS_FAULT;
61
+ } else if (two_stage && !first_stage) {
62
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
63
} else {
64
- cs->exception_index = pmp_violation ?
65
- RISCV_EXCP_LOAD_ACCESS_FAULT : RISCV_EXCP_LOAD_PAGE_FAULT;
66
+ cs->exception_index = RISCV_EXCP_LOAD_PAGE_FAULT;
67
}
68
break;
69
case MMU_DATA_STORE:
70
- if (two_stage && !first_stage) {
71
+ if (pmp_violation) {
72
+ cs->exception_index = RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
73
+ } else if (two_stage && !first_stage) {
74
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
75
} else {
76
- cs->exception_index = pmp_violation ?
77
- RISCV_EXCP_STORE_AMO_ACCESS_FAULT :
78
- RISCV_EXCP_STORE_PAGE_FAULT;
79
+ cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT;
80
}
81
break;
82
default:
83
--
47
--
84
2.45.1
48
2.41.0
49
50
diff view generated by jsdifflib
New patch
1
From: Thomas Huth <thuth@redhat.com>
1
2
3
The character that should be printed is stored in the 64 bit "payload"
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.
9
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>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Message-Id: <20230721094720.902454-2-thuth@redhat.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
19
hw/char/riscv_htif.c | 3 ++-
20
1 file changed, 2 insertions(+), 1 deletion(-)
21
22
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/char/riscv_htif.c
25
+++ b/hw/char/riscv_htif.c
26
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
27
s->tohost = 0; /* clear to indicate we read */
28
return;
29
} else if (cmd == HTIF_CONSOLE_CMD_PUTC) {
30
- 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);
33
resp = 0x100 | (uint8_t)payload;
34
} else {
35
qemu_log("HTIF device %d: unknown command\n", device);
36
--
37
2.41.0
38
39
diff view generated by jsdifflib
New patch
1
From: Thomas Huth <thuth@redhat.com>
1
2
3
Values that have been read via cpu_physical_memory_read() from the
4
guest's memory have to be swapped in case the host endianess differs
5
from the guest.
6
7
Fixes: a6e13e31d5 ("riscv_htif: Support console output via proxy syscall")
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Bin Meng <bmeng@tinylab.org>
11
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
Message-Id: <20230721094720.902454-3-thuth@redhat.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
hw/char/riscv_htif.c | 9 +++++----
16
1 file changed, 5 insertions(+), 4 deletions(-)
17
18
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/char/riscv_htif.c
21
+++ b/hw/char/riscv_htif.c
22
@@ -XXX,XX +XXX,XX @@
23
#include "qemu/timer.h"
24
#include "qemu/error-report.h"
25
#include "exec/address-spaces.h"
26
+#include "exec/tswap.h"
27
#include "sysemu/dma.h"
28
29
#define RISCV_DEBUG_HTIF 0
30
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
31
} else {
32
uint64_t syscall[8];
33
cpu_physical_memory_read(payload, syscall, sizeof(syscall));
34
- if (syscall[0] == PK_SYS_WRITE &&
35
- syscall[1] == HTIF_DEV_CONSOLE &&
36
- syscall[3] == HTIF_CONSOLE_CMD_PUTC) {
37
+ if (tswap64(syscall[0]) == PK_SYS_WRITE &&
38
+ tswap64(syscall[1]) == HTIF_DEV_CONSOLE &&
39
+ tswap64(syscall[3]) == HTIF_CONSOLE_CMD_PUTC) {
40
uint8_t ch;
41
- cpu_physical_memory_read(syscall[2], &ch, 1);
42
+ cpu_physical_memory_read(tswap64(syscall[2]), &ch, 1);
43
qemu_chr_fe_write(&s->chr, &ch, 1);
44
resp = 0x100 | (uint8_t)payload;
45
} else {
46
--
47
2.41.0
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
zmmul was promoted from experimental to ratified in commit 6d00ffad4e95.
4
Add a riscv,isa string for it.
5
6
Fixes: 6d00ffad4e95 ("target/riscv: move zmmul out of the experimental properties")
7
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20230720132424.371132-2-dbarboza@ventanamicro.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/cpu.c | 1 +
14
1 file changed, 1 insertion(+)
15
16
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/cpu.c
19
+++ b/target/riscv/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
21
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
22
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
23
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
24
+ ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
25
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
26
ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
27
ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
28
--
29
2.41.0
diff view generated by jsdifflib
1
From: Rob Bradford <rbradford@rivosinc.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
This extension has now been ratified:
3
The cpu->cfg.epmp extension is still experimental, but it already has a
4
https://jira.riscv.org/browse/RVS-2006 so the "x-" prefix can be
4
'smepmp' riscv,isa string. Add it.
5
removed.
6
5
7
Since this is now a ratified extension add it to the list of extensions
6
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
included in the "max" CPU variant.
7
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
10
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
11
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Message-Id: <20230720132424.371132-3-dbarboza@ventanamicro.com>
14
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
15
Message-ID: <20240514110217.22516-1-rbradford@rivosinc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
11
---
18
target/riscv/cpu.c | 2 +-
12
target/riscv/cpu.c | 1 +
19
target/riscv/tcg/tcg-cpu.c | 2 +-
13
1 file changed, 1 insertion(+)
20
2 files changed, 2 insertions(+), 2 deletions(-)
21
14
22
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
23
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/cpu.c
17
--- a/target/riscv/cpu.c
25
+++ b/target/riscv/cpu.c
18
+++ b/target/riscv/cpu.c
26
@@ -XXX,XX +XXX,XX @@ static const MISAExtInfo misa_ext_info_arr[] = {
19
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
27
MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
20
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
28
MISA_EXT_INFO(RVV, "v", "Vector operations"),
21
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
29
MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
22
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
30
- MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)")
23
+ ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, epmp),
31
+ MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)")
24
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
32
};
25
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
33
26
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
34
static void riscv_cpu_validate_misa_mxl(RISCVCPUClass *mcc)
35
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/tcg/tcg-cpu.c
38
+++ b/target/riscv/tcg/tcg-cpu.c
39
@@ -XXX,XX +XXX,XX @@ static void riscv_init_max_cpu_extensions(Object *obj)
40
const RISCVCPUMultiExtConfig *prop;
41
42
/* Enable RVG, RVJ and RVV that are disabled by default */
43
- riscv_cpu_set_misa_ext(env, env->misa_ext | RVG | RVJ | RVV);
44
+ riscv_cpu_set_misa_ext(env, env->misa_ext | RVB | RVG | RVJ | RVV);
45
46
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
47
isa_ext_update_enabled(cpu, prop->offset, true);
48
--
27
--
49
2.45.1
28
2.41.0
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
2
3
Commit bef6f008b98(accel/tcg: Return bool from page_check_range) converts
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.
7
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-ID: <20230729031618.821-1-zhiwei_liu@linux.alibaba.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/vector_helper.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/vector_helper.c
19
+++ b/target/riscv/vector_helper.c
20
@@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base,
21
cpu_mmu_index(env, false));
22
if (host) {
23
#ifdef CONFIG_USER_ONLY
24
- if (page_check_range(addr, offset, PAGE_READ)) {
25
+ if (!page_check_range(addr, offset, PAGE_READ)) {
26
vl = i;
27
goto ProbeSuccess;
28
}
29
--
30
2.41.0
diff view generated by jsdifflib
1
From: Alexei Filippov <alexei.filippov@syntacore.com>
1
From: Ard Biesheuvel <ardb@kernel.org>
2
2
3
Previous patch fixed the PMP priority in raise_mmu_exception() but we're still
3
The AES MixColumns and InvMixColumns operations are relatively
4
setting mtval2 incorrectly. In riscv_cpu_tlb_fill(), after pmp check in 2 stage
4
expensive 4x4 matrix multiplications in GF(2^8), which is why C
5
translation part, mtval2 will be set in case of successes 2 stage translation but
5
implementations usually rely on precomputed lookup tables rather than
6
failed pmp check.
6
performing the calculations on demand.
7
7
8
In this case we gonna set mtval2 via env->guest_phys_fault_addr in context of
8
Given that we already carry those tables in QEMU, we can just grab the
9
riscv_cpu_tlb_fill(), as this was a guest-page-fault, but it didn't and mtval2
9
right value in the implementation of the RISC-V AES32 instructions. Note
10
should be zero, according to RISCV privileged spec sect. 9.4.4: When a guest
10
that the tables in question are permuted according to the respective
11
page-fault is taken into M-mode, mtval2 is written with either zero or guest
11
Sbox, so we can omit the Sbox lookup as well in this case.
12
physical address that faulted, shifted by 2 bits. *For other traps, mtval2
13
is set to zero...*
14
12
15
Signed-off-by: Alexei Filippov <alexei.filippov@syntacore.com>
13
Cc: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Cc: Zewen Ye <lustrew@foxmail.com>
18
Message-ID: <20240503103052.6819-1-alexei.filippov@syntacore.com>
16
Cc: Weiwei Li <liweiwei@iscas.ac.cn>
19
Cc: qemu-stable <qemu-stable@nongnu.org>
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>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
22
---
22
target/riscv/cpu_helper.c | 12 ++++++------
23
include/crypto/aes.h | 7 +++++++
23
1 file changed, 6 insertions(+), 6 deletions(-)
24
crypto/aes.c | 4 ++--
25
target/riscv/crypto_helper.c | 34 ++++------------------------------
26
3 files changed, 13 insertions(+), 32 deletions(-)
24
27
25
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
28
diff --git a/include/crypto/aes.h b/include/crypto/aes.h
26
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
27
--- a/target/riscv/cpu_helper.c
30
--- a/include/crypto/aes.h
28
+++ b/target/riscv/cpu_helper.c
31
+++ b/include/crypto/aes.h
29
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
32
@@ -XXX,XX +XXX,XX @@ void AES_decrypt(const unsigned char *in, unsigned char *out,
30
__func__, pa, ret, prot_pmp, tlb_size);
33
extern const uint8_t AES_sbox[256];
31
34
extern const uint8_t AES_isbox[256];
32
prot &= prot_pmp;
35
33
- }
36
+/*
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,
59
};
60
61
-static const uint32_t AES_Td0[256] = {
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
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/crypto_helper.c
69
+++ b/target/riscv/crypto_helper.c
70
@@ -XXX,XX +XXX,XX @@
71
#include "crypto/aes-round.h"
72
#include "crypto/sm4.h"
73
74
-#define AES_XTIME(a) \
75
- ((a << 1) ^ ((a & 0x80) ? 0x1b : 0))
34
-
76
-
35
- if (ret != TRANSLATE_SUCCESS) {
77
-#define AES_GFMUL(a, b) (( \
36
+ } else {
78
- (((b) & 0x1) ? (a) : 0) ^ \
37
/*
79
- (((b) & 0x2) ? AES_XTIME(a) : 0) ^ \
38
* Guest physical address translation failed, this is a HS
80
- (((b) & 0x4) ? AES_XTIME(AES_XTIME(a)) : 0) ^ \
39
* level exception
81
- (((b) & 0x8) ? AES_XTIME(AES_XTIME(AES_XTIME(a))) : 0)) & 0xFF)
40
*/
82
-
41
first_stage_error = false;
83
-static inline uint32_t aes_mixcolumn_byte(uint8_t x, bool fwd)
42
- env->guest_phys_fault_addr = (im_address |
84
-{
43
- (address &
85
- uint32_t u;
44
- (TARGET_PAGE_SIZE - 1))) >> 2;
86
-
45
+ if (ret != TRANSLATE_PMP_FAIL) {
87
- if (fwd) {
46
+ env->guest_phys_fault_addr = (im_address |
88
- u = (AES_GFMUL(x, 3) << 24) | (x << 16) | (x << 8) |
47
+ (address &
89
- (AES_GFMUL(x, 2) << 0);
48
+ (TARGET_PAGE_SIZE - 1))) >> 2;
90
- } else {
49
+ }
91
- u = (AES_GFMUL(x, 0xb) << 24) | (AES_GFMUL(x, 0xd) << 16) |
50
}
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)
102
{
103
uint8_t si = rs2 >> shamt;
104
- uint8_t so;
105
uint32_t mixed;
106
target_ulong res;
107
108
if (enc) {
109
- so = AES_sbox[si];
110
if (mix) {
111
- mixed = aes_mixcolumn_byte(so, true);
112
+ mixed = be32_to_cpu(AES_Te0[si]);
113
} else {
114
- mixed = so;
115
+ mixed = AES_sbox[si];
51
}
116
}
52
} else {
117
} else {
118
- so = AES_isbox[si];
119
if (mix) {
120
- mixed = aes_mixcolumn_byte(so, false);
121
+ mixed = be32_to_cpu(AES_Td0[si]);
122
} else {
123
- mixed = so;
124
+ mixed = AES_isbox[si];
125
}
126
}
127
mixed = rol32(mixed, shamt);
53
--
128
--
54
2.45.1
129
2.41.0
130
131
diff view generated by jsdifflib
1
From: Cheng Yang <yangcheng.work@foxmail.com>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
Use qemu_fdt_setprop_u64() instead of qemu_fdt_setprop_cell()
3
Take some functions/macros out of `vector_helper` and put them in a new
4
to set the address of initrd in FDT to support 64-bit address.
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: Cheng Yang <yangcheng.work@foxmail.com>
8
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Message-ID: <tencent_A4482251DD0890F312758FA6B33F60815609@qq.com>
10
Signed-off-by: Max Chou <max.chou@sifive.com>
11
Acked-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-ID: <20230711165917.2629866-2-max.chou@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
14
---
11
hw/riscv/boot.c | 4 ++--
15
target/riscv/vector_internals.h | 182 +++++++++++++++++++++++++++++
12
1 file changed, 2 insertions(+), 2 deletions(-)
16
target/riscv/vector_helper.c | 201 +-------------------------------
17
target/riscv/vector_internals.c | 81 +++++++++++++
18
target/riscv/meson.build | 1 +
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
13
22
14
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
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
15
index XXXXXXX..XXXXXXX 100644
212
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/boot.c
213
--- a/target/riscv/vector_helper.c
17
+++ b/hw/riscv/boot.c
214
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
215
@@ -XXX,XX +XXX,XX @@
19
/* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
216
#include "fpu/softfloat.h"
20
if (fdt) {
217
#include "tcg/tcg-gvec-desc.h"
21
end = start + size;
218
#include "internals.h"
22
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
219
+#include "vector_internals.h"
23
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
220
#include <math.h>
24
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-start", start);
221
25
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-end", end);
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.
291
*
292
@@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz)
293
return scale < 0 ? vlenb >> -scale : vlenb << scale;
294
}
295
296
-/*
297
- * Get number of total elements, including prestart, body and tail elements.
298
- * Note that when LMUL < 1, the tail includes the elements past VLMAX that
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)
312
{
313
return (addr & ~env->cur_pmmask) | env->cur_pmbase;
314
@@ -XXX,XX +XXX,XX @@ static void probe_pages(CPURISCVState *env, target_ulong addr,
26
}
315
}
27
}
316
}
28
317
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
579
index XXXXXXX..XXXXXXX 100644
580
--- a/target/riscv/meson.build
581
+++ b/target/riscv/meson.build
582
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(files(
583
'gdbstub.c',
584
'op_helper.c',
585
'vector_helper.c',
586
+ 'vector_internals.c',
587
'bitmanip_helper.c',
588
'translate.c',
589
'm128_helper.c',
29
--
590
--
30
2.45.1
591
2.41.0
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
The opfv_narrow_check needs to check the single width float operator by
3
Refactor the non SEW-specific stuff out of `GEN_OPIVV_TRANS` into
4
require_rvf.
4
function `opivv_trans` (similar to `opivi_trans`). `opivv_trans` will be
5
used in proceeding vector-crypto commits.
5
6
7
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Signed-off-by: Max Chou <max.chou@sifive.com>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
Message-ID: <20230711165917.2629866-3-max.chou@sifive.com>
8
Cc: qemu-stable <qemu-stable@nongnu.org>
9
Message-ID: <20240322092600.1198921-4-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
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
15
target/riscv/insn_trans/trans_rvv.c.inc | 62 +++++++++++++------------
13
1 file changed, 1 insertion(+)
16
1 file changed, 32 insertions(+), 30 deletions(-)
14
17
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
18
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
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
20
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
21
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
22
@@ -XXX,XX +XXX,XX @@ GEN_OPIWX_WIDEN_TRANS(vwadd_wx)
20
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
23
GEN_OPIWX_WIDEN_TRANS(vwsubu_wx)
21
{
24
GEN_OPIWX_WIDEN_TRANS(vwsub_wx)
22
return opfv_narrow_check(s, a) &&
25
23
+ require_rvf(s) &&
26
+static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
24
require_scale_rvf(s) &&
27
+ gen_helper_gvec_4_ptr *fn, DisasContext *s)
25
(s->sew != MO_8);
28
+{
29
+ uint32_t data = 0;
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
+ data = FIELD_DP32(data, VDATA, VM, vm);
35
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
36
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
37
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
38
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
39
+ tcg_gen_gvec_4_ptr(vreg_ofs(s, vd), vreg_ofs(s, 0), vreg_ofs(s, vs1),
40
+ vreg_ofs(s, vs2), cpu_env, s->cfg_ptr->vlen / 8,
41
+ s->cfg_ptr->vlen / 8, data, fn);
42
+ mark_vs_dirty(s);
43
+ gen_set_label(over);
44
+ return true;
45
+}
46
+
47
/* Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions */
48
/* OPIVV without GVEC IR */
49
-#define GEN_OPIVV_TRANS(NAME, CHECK) \
50
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
51
-{ \
52
- if (CHECK(s, a)) { \
53
- uint32_t data = 0; \
54
- static gen_helper_gvec_4_ptr * const fns[4] = { \
55
- gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
56
- gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
57
- }; \
58
- TCGLabel *over = gen_new_label(); \
59
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
60
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
61
- \
62
- data = FIELD_DP32(data, VDATA, VM, a->vm); \
63
- data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
64
- data = FIELD_DP32(data, VDATA, VTA, s->vta); \
65
- data = \
66
- FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
67
- data = FIELD_DP32(data, VDATA, VMA, s->vma); \
68
- tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
69
- vreg_ofs(s, a->rs1), \
70
- vreg_ofs(s, a->rs2), cpu_env, \
71
- s->cfg_ptr->vlen / 8, \
72
- s->cfg_ptr->vlen / 8, data, \
73
- fns[s->sew]); \
74
- mark_vs_dirty(s); \
75
- gen_set_label(over); \
76
- return true; \
77
- } \
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; \
26
}
90
}
91
92
/*
27
--
93
--
28
2.45.1
94
2.41.0
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
The require_scale_rvf function only checks the double width operator for
3
Remove the redundant "vl == 0" check which is already included within the vstart >= vl check, when vl == 0.
4
the vector floating point widen instructions, so most of the widen
5
checking functions need to add require_rvf for single width operator.
6
4
7
The vfwcvt.f.x.v and vfwcvt.f.xu.v instructions convert single width
5
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
8
integer to double width float, so the opfxv_widen_check function doesn’t
6
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
need require_rvf for the single width operator(integer).
10
11
Signed-off-by: Max Chou <max.chou@sifive.com>
7
Signed-off-by: Max Chou <max.chou@sifive.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
9
Message-ID: <20230711165917.2629866-4-max.chou@sifive.com>
14
Message-ID: <20240322092600.1198921-3-max.chou@sifive.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
11
---
17
target/riscv/insn_trans/trans_rvv.c.inc | 5 +++++
12
target/riscv/insn_trans/trans_rvv.c.inc | 31 +------------------------
18
1 file changed, 5 insertions(+)
13
1 file changed, 1 insertion(+), 30 deletions(-)
19
14
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
15
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
16
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
24
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check)
19
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
25
static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
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,
26
{
92
{
27
return require_rvv(s) &&
93
uint32_t data = 0;
28
+ require_rvf(s) &&
94
TCGLabel *over = gen_new_label();
29
require_scale_rvf(s) &&
95
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
30
(s->sew != MO_8) &&
96
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
31
vext_check_isa_ill(s) &&
97
32
@@ -XXX,XX +XXX,XX @@ GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check)
98
data = FIELD_DP32(data, VDATA, VM, vm);
33
static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
99
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
34
{
100
gen_helper_##NAME##_w, \
35
return require_rvv(s) &&
101
}; \
36
+ require_rvf(s) &&
102
TCGLabel *over = gen_new_label(); \
37
require_scale_rvf(s) &&
103
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
38
(s->sew != MO_8) &&
104
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
39
vext_check_isa_ill(s) &&
105
\
40
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_WIDEN_TRANS(vfwsub_vf)
106
data = FIELD_DP32(data, VDATA, VM, a->vm); \
41
static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
107
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
42
{
108
gen_helper_vmv_v_v_w, gen_helper_vmv_v_v_d,
43
return require_rvv(s) &&
109
};
44
+ require_rvf(s) &&
110
TCGLabel *over = gen_new_label();
45
require_scale_rvf(s) &&
111
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
46
(s->sew != MO_8) &&
112
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
47
vext_check_isa_ill(s) &&
113
48
@@ -XXX,XX +XXX,XX @@ GEN_OPFWV_WIDEN_TRANS(vfwsub_wv)
114
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
49
static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
115
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
50
{
116
vext_check_ss(s, a->rd, 0, 1)) {
51
return require_rvv(s) &&
117
TCGv s1;
52
+ require_rvf(s) &&
118
TCGLabel *over = gen_new_label();
53
require_scale_rvf(s) &&
119
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
54
(s->sew != MO_8) &&
120
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
55
vext_check_isa_ill(s) &&
121
56
@@ -XXX,XX +XXX,XX @@ GEN_OPFVV_TRANS(vfredmin_vs, freduction_check)
122
s1 = get_gpr(s, a->rs1, EXT_SIGN);
57
static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
123
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
58
{
124
gen_helper_vmv_v_x_w, gen_helper_vmv_v_x_d,
59
return reduction_widen_check(s, a) &&
125
};
60
+ require_rvf(s) &&
126
TCGLabel *over = gen_new_label();
61
require_scale_rvf(s) &&
127
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
62
(s->sew != MO_8);
128
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
63
}
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] = {
64
--
253
--
65
2.45.1
254
2.41.0
66
67
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
2
2
3
The th.sxstatus CSR can be used to identify available custom extension
3
This commit adds support for the Zvbc vector-crypto extension, which
4
on T-Head CPUs. The CSR is documented here:
4
consists of the following instructions:
5
https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadsxstatus.adoc
5
6
6
* vclmulh.[vx,vv]
7
An important property of this patch is, that the th.sxstatus MAEE field
7
* vclmul.[vx,vv]
8
is not set (indicating that XTheadMae is not available).
8
9
XTheadMae is a memory attribute extension (similar to Svpbmt) which is
9
Translation functions are defined in
10
implemented in many T-Head CPUs (C906, C910, etc.) and utilizes bits
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
in PTEs that are marked as reserved. QEMU maintainers prefer to not
11
`target/riscv/vcrypto_helper.c`.
12
implement XTheadMae, so we need give kernels a mechanism to identify
12
13
if XTheadMae is available in a system or not. And this patch introduces
13
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
14
this mechanism in QEMU in a way that's compatible with real HW
14
Co-authored-by: Max Chou <max.chou@sifive.com>
15
(i.e., probing the th.sxstatus.MAEE bit).
15
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
16
16
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
17
Further context can be found on the list:
17
Signed-off-by: Max Chou <max.chou@sifive.com>
18
https://lists.gnu.org/archive/html/qemu-devel/2024-02/msg00775.html
18
[max.chou@sifive.com: Exposed x-zvbc property]
19
19
Message-ID: <20230711165917.2629866-5-max.chou@sifive.com>
20
Reviewed-by: LIU Zhiwei <zhiwe_liu@linux.alibaba.com>
21
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
23
Message-ID: <20240429073656.2486732-1-christoph.muellner@vrull.eu>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
21
---
26
MAINTAINERS | 1 +
22
target/riscv/cpu_cfg.h | 1 +
27
target/riscv/cpu.h | 3 ++
23
target/riscv/helper.h | 6 +++
28
target/riscv/cpu.c | 1 +
24
target/riscv/insn32.decode | 6 +++
29
target/riscv/th_csr.c | 79 ++++++++++++++++++++++++++++++++++++++++
25
target/riscv/cpu.c | 9 ++++
30
target/riscv/meson.build | 1 +
26
target/riscv/translate.c | 1 +
31
5 files changed, 85 insertions(+)
27
target/riscv/vcrypto_helper.c | 59 ++++++++++++++++++++++
32
create mode 100644 target/riscv/th_csr.c
28
target/riscv/insn_trans/trans_rvvk.c.inc | 62 ++++++++++++++++++++++++
33
29
target/riscv/meson.build | 3 +-
34
diff --git a/MAINTAINERS b/MAINTAINERS
30
8 files changed, 146 insertions(+), 1 deletion(-)
35
index XXXXXXX..XXXXXXX 100644
31
create mode 100644 target/riscv/vcrypto_helper.c
36
--- a/MAINTAINERS
32
create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc
37
+++ b/MAINTAINERS
33
38
@@ -XXX,XX +XXX,XX @@ L: qemu-riscv@nongnu.org
34
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
39
S: Supported
35
index XXXXXXX..XXXXXXX 100644
40
F: target/riscv/insn_trans/trans_xthead.c.inc
36
--- a/target/riscv/cpu_cfg.h
41
F: target/riscv/xthead*.decode
37
+++ b/target/riscv/cpu_cfg.h
42
+F: target/riscv/th_*
38
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
43
F: disas/riscv-xthead*
39
bool ext_zve32f;
44
40
bool ext_zve64f;
45
RISC-V XVentanaCondOps extension
41
bool ext_zve64d;
46
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
42
+ bool ext_zvbc;
47
index XXXXXXX..XXXXXXX 100644
43
bool ext_zmmul;
48
--- a/target/riscv/cpu.h
44
bool ext_zvfbfmin;
49
+++ b/target/riscv/cpu.h
45
bool ext_zvfbfwma;
50
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_new_csr_seed(target_ulong new_value,
46
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
51
uint8_t satp_mode_max_from_map(uint32_t map);
47
index XXXXXXX..XXXXXXX 100644
52
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
48
--- a/target/riscv/helper.h
53
49
+++ b/target/riscv/helper.h
54
+/* Implemented in th_csr.c */
50
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vfwcvtbf16_f_f_v, void, ptr, ptr, ptr, env, i32)
55
+void th_register_custom_csrs(RISCVCPU *cpu);
51
56
+
52
DEF_HELPER_6(vfwmaccbf16_vv, void, ptr, ptr, ptr, ptr, env, i32)
57
#endif /* RISCV_CPU_H */
53
DEF_HELPER_6(vfwmaccbf16_vf, void, ptr, ptr, i64, ptr, env, i32)
54
+
55
+/* Vector crypto functions */
56
+DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
57
+DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
58
+DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
59
+DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
60
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/riscv/insn32.decode
63
+++ b/target/riscv/insn32.decode
64
@@ -XXX,XX +XXX,XX @@ vfwcvtbf16_f_f_v 010010 . ..... 01101 001 ..... 1010111 @r2_vm
65
# *** Zvfbfwma Standard Extension ***
66
vfwmaccbf16_vv 111011 . ..... ..... 001 ..... 1010111 @r_vm
67
vfwmaccbf16_vf 111011 . ..... ..... 101 ..... 1010111 @r_vm
68
+
69
+# *** Zvbc vector crypto extension ***
70
+vclmul_vv 001100 . ..... ..... 010 ..... 1010111 @r_vm
71
+vclmul_vx 001100 . ..... ..... 110 ..... 1010111 @r_vm
72
+vclmulh_vv 001101 . ..... ..... 010 ..... 1010111 @r_vm
73
+vclmulh_vx 001101 . ..... ..... 110 ..... 1010111 @r_vm
58
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
74
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
59
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
60
--- a/target/riscv/cpu.c
76
--- a/target/riscv/cpu.c
61
+++ b/target/riscv/cpu.c
77
+++ b/target/riscv/cpu.c
62
@@ -XXX,XX +XXX,XX @@ static void rv64_thead_c906_cpu_init(Object *obj)
78
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
63
cpu->cfg.mvendorid = THEAD_VENDOR_ID;
79
ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
64
#ifndef CONFIG_USER_ONLY
80
ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
65
set_satp_mode_max_supported(cpu, VM_1_10_SV39);
81
ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
66
+ th_register_custom_csrs(cpu);
82
+ ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
67
#endif
83
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
68
84
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
69
/* inherited from parent obj via riscv_cpu_init() */
85
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
70
diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
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
108
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/target/riscv/translate.c
111
+++ b/target/riscv/translate.c
112
@@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
113
#include "insn_trans/trans_rvzfa.c.inc"
114
#include "insn_trans/trans_rvzfh.c.inc"
115
#include "insn_trans/trans_rvk.c.inc"
116
+#include "insn_trans/trans_rvvk.c.inc"
117
#include "insn_trans/trans_privileged.c.inc"
118
#include "insn_trans/trans_svinval.c.inc"
119
#include "insn_trans/trans_rvbf16.c.inc"
120
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
71
new file mode 100644
121
new file mode 100644
72
index XXXXXXX..XXXXXXX
122
index XXXXXXX..XXXXXXX
73
--- /dev/null
123
--- /dev/null
74
+++ b/target/riscv/th_csr.c
124
+++ b/target/riscv/vcrypto_helper.c
75
@@ -XXX,XX +XXX,XX @@
125
@@ -XXX,XX +XXX,XX @@
76
+/*
126
+/*
77
+ * T-Head-specific CSRs.
127
+ * RISC-V Vector Crypto Extension Helpers for QEMU.
78
+ *
128
+ *
79
+ * Copyright (c) 2024 VRULL GmbH
129
+ * Copyright (C) 2023 SiFive, Inc.
130
+ * Written by Codethink Ltd and SiFive.
80
+ *
131
+ *
81
+ * This program is free software; you can redistribute it and/or modify it
132
+ * This program is free software; you can redistribute it and/or modify it
82
+ * under the terms and conditions of the GNU General Public License,
133
+ * under the terms and conditions of the GNU General Public License,
83
+ * version 2 or later, as published by the Free Software Foundation.
134
+ * version 2 or later, as published by the Free Software Foundation.
84
+ *
135
+ *
...
...
90
+ * You should have received a copy of the GNU General Public License along with
141
+ * You should have received a copy of the GNU General Public License along with
91
+ * this program. If not, see <http://www.gnu.org/licenses/>.
142
+ * this program. If not, see <http://www.gnu.org/licenses/>.
92
+ */
143
+ */
93
+
144
+
94
+#include "qemu/osdep.h"
145
+#include "qemu/osdep.h"
146
+#include "qemu/host-utils.h"
147
+#include "qemu/bitops.h"
95
+#include "cpu.h"
148
+#include "cpu.h"
96
+#include "cpu_vendorid.h"
149
+#include "exec/memop.h"
97
+
150
+#include "exec/exec-all.h"
98
+#define CSR_TH_SXSTATUS 0x5c0
151
+#include "exec/helper-proto.h"
99
+
152
+#include "internals.h"
100
+/* TH_SXSTATUS bits */
153
+#include "vector_internals.h"
101
+#define TH_SXSTATUS_UCME BIT(16)
154
+
102
+#define TH_SXSTATUS_MAEE BIT(21)
155
+static uint64_t clmul64(uint64_t y, uint64_t x)
103
+#define TH_SXSTATUS_THEADISAEE BIT(22)
156
+{
104
+
157
+ uint64_t result = 0;
105
+typedef struct {
158
+ for (int j = 63; j >= 0; j--) {
106
+ int csrno;
159
+ if ((y >> j) & 1) {
107
+ int (*insertion_test)(RISCVCPU *cpu);
160
+ result ^= (x << j);
108
+ riscv_csr_operations csr_ops;
109
+} riscv_csr;
110
+
111
+static RISCVException smode(CPURISCVState *env, int csrno)
112
+{
113
+ if (riscv_has_ext(env, RVS)) {
114
+ return RISCV_EXCP_NONE;
115
+ }
116
+
117
+ return RISCV_EXCP_ILLEGAL_INST;
118
+}
119
+
120
+static int test_thead_mvendorid(RISCVCPU *cpu)
121
+{
122
+ if (cpu->cfg.mvendorid != THEAD_VENDOR_ID) {
123
+ return -1;
124
+ }
125
+
126
+ return 0;
127
+}
128
+
129
+static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
130
+ target_ulong *val)
131
+{
132
+ /* We don't set MAEE here, because QEMU does not implement MAEE. */
133
+ *val = TH_SXSTATUS_UCME | TH_SXSTATUS_THEADISAEE;
134
+ return RISCV_EXCP_NONE;
135
+}
136
+
137
+static riscv_csr th_csr_list[] = {
138
+ {
139
+ .csrno = CSR_TH_SXSTATUS,
140
+ .insertion_test = test_thead_mvendorid,
141
+ .csr_ops = { "th.sxstatus", smode, read_th_sxstatus }
142
+ }
143
+};
144
+
145
+void th_register_custom_csrs(RISCVCPU *cpu)
146
+{
147
+ for (size_t i = 0; i < ARRAY_SIZE(th_csr_list); i++) {
148
+ int csrno = th_csr_list[i].csrno;
149
+ riscv_csr_operations *csr_ops = &th_csr_list[i].csr_ops;
150
+ if (!th_csr_list[i].insertion_test(cpu)) {
151
+ riscv_set_csr_ops(csrno, csr_ops);
152
+ }
161
+ }
153
+ }
162
+ }
154
+}
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)
155
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
253
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
156
index XXXXXXX..XXXXXXX 100644
254
index XXXXXXX..XXXXXXX 100644
157
--- a/target/riscv/meson.build
255
--- a/target/riscv/meson.build
158
+++ b/target/riscv/meson.build
256
+++ b/target/riscv/meson.build
159
@@ -XXX,XX +XXX,XX @@ riscv_system_ss.add(files(
257
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(files(
160
'monitor.c',
258
'translate.c',
161
'machine.c',
259
'm128_helper.c',
162
'pmu.c',
260
'crypto_helper.c',
163
+ 'th_csr.c',
261
- 'zce_helper.c'
164
'time_helper.c',
262
+ 'zce_helper.c',
165
'riscv-qmp-cmds.c',
263
+ 'vcrypto_helper.c'
166
))
264
))
265
riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c'))
266
167
--
267
--
168
2.45.1
268
2.41.0
169
170
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
According v spec 18.4, only the vfwcvt.f.f.v and vfncvt.f.f.w
3
Move the checks out of `do_opiv{v,x,i}_gvec{,_shift}` functions
4
instructions will be affected by Zvfhmin extension.
4
and into the corresponding macros. This enables the functions to be
5
And the vfwcvt.f.f.v and vfncvt.f.f.w instructions only support the
5
reused in proceeding commits without check duplication.
6
conversions of
7
6
8
* From 1*SEW(16/32) to 2*SEW(32/64)
7
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
9
* From 2*SEW(32/64) to 1*SEW(16/32)
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
9
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
10
Signed-off-by: Max Chou <max.chou@sifive.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Message-ID: <20230711165917.2629866-6-max.chou@sifive.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Message-ID: <20240322092600.1198921-2-max.chou@sifive.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
13
---
17
target/riscv/insn_trans/trans_rvv.c.inc | 20 ++++++++++++++++++--
14
target/riscv/insn_trans/trans_rvv.c.inc | 28 +++++++++++--------------
18
1 file changed, 18 insertions(+), 2 deletions(-)
15
1 file changed, 12 insertions(+), 16 deletions(-)
19
16
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
17
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
18
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
19
--- a/target/riscv/insn_trans/trans_rvv.c.inc
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
20
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
24
@@ -XXX,XX +XXX,XX @@ static bool require_rvf(DisasContext *s)
21
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
25
}
22
gen_helper_gvec_4_ptr *fn)
23
{
24
TCGLabel *over = gen_new_label();
25
- if (!opivv_check(s, a)) {
26
- return false;
27
- }
28
29
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
30
31
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
32
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
33
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
34
}; \
35
+ if (!opivv_check(s, a)) { \
36
+ return false; \
37
+ } \
38
return do_opivv_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
26
}
39
}
27
40
28
+static bool require_rvfmin(DisasContext *s)
41
@@ -XXX,XX +XXX,XX @@ static inline bool
29
+{
42
do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
30
+ if (s->mstatus_fs == EXT_STATUS_DISABLED) {
43
gen_helper_opivx *fn)
31
+ return false;
32
+ }
33
+
34
+ switch (s->sew) {
35
+ case MO_16:
36
+ return s->cfg_ptr->ext_zvfhmin;
37
+ case MO_32:
38
+ return s->cfg_ptr->ext_zve32f;
39
+ default:
40
+ return false;
41
+ }
42
+}
43
+
44
static bool require_scale_rvf(DisasContext *s)
45
{
44
{
46
if (s->mstatus_fs == EXT_STATUS_DISABLED) {
45
- if (!opivx_check(s, a)) {
47
@@ -XXX,XX +XXX,XX @@ static bool require_scale_rvfmin(DisasContext *s)
46
- return false;
48
}
47
- }
49
48
-
50
switch (s->sew) {
49
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
51
- case MO_8:
50
TCGv_i64 src1 = tcg_temp_new_i64();
52
- return s->cfg_ptr->ext_zvfhmin;
51
53
case MO_16:
52
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
54
return s->cfg_ptr->ext_zve32f;
53
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
55
case MO_32:
54
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
56
@@ -XXX,XX +XXX,XX @@ static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
55
}; \
57
static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
56
+ if (!opivx_check(s, a)) { \
57
+ return false; \
58
+ } \
59
return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
60
}
61
62
@@ -XXX,XX +XXX,XX @@ static inline bool
63
do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn,
64
gen_helper_opivx *fn, imm_mode_t imm_mode)
58
{
65
{
59
return opfv_widen_check(s, a) &&
66
- if (!opivx_check(s, a)) {
60
+ require_rvfmin(s) &&
67
- return false;
61
require_scale_rvfmin(s) &&
68
- }
62
(s->sew != MO_8);
69
-
70
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
71
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
72
extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s));
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); \
63
}
82
}
64
@@ -XXX,XX +XXX,XX @@ static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a)
83
@@ -XXX,XX +XXX,XX @@ static inline bool
65
static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
84
do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
85
gen_helper_opivx *fn)
66
{
86
{
67
return opfv_narrow_check(s, a) &&
87
- if (!opivx_check(s, a)) {
68
+ require_rvfmin(s) &&
88
- return false;
69
require_scale_rvfmin(s) &&
89
- }
70
(s->sew != MO_8);
90
-
91
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
92
TCGv_i32 src1 = tcg_temp_new_i32();
93
94
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
95
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
96
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
97
}; \
98
- \
99
+ if (!opivx_check(s, a)) { \
100
+ return false; \
101
+ } \
102
return do_opivx_gvec_shift(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
71
}
103
}
104
72
--
105
--
73
2.45.1
106
2.41.0
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Dickon Hood <dickon.hood@codethink.co.uk>
2
2
3
If the checking functions check both the single and double width
3
Zvbb (implemented in later commit) has a widening instruction, which
4
operators at the same time, then the single width operator checking
4
requires an extra check on the enabled extensions. Refactor
5
functions (require_rvf[min]) will check whether the SEW is 8.
5
GEN_OPIVX_WIDEN_TRANS() to take a check function to avoid reimplementing
6
it.
6
7
8
Signed-off-by: Dickon Hood <dickon.hood@codethink.co.uk>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
7
Signed-off-by: Max Chou <max.chou@sifive.com>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
Message-ID: <20230711165917.2629866-7-max.chou@sifive.com>
9
Cc: qemu-stable <qemu-stable@nongnu.org>
10
Message-ID: <20240322092600.1198921-5-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
target/riscv/insn_trans/trans_rvv.c.inc | 16 ++++------------
15
target/riscv/insn_trans/trans_rvv.c.inc | 52 +++++++++++--------------
14
1 file changed, 4 insertions(+), 12 deletions(-)
16
1 file changed, 23 insertions(+), 29 deletions(-)
15
17
16
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
18
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/insn_trans/trans_rvv.c.inc
20
--- a/target/riscv/insn_trans/trans_rvv.c.inc
19
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
21
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
20
@@ -XXX,XX +XXX,XX @@ static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
22
@@ -XXX,XX +XXX,XX @@ static bool opivx_widen_check(DisasContext *s, arg_rmrr *a)
21
return require_rvv(s) &&
22
require_rvf(s) &&
23
require_scale_rvf(s) &&
24
- (s->sew != MO_8) &&
25
vext_check_isa_ill(s) &&
26
vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
27
}
28
@@ -XXX,XX +XXX,XX @@ static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
29
return require_rvv(s) &&
30
require_rvf(s) &&
31
require_scale_rvf(s) &&
32
- (s->sew != MO_8) &&
33
vext_check_isa_ill(s) &&
34
vext_check_ds(s, a->rd, a->rs2, a->vm);
23
vext_check_ds(s, a->rd, a->rs2, a->vm);
35
}
24
}
36
@@ -XXX,XX +XXX,XX @@ static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
25
37
return require_rvv(s) &&
26
-static bool do_opivx_widen(DisasContext *s, arg_rmrr *a,
38
require_rvf(s) &&
27
- gen_helper_opivx *fn)
39
require_scale_rvf(s) &&
28
-{
40
- (s->sew != MO_8) &&
29
- if (opivx_widen_check(s, a)) {
41
vext_check_isa_ill(s) &&
30
- return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
42
vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
31
- }
32
- return false;
33
-}
34
-
35
-#define GEN_OPIVX_WIDEN_TRANS(NAME) \
36
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
37
-{ \
38
- static gen_helper_opivx * const fns[3] = { \
39
- gen_helper_##NAME##_b, \
40
- gen_helper_##NAME##_h, \
41
- gen_helper_##NAME##_w \
42
- }; \
43
- return do_opivx_widen(s, a, fns[s->sew]); \
44
+#define GEN_OPIVX_WIDEN_TRANS(NAME, CHECK) \
45
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
46
+{ \
47
+ if (CHECK(s, a)) { \
48
+ static gen_helper_opivx * const fns[3] = { \
49
+ gen_helper_##NAME##_b, \
50
+ gen_helper_##NAME##_h, \
51
+ gen_helper_##NAME##_w \
52
+ }; \
53
+ return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s); \
54
+ } \
55
+ return false; \
43
}
56
}
44
@@ -XXX,XX +XXX,XX @@ static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
57
45
return require_rvv(s) &&
58
-GEN_OPIVX_WIDEN_TRANS(vwaddu_vx)
46
require_rvf(s) &&
59
-GEN_OPIVX_WIDEN_TRANS(vwadd_vx)
47
require_scale_rvf(s) &&
60
-GEN_OPIVX_WIDEN_TRANS(vwsubu_vx)
48
- (s->sew != MO_8) &&
61
-GEN_OPIVX_WIDEN_TRANS(vwsub_vx)
49
vext_check_isa_ill(s) &&
62
+GEN_OPIVX_WIDEN_TRANS(vwaddu_vx, opivx_widen_check)
50
vext_check_dd(s, a->rd, a->rs2, a->vm);
63
+GEN_OPIVX_WIDEN_TRANS(vwadd_vx, opivx_widen_check)
51
}
64
+GEN_OPIVX_WIDEN_TRANS(vwsubu_vx, opivx_widen_check)
52
@@ -XXX,XX +XXX,XX @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
65
+GEN_OPIVX_WIDEN_TRANS(vwsub_vx, opivx_widen_check)
53
{
66
54
return opfv_widen_check(s, a) &&
67
/* WIDEN OPIVV with WIDEN */
55
require_rvfmin(s) &&
68
static bool opiwv_widen_check(DisasContext *s, arg_rmrr *a)
56
- require_scale_rvfmin(s) &&
69
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vrem_vx, opivx_check)
57
- (s->sew != MO_8);
70
GEN_OPIVV_WIDEN_TRANS(vwmul_vv, opivv_widen_check)
58
+ require_scale_rvfmin(s);
71
GEN_OPIVV_WIDEN_TRANS(vwmulu_vv, opivv_widen_check)
59
}
72
GEN_OPIVV_WIDEN_TRANS(vwmulsu_vv, opivv_widen_check)
60
73
-GEN_OPIVX_WIDEN_TRANS(vwmul_vx)
61
#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \
74
-GEN_OPIVX_WIDEN_TRANS(vwmulu_vx)
62
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
75
-GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx)
63
{
76
+GEN_OPIVX_WIDEN_TRANS(vwmul_vx, opivx_widen_check)
64
return opfv_narrow_check(s, a) &&
77
+GEN_OPIVX_WIDEN_TRANS(vwmulu_vx, opivx_widen_check)
65
require_rvfmin(s) &&
78
+GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx, opivx_widen_check)
66
- require_scale_rvfmin(s) &&
79
67
- (s->sew != MO_8);
80
/* Vector Single-Width Integer Multiply-Add Instructions */
68
+ require_scale_rvfmin(s);
81
GEN_OPIVV_TRANS(vmacc_vv, opivv_check)
69
}
82
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vnmsub_vx, opivx_check)
70
83
GEN_OPIVV_WIDEN_TRANS(vwmaccu_vv, opivv_widen_check)
71
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
84
GEN_OPIVV_WIDEN_TRANS(vwmacc_vv, opivv_widen_check)
72
{
85
GEN_OPIVV_WIDEN_TRANS(vwmaccsu_vv, opivv_widen_check)
73
return opfv_narrow_check(s, a) &&
86
-GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx)
74
require_rvf(s) &&
87
-GEN_OPIVX_WIDEN_TRANS(vwmacc_vx)
75
- require_scale_rvf(s) &&
88
-GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx)
76
- (s->sew != MO_8);
89
-GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx)
77
+ require_scale_rvf(s);
90
+GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx, opivx_widen_check)
78
}
91
+GEN_OPIVX_WIDEN_TRANS(vwmacc_vx, opivx_widen_check)
79
92
+GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx, opivx_widen_check)
80
#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \
93
+GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx, opivx_widen_check)
81
@@ -XXX,XX +XXX,XX @@ static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
94
82
{
95
/* Vector Integer Merge and Move Instructions */
83
return reduction_widen_check(s, a) &&
96
static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
84
require_rvf(s) &&
85
- require_scale_rvf(s) &&
86
- (s->sew != MO_8);
87
+ require_scale_rvf(s);
88
}
89
90
GEN_OPFVV_WIDEN_TRANS(vfwredusum_vs, freduction_widen_check)
91
--
97
--
92
2.45.1
98
2.41.0
diff view generated by jsdifflib
New patch
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
1
2
3
Move some macros out of `vector_helper` and into `vector_internals`.
4
This ensures they can be used by both vector and vector-crypto helpers
5
(latter implemented in proceeding commits).
6
7
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
8
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
Signed-off-by: Max Chou <max.chou@sifive.com>
10
Message-ID: <20230711165917.2629866-8-max.chou@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/vector_internals.h | 46 +++++++++++++++++++++++++++++++++
14
target/riscv/vector_helper.c | 42 ------------------------------
15
2 files changed, 46 insertions(+), 42 deletions(-)
16
17
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/vector_internals.h
20
+++ b/target/riscv/vector_internals.h
21
@@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
22
/* expand macro args before macro */
23
#define RVVCALL(macro, ...) macro(__VA_ARGS__)
24
25
+/* (TD, T2, TX2) */
26
+#define OP_UU_B uint8_t, uint8_t, uint8_t
27
+#define OP_UU_H uint16_t, uint16_t, uint16_t
28
+#define OP_UU_W uint32_t, uint32_t, uint32_t
29
+#define OP_UU_D uint64_t, uint64_t, uint64_t
30
+
31
/* (TD, T1, T2, TX1, TX2) */
32
#define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
33
#define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t
34
#define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t
35
#define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t
36
37
+#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
38
+static void do_##NAME(void *vd, void *vs2, int i) \
39
+{ \
40
+ TX2 s2 = *((T2 *)vs2 + HS2(i)); \
41
+ *((TD *)vd + HD(i)) = OP(s2); \
42
+}
43
+
44
+#define GEN_VEXT_V(NAME, ESZ) \
45
+void HELPER(NAME)(void *vd, void *v0, void *vs2, \
46
+ CPURISCVState *env, uint32_t desc) \
47
+{ \
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); \
76
}
77
78
+/* Three of the widening shortening macros: */
79
+/* (TD, T1, T2, TX1, TX2) */
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
107
-
108
#define OPFVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
109
static void do_##NAME(void *vd, void *vs2, int i, \
110
CPURISCVState *env) \
111
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_CMP_VF(vmfge_vf_w, uint32_t, H4, vmfge32)
112
GEN_VEXT_CMP_VF(vmfge_vf_d, uint64_t, H8, vmfge64)
113
114
/* Vector Floating-Point Classify Instruction */
115
-#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
116
-static void do_##NAME(void *vd, void *vs2, int i) \
117
-{ \
118
- TX2 s2 = *((T2 *)vs2 + HS2(i)); \
119
- *((TD *)vd + HD(i)) = OP(s2); \
120
-}
121
-
122
-#define GEN_VEXT_V(NAME, ESZ) \
123
-void HELPER(NAME)(void *vd, void *v0, void *vs2, \
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;
152
--
153
2.41.0
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
1
From: Dickon Hood <dickon.hood@codethink.co.uk>
2
2
3
Add support for Zve32x extension and replace some checks for Zve32f with
3
This commit adds support for the Zvbb vector-crypto extension, which
4
Zve32x, since Zve32f depends on Zve32x.
4
consists of the following instructions:
5
5
6
Signed-off-by: Jason Chien <jason.chien@sifive.com>
6
* vrol.[vv,vx]
7
Reviewed-by: Frank Chang <frank.chang@sifive.com>
7
* vror.[vv,vx,vi]
8
Reviewed-by: Max Chou <max.chou@sifive.com>
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]
16
17
Translation functions are defined in
18
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
19
`target/riscv/vcrypto_helper.c`.
20
21
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
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>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
30
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Message-ID: <20240328022343.6871-2-jason.chien@sifive.com>
31
[max.chou@sifive.com: Exposed x-zvbb property]
32
Message-ID: <20230711165917.2629866-9-max.chou@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
34
---
13
target/riscv/cpu_cfg.h | 1 +
35
target/riscv/cpu_cfg.h | 1 +
14
target/riscv/cpu.c | 2 ++
36
target/riscv/helper.h | 62 +++++++++
15
target/riscv/cpu_helper.c | 2 +-
37
target/riscv/insn32.decode | 20 +++
16
target/riscv/csr.c | 2 +-
38
target/riscv/cpu.c | 12 ++
17
target/riscv/tcg/tcg-cpu.c | 16 ++++++++--------
39
target/riscv/vcrypto_helper.c | 138 +++++++++++++++++++
18
target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
40
target/riscv/insn_trans/trans_rvvk.c.inc | 164 +++++++++++++++++++++++
19
6 files changed, 15 insertions(+), 12 deletions(-)
41
6 files changed, 397 insertions(+)
20
42
21
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
43
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
22
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/cpu_cfg.h
45
--- a/target/riscv/cpu_cfg.h
24
+++ b/target/riscv/cpu_cfg.h
46
+++ b/target/riscv/cpu_cfg.h
25
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
47
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
26
bool ext_zhinx;
27
bool ext_zhinxmin;
28
bool ext_zve32f;
48
bool ext_zve32f;
29
+ bool ext_zve32x;
30
bool ext_zve64f;
49
bool ext_zve64f;
31
bool ext_zve64d;
50
bool ext_zve64d;
32
bool ext_zvbb;
51
+ bool ext_zvbb;
52
bool ext_zvbc;
53
bool ext_zmmul;
54
bool ext_zvfbfmin;
55
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/riscv/helper.h
58
+++ b/target/riscv/helper.h
59
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
60
DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
61
DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
62
DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
63
+
64
+DEF_HELPER_6(vror_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
65
+DEF_HELPER_6(vror_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
66
+DEF_HELPER_6(vror_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
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
126
index XXXXXXX..XXXXXXX 100644
127
--- a/target/riscv/insn32.decode
128
+++ b/target/riscv/insn32.decode
129
@@ -XXX,XX +XXX,XX @@
130
%imm_u 12:s20 !function=ex_shift_12
131
%imm_bs 30:2 !function=ex_shift_3
132
%imm_rnum 20:4
133
+%imm_z6 26:1 15:5
134
135
# Argument sets:
136
&empty
137
@@ -XXX,XX +XXX,XX @@
138
@r_vm ...... vm:1 ..... ..... ... ..... ....... &rmrr %rs2 %rs1 %rd
139
@r_vm_1 ...... . ..... ..... ... ..... ....... &rmrr vm=1 %rs2 %rs1 %rd
140
@r_vm_0 ...... . ..... ..... ... ..... ....... &rmrr vm=0 %rs2 %rs1 %rd
141
+@r2_zimm6 ..... . vm:1 ..... ..... ... ..... ....... &rmrr %rs2 rs1=%imm_z6 %rd
142
@r2_zimm11 . zimm:11 ..... ... ..... ....... %rs1 %rd
143
@r2_zimm10 .. zimm:10 ..... ... ..... ....... %rs1 %rd
144
@r2_s ....... ..... ..... ... ..... ....... %rs2 %rs1
145
@@ -XXX,XX +XXX,XX @@ vclmul_vv 001100 . ..... ..... 010 ..... 1010111 @r_vm
146
vclmul_vx 001100 . ..... ..... 110 ..... 1010111 @r_vm
147
vclmulh_vv 001101 . ..... ..... 010 ..... 1010111 @r_vm
148
vclmulh_vx 001101 . ..... ..... 110 ..... 1010111 @r_vm
149
+
150
+# *** Zvbb vector crypto extension ***
151
+vrol_vv 010101 . ..... ..... 000 ..... 1010111 @r_vm
152
+vrol_vx 010101 . ..... ..... 100 ..... 1010111 @r_vm
153
+vror_vv 010100 . ..... ..... 000 ..... 1010111 @r_vm
154
+vror_vx 010100 . ..... ..... 100 ..... 1010111 @r_vm
155
+vror_vi 01010. . ..... ..... 011 ..... 1010111 @r2_zimm6
156
+vbrev8_v 010010 . ..... 01000 010 ..... 1010111 @r2_vm
157
+vrev8_v 010010 . ..... 01001 010 ..... 1010111 @r2_vm
158
+vandn_vv 000001 . ..... ..... 000 ..... 1010111 @r_vm
159
+vandn_vx 000001 . ..... ..... 100 ..... 1010111 @r_vm
160
+vbrev_v 010010 . ..... 01010 010 ..... 1010111 @r2_vm
161
+vclz_v 010010 . ..... 01100 010 ..... 1010111 @r2_vm
162
+vctz_v 010010 . ..... 01101 010 ..... 1010111 @r2_vm
163
+vcpop_v 010010 . ..... 01110 010 ..... 1010111 @r2_vm
164
+vwsll_vv 110101 . ..... ..... 000 ..... 1010111 @r_vm
165
+vwsll_vx 110101 . ..... ..... 100 ..... 1010111 @r_vm
166
+vwsll_vi 110101 . ..... ..... 011 ..... 1010111 @r_vm
33
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
167
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
34
index XXXXXXX..XXXXXXX 100644
168
index XXXXXXX..XXXXXXX 100644
35
--- a/target/riscv/cpu.c
169
--- a/target/riscv/cpu.c
36
+++ b/target/riscv/cpu.c
170
+++ b/target/riscv/cpu.c
37
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
171
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
38
ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
172
ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
173
ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
174
ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
175
+ ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
39
ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
176
ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
40
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
177
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
41
+ ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
42
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
178
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
43
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
44
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
45
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
46
MULTI_EXT_CFG_BOOL("zfh", ext_zfh, false),
47
MULTI_EXT_CFG_BOOL("zfhmin", ext_zfhmin, false),
48
MULTI_EXT_CFG_BOOL("zve32f", ext_zve32f, false),
49
+ MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
50
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
51
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
52
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
53
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/riscv/cpu_helper.c
56
+++ b/target/riscv/cpu_helper.c
57
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
58
*pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
59
*cs_base = 0;
60
61
- if (cpu->cfg.ext_zve32f) {
62
+ if (cpu->cfg.ext_zve32x) {
63
/*
64
* If env->vl equals to VLMAX, we can use generic vector operation
65
* expanders (GVEC) to accerlate the vector operations.
66
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/csr.c
69
+++ b/target/riscv/csr.c
70
@@ -XXX,XX +XXX,XX @@ static RISCVException fs(CPURISCVState *env, int csrno)
71
72
static RISCVException vs(CPURISCVState *env, int csrno)
73
{
74
- if (riscv_cpu_cfg(env)->ext_zve32f) {
75
+ if (riscv_cpu_cfg(env)->ext_zve32x) {
76
#if !defined(CONFIG_USER_ONLY)
77
if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
78
return RISCV_EXCP_ILLEGAL_INST;
79
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/riscv/tcg/tcg-cpu.c
82
+++ b/target/riscv/tcg/tcg-cpu.c
83
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
179
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
84
return;
180
return;
85
}
181
}
86
182
87
- if (cpu->cfg.ext_zve32f && !riscv_has_ext(env, RVF)) {
183
+ /*
88
- error_setg(errp, "Zve32f/Zve64f extensions require F extension");
184
+ * In principle Zve*x would also suffice here, were they supported
89
- return;
185
+ * in qemu
90
+ /* The Zve32f extension depends on the Zve32x extension */
186
+ */
91
+ if (cpu->cfg.ext_zve32f) {
187
+ if (cpu->cfg.ext_zvbb && !cpu->cfg.ext_zve32f) {
92
+ if (!riscv_has_ext(env, RVF)) {
188
+ error_setg(errp,
93
+ error_setg(errp, "Zve32f/Zve64f extensions require F extension");
189
+ "Vector crypto extensions require V or Zve* extensions");
94
+ return;
190
+ return;
95
+ }
191
+ }
96
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
192
+
97
}
193
if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
98
194
error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
99
if (cpu->cfg.ext_zvfh) {
100
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
101
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zvbc), true);
102
}
103
104
- /*
105
- * In principle Zve*x would also suffice here, were they supported
106
- * in qemu
107
- */
108
if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkg ||
109
cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed ||
110
- cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
111
+ cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32x) {
112
error_setg(errp,
113
"Vector crypto extensions require V or Zve* extensions");
114
return;
195
return;
115
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
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
116
index XXXXXXX..XXXXXXX 100644
205
index XXXXXXX..XXXXXXX 100644
117
--- a/target/riscv/insn_trans/trans_rvv.c.inc
206
--- a/target/riscv/vcrypto_helper.c
118
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
207
+++ b/target/riscv/vcrypto_helper.c
119
@@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
208
@@ -XXX,XX +XXX,XX @@
120
{
209
#include "qemu/osdep.h"
121
TCGv s1, dst;
210
#include "qemu/host-utils.h"
122
211
#include "qemu/bitops.h"
123
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
212
+#include "qemu/bswap.h"
124
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
213
#include "cpu.h"
125
return false;
214
#include "exec/memop.h"
126
}
215
#include "exec/exec-all.h"
127
216
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64)
128
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
217
GEN_VEXT_VV(vclmulh_vv, 8)
129
{
218
RVVCALL(OPIVX2, vclmulh_vx, OP_UUU_D, H8, H8, clmulh64)
130
TCGv dst;
219
GEN_VEXT_VX(vclmulh_vx, 8)
131
220
+
132
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
221
+RVVCALL(OPIVV2, vror_vv_b, OP_UUU_B, H1, H1, H1, ror8)
133
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
222
+RVVCALL(OPIVV2, vror_vv_h, OP_UUU_H, H2, H2, H2, ror16)
134
return false;
223
+RVVCALL(OPIVV2, vror_vv_w, OP_UUU_W, H4, H4, H4, ror32)
135
}
224
+RVVCALL(OPIVV2, vror_vv_d, OP_UUU_D, H8, H8, H8, ror64)
136
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)
258
+{
259
+ val = ((val & 0x5555555555555555ull) << 1) |
260
+ ((val & 0xAAAAAAAAAAAAAAAAull) >> 1);
261
+ val = ((val & 0x3333333333333333ull) << 2) |
262
+ ((val & 0xCCCCCCCCCCCCCCCCull) >> 2);
263
+ val = ((val & 0x0F0F0F0F0F0F0F0Full) << 4) |
264
+ ((val & 0xF0F0F0F0F0F0F0F0ull) >> 4);
265
+
266
+ return val;
267
+}
268
+
269
+RVVCALL(OPIVV1, vbrev8_v_b, OP_UU_B, H1, H1, brev8)
270
+RVVCALL(OPIVV1, vbrev8_v_h, OP_UU_H, H2, H2, brev8)
271
+RVVCALL(OPIVV1, vbrev8_v_w, OP_UU_W, H4, H4, brev8)
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
358
index XXXXXXX..XXXXXXX 100644
359
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
360
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
361
@@ -XXX,XX +XXX,XX @@ static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a)
362
363
GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check)
364
GEN_VX_MASKED_TRANS(vclmulh_vx, vclmul_vx_check)
365
+
366
+/*
367
+ * Zvbb
368
+ */
369
+
370
+#define GEN_OPIVI_GVEC_TRANS_CHECK(NAME, IMM_MODE, OPIVX, SUF, CHECK) \
371
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
372
+ { \
373
+ if (CHECK(s, a)) { \
374
+ static gen_helper_opivx *const fns[4] = { \
375
+ gen_helper_##OPIVX##_b, \
376
+ gen_helper_##OPIVX##_h, \
377
+ gen_helper_##OPIVX##_w, \
378
+ gen_helper_##OPIVX##_d, \
379
+ }; \
380
+ return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew], \
381
+ IMM_MODE); \
382
+ } \
383
+ return false; \
384
+ }
385
+
386
+#define GEN_OPIVV_GVEC_TRANS_CHECK(NAME, SUF, CHECK) \
387
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
388
+ { \
389
+ if (CHECK(s, a)) { \
390
+ static gen_helper_gvec_4_ptr *const fns[4] = { \
391
+ gen_helper_##NAME##_b, \
392
+ gen_helper_##NAME##_h, \
393
+ gen_helper_##NAME##_w, \
394
+ gen_helper_##NAME##_d, \
395
+ }; \
396
+ return do_opivv_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
397
+ } \
398
+ return false; \
399
+ }
400
+
401
+#define GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(NAME, SUF, CHECK) \
402
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
403
+ { \
404
+ if (CHECK(s, a)) { \
405
+ static gen_helper_opivx *const fns[4] = { \
406
+ gen_helper_##NAME##_b, \
407
+ gen_helper_##NAME##_h, \
408
+ gen_helper_##NAME##_w, \
409
+ gen_helper_##NAME##_d, \
410
+ }; \
411
+ return do_opivx_gvec_shift(s, a, tcg_gen_gvec_##SUF, \
412
+ fns[s->sew]); \
413
+ } \
414
+ return false; \
415
+ }
416
+
417
+static bool zvbb_vv_check(DisasContext *s, arg_rmrr *a)
418
+{
419
+ return opivv_check(s, a) && s->cfg_ptr->ext_zvbb == true;
420
+}
421
+
422
+static bool zvbb_vx_check(DisasContext *s, arg_rmrr *a)
423
+{
424
+ return opivx_check(s, a) && s->cfg_ptr->ext_zvbb == true;
425
+}
426
+
427
+/* vrol.v[vx] */
428
+GEN_OPIVV_GVEC_TRANS_CHECK(vrol_vv, rotlv, zvbb_vv_check)
429
+GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vrol_vx, rotls, zvbb_vx_check)
430
+
431
+/* vror.v[vxi] */
432
+GEN_OPIVV_GVEC_TRANS_CHECK(vror_vv, rotrv, zvbb_vv_check)
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)
137
--
529
--
138
2.45.1
530
2.41.0
diff view generated by jsdifflib
1
From: Andrew Jones <ajones@ventanamicro.com>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
Implementing wrs.nto to always just return is consistent with the
3
This commit adds support for the Zvkned vector-crypto extension, which
4
specification, as the instruction is permitted to terminate the
4
consists of the following instructions:
5
stall for any reason, but it's not useful for virtualization, where
6
we'd like the guest to trap to the hypervisor in order to allow
7
scheduling of the lock holding VCPU. Change to always immediately
8
raise exceptions when the appropriate conditions are present,
9
otherwise continue to just return. Note, immediately raising
10
exceptions is also consistent with the specification since the
11
time limit that should expire prior to the exception is
12
implementation-specific.
13
5
14
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
6
* vaesef.[vv,vs]
15
Reviewed-by: Christoph Müllner <christoph.muellner@vrull.eu>
7
* vaesdf.[vv,vs]
8
* vaesdm.[vv,vs]
9
* vaesz.vs
10
* vaesem.[vv,vs]
11
* vaeskf1.vi
12
* vaeskf2.vi
13
14
Translation functions are defined in
15
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
16
`target/riscv/vcrypto_helper.c`.
17
18
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
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>
16
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
25
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
26
[max.chou@sifive.com: Imported aes-round.h and exposed x-zvkned
18
Message-ID: <20240424142808.62936-2-ajones@ventanamicro.com>
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>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
32
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
33
---
21
target/riscv/helper.h | 1 +
34
target/riscv/cpu_cfg.h | 1 +
22
target/riscv/op_helper.c | 11 ++++++++
35
target/riscv/helper.h | 14 ++
23
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 ++++++++++++++-------
36
target/riscv/insn32.decode | 14 ++
24
3 files changed, 32 insertions(+), 9 deletions(-)
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(-)
25
41
42
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/riscv/cpu_cfg.h
45
+++ b/target/riscv/cpu_cfg.h
46
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
47
bool ext_zve64d;
48
bool ext_zvbb;
49
bool ext_zvbc;
50
+ bool ext_zvkned;
51
bool ext_zmmul;
52
bool ext_zvfbfmin;
53
bool ext_zvfbfwma;
26
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
54
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
27
index XXXXXXX..XXXXXXX 100644
55
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/helper.h
56
--- a/target/riscv/helper.h
29
+++ b/target/riscv/helper.h
57
+++ b/target/riscv/helper.h
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl)
58
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vandn_vx_b, void, ptr, ptr, tl, ptr, env, i32)
31
DEF_HELPER_1(sret, tl, env)
59
DEF_HELPER_6(vandn_vx_h, void, ptr, ptr, tl, ptr, env, i32)
32
DEF_HELPER_1(mret, tl, env)
60
DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, i32)
33
DEF_HELPER_1(wfi, void, env)
61
DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32)
34
+DEF_HELPER_1(wrs_nto, void, env)
62
+
35
DEF_HELPER_1(tlb_flush, void, env)
63
+DEF_HELPER_2(egs_check, void, i32, env)
36
DEF_HELPER_1(tlb_flush_all, void, env)
64
+
37
/* Native Debug */
65
+DEF_HELPER_4(vaesef_vv, void, ptr, ptr, env, i32)
38
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
66
+DEF_HELPER_4(vaesef_vs, void, ptr, ptr, env, i32)
67
+DEF_HELPER_4(vaesdf_vv, void, ptr, ptr, env, i32)
68
+DEF_HELPER_4(vaesdf_vs, void, ptr, ptr, env, i32)
69
+DEF_HELPER_4(vaesem_vv, void, ptr, ptr, env, i32)
70
+DEF_HELPER_4(vaesem_vs, void, ptr, ptr, env, i32)
71
+DEF_HELPER_4(vaesdm_vv, void, ptr, ptr, env, i32)
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
39
index XXXXXXX..XXXXXXX 100644
77
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/op_helper.c
78
--- a/target/riscv/insn32.decode
41
+++ b/target/riscv/op_helper.c
79
+++ b/target/riscv/insn32.decode
42
@@ -XXX,XX +XXX,XX @@ void helper_wfi(CPURISCVState *env)
80
@@ -XXX,XX +XXX,XX @@
43
}
81
@r_rm ....... ..... ..... ... ..... ....... %rs2 %rs1 %rm %rd
44
}
82
@r2_rm ....... ..... ..... ... ..... ....... %rs1 %rm %rd
45
83
@r2 ....... ..... ..... ... ..... ....... &r2 %rs1 %rd
46
+void helper_wrs_nto(CPURISCVState *env)
84
+@r2_vm_1 ...... . ..... ..... ... ..... ....... &rmr vm=1 %rs2 %rd
47
+{
85
@r2_nfvm ... ... vm:1 ..... ..... ... ..... ....... &r2nfvm %nf %rs1 %rd
48
+ if (env->virt_enabled && (env->priv == PRV_S || env->priv == PRV_U) &&
86
@r2_vm ...... vm:1 ..... ..... ... ..... ....... &rmr %rs2 %rd
49
+ get_field(env->hstatus, HSTATUS_VTW) &&
87
@r1_vm ...... vm:1 ..... ..... ... ..... ....... %rd
50
+ !get_field(env->mstatus, MSTATUS_TW)) {
88
@@ -XXX,XX +XXX,XX @@ vcpop_v 010010 . ..... 01110 010 ..... 1010111 @r2_vm
51
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
89
vwsll_vv 110101 . ..... ..... 000 ..... 1010111 @r_vm
52
+ } else if (env->priv != PRV_M && get_field(env->mstatus, MSTATUS_TW)) {
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) {
53
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
158
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
54
+ }
159
+ }
55
+}
160
+}
56
+
161
+
57
void helper_tlb_flush(CPURISCVState *env)
162
+static inline void xor_round_key(AESState *round_state, AESState *round_key)
58
{
163
+{
59
CPUState *cs = env_cpu(env);
164
+ round_state->v = round_state->v ^ round_key->v;
60
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc b/target/riscv/insn_trans/trans_rvzawrs.c.inc
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
61
index XXXXXXX..XXXXXXX 100644
352
index XXXXXXX..XXXXXXX 100644
62
--- a/target/riscv/insn_trans/trans_rvzawrs.c.inc
353
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
63
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
354
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
64
@@ -XXX,XX +XXX,XX @@
355
@@ -XXX,XX +XXX,XX @@ static bool vwsll_vx_check(DisasContext *s, arg_rmrr *a)
65
* this program. If not, see <http://www.gnu.org/licenses/>.
356
GEN_OPIVV_WIDEN_TRANS(vwsll_vv, vwsll_vv_check)
66
*/
357
GEN_OPIVX_WIDEN_TRANS(vwsll_vx, vwsll_vx_check)
67
358
GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
68
-static bool trans_wrs(DisasContext *ctx)
359
+
69
+static bool trans_wrs_sto(DisasContext *ctx, arg_wrs_sto *a)
360
+/*
70
{
361
+ * Zvkned
71
if (!ctx->cfg_ptr->ext_zawrs) {
362
+ */
72
return false;
363
+
73
@@ -XXX,XX +XXX,XX @@ static bool trans_wrs(DisasContext *ctx)
364
+#define ZVKNED_EGS 4
74
return true;
365
+
75
}
366
+#define GEN_V_UNMASKED_TRANS(NAME, CHECK, EGS) \
76
367
+ static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
77
-#define GEN_TRANS_WRS(insn) \
368
+ { \
78
-static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn *a) \
369
+ if (CHECK(s, a)) { \
79
-{ \
370
+ TCGv_ptr rd_v, rs2_v; \
80
- (void)a; \
371
+ TCGv_i32 desc, egs; \
81
- return trans_wrs(ctx); \
372
+ uint32_t data = 0; \
82
-}
373
+ TCGLabel *over = gen_new_label(); \
83
+static bool trans_wrs_nto(DisasContext *ctx, arg_wrs_nto *a)
374
+ \
84
+{
375
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
85
+ if (!ctx->cfg_ptr->ext_zawrs) {
376
+ /* save opcode for unwinding in case we throw an exception */ \
86
+ return false;
377
+ decode_save_opc(s); \
87
+ }
378
+ egs = tcg_constant_i32(EGS); \
88
379
+ gen_helper_egs_check(egs, cpu_env); \
89
-GEN_TRANS_WRS(wrs_nto)
380
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
90
-GEN_TRANS_WRS(wrs_sto)
381
+ } \
91
+ /*
382
+ \
92
+ * Depending on the mode of execution, mstatus.TW and hstatus.VTW, wrs.nto
383
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
93
+ * should raise an exception when the implementation-specific bounded time
384
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
94
+ * limit has expired. Our time limit is zero, so we either return
385
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
95
+ * immediately, as does our implementation of wrs.sto, or raise an
386
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
96
+ * exception, as handled by the wrs.nto helper.
387
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
97
+ */
388
+ rd_v = tcg_temp_new_ptr(); \
98
+#ifndef CONFIG_USER_ONLY
389
+ rs2_v = tcg_temp_new_ptr(); \
99
+ gen_helper_wrs_nto(tcg_env);
390
+ desc = tcg_constant_i32( \
100
+#endif
391
+ simd_desc(s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, data)); \
101
+
392
+ tcg_gen_addi_ptr(rd_v, cpu_env, vreg_ofs(s, a->rd)); \
102
+ /* We only get here when helper_wrs_nto() doesn't raise an exception. */
393
+ tcg_gen_addi_ptr(rs2_v, cpu_env, vreg_ofs(s, a->rs2)); \
103
+ return trans_wrs_sto(ctx, NULL);
394
+ gen_helper_##NAME(rd_v, rs2_v, cpu_env, desc); \
104
+}
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)
105
--
506
--
106
2.45.1
507
2.41.0
107
108
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
Add support for Zve64x extension. Enabling Zve64f enables Zve64x and
3
This commit adds support for the Zvknh vector-crypto extension, which
4
enabling Zve64x enables Zve32x according to their dependency.
4
consists of the following instructions:
5
5
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2107
6
* vsha2ms.vv
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
7
* vsha2c[hl].vv
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
9
Reviewed-by: Max Chou <max.chou@sifive.com>
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>
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
20
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Message-ID: <20240328022343.6871-3-jason.chien@sifive.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>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
26
---
14
target/riscv/cpu_cfg.h | 1 +
27
target/riscv/cpu_cfg.h | 2 +
15
target/riscv/cpu.c | 2 ++
28
target/riscv/helper.h | 6 +
16
target/riscv/tcg/tcg-cpu.c | 17 +++++++++++------
29
target/riscv/insn32.decode | 5 +
17
3 files changed, 14 insertions(+), 6 deletions(-)
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(-)
18
34
19
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
35
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
20
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu_cfg.h
37
--- a/target/riscv/cpu_cfg.h
22
+++ b/target/riscv/cpu_cfg.h
38
+++ b/target/riscv/cpu_cfg.h
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
39
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
24
bool ext_zve32x;
25
bool ext_zve64f;
26
bool ext_zve64d;
27
+ bool ext_zve64x;
28
bool ext_zvbb;
40
bool ext_zvbb;
29
bool ext_zvbc;
41
bool ext_zvbc;
30
bool ext_zvkb;
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
31
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
75
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
32
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/cpu.c
77
--- a/target/riscv/cpu.c
34
+++ b/target/riscv/cpu.c
78
+++ b/target/riscv/cpu.c
35
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
79
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
36
ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
37
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
38
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
39
+ ISA_EXT_DATA_ENTRY(zve64x, PRIV_VERSION_1_10_0, ext_zve64x),
40
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
41
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
42
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
80
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
43
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
81
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
44
MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
82
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
45
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
83
+ ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
46
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
84
+ ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
47
+ MULTI_EXT_CFG_BOOL("zve64x", ext_zve64x, false),
85
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
48
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
86
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
49
MULTI_EXT_CFG_BOOL("zvfbfwma", ext_zvfbfwma, false),
87
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
50
MULTI_EXT_CFG_BOOL("zvfh", ext_zvfh, false),
51
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/tcg/tcg-cpu.c
54
+++ b/target/riscv/tcg/tcg-cpu.c
55
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
88
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
56
89
* In principle Zve*x would also suffice here, were they supported
57
/* The Zve64d extension depends on the Zve64f extension */
90
* in qemu
58
if (cpu->cfg.ext_zve64d) {
91
*/
59
+ if (!riscv_has_ext(env, RVD)) {
92
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) && !cpu->cfg.ext_zve32f) {
60
+ error_setg(errp, "Zve64d/V extensions require D extension");
93
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
61
+ return;
94
+ !cpu->cfg.ext_zve32f) {
62
+ }
95
error_setg(errp,
63
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64f), true);
96
"Vector crypto extensions require V or Zve* extensions");
64
}
65
66
- /* The Zve64f extension depends on the Zve32f extension */
67
+ /* The Zve64f extension depends on the Zve64x and Zve32f extensions */
68
if (cpu->cfg.ext_zve64f) {
69
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64x), true);
70
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32f), true);
71
}
72
73
- if (cpu->cfg.ext_zve64d && !riscv_has_ext(env, RVD)) {
74
- error_setg(errp, "Zve64d/V extensions require D extension");
75
- return;
76
+ /* The Zve64x extension depends on the Zve32x extension */
77
+ if (cpu->cfg.ext_zve64x) {
78
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
79
}
80
81
/* The Zve32f extension depends on the Zve32x extension */
82
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
83
return;
97
return;
84
}
98
}
85
99
86
- if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
100
- if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
87
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64x) {
101
- error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
88
error_setg(
102
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
89
errp,
103
+ error_setg(
90
- "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
104
+ errp,
91
+ "Zvbc and Zvknhb extensions require V or Zve64x extensions");
105
+ "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
92
return;
106
return;
93
}
107
}
94
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
+}
95
--
501
--
96
2.45.1
502
2.41.0
diff view generated by jsdifflib
New patch
1
1
From: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
2
3
This commit adds support for the Zvksh vector-crypto extension, which
4
consists of the following instructions:
5
6
* vsm3me.vv
7
* vsm3c.vi
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>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
---
23
target/riscv/cpu_cfg.h | 1 +
24
target/riscv/helper.h | 3 +
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
66
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/cpu.c
69
+++ b/target/riscv/cpu.c
70
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
71
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
72
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
73
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
74
+ ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh),
75
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
76
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
77
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
78
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
79
* In principle Zve*x would also suffice here, were they supported
80
* in qemu
81
*/
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)
278
--
279
2.41.0
diff view generated by jsdifflib
New patch
1
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
3
This commit adds support for the Zvkg vector-crypto extension, which
4
consists of the following instructions:
5
6
* vgmul.vv
7
* vghsh.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: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
14
[max.chou@sifive.com: Replaced vstart checking by TCG op]
15
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
16
Signed-off-by: Nazar Kazakov <nazar.kazakov@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-zvkg property]
20
[max.chou@sifive.com: Replaced uint by int for cross win32 build]
21
Message-ID: <20230711165917.2629866-13-max.chou@sifive.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
24
target/riscv/cpu_cfg.h | 1 +
25
target/riscv/helper.h | 3 +
26
target/riscv/insn32.decode | 4 ++
27
target/riscv/cpu.c | 6 +-
28
target/riscv/vcrypto_helper.c | 72 ++++++++++++++++++++++++
29
target/riscv/insn_trans/trans_rvvk.c.inc | 30 ++++++++++
30
6 files changed, 114 insertions(+), 2 deletions(-)
31
32
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/cpu_cfg.h
35
+++ b/target/riscv/cpu_cfg.h
36
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
37
bool ext_zve64d;
38
bool ext_zvbb;
39
bool ext_zvbc;
40
+ bool ext_zvkg;
41
bool ext_zvkned;
42
bool ext_zvknha;
43
bool ext_zvknhb;
44
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/riscv/helper.h
47
+++ b/target/riscv/helper.h
48
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
49
50
DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
51
DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
52
+
53
+DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
54
+DEF_HELPER_4(vgmul_vv, 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 @@ vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
60
# *** Zvksh vector crypto extension ***
61
vsm3me_vv 100000 1 ..... ..... 010 ..... 1110111 @r_vm_1
62
vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
63
+
64
+# *** Zvkg vector crypto extension ***
65
+vghsh_vv 101100 1 ..... ..... 010 ..... 1110111 @r_vm_1
66
+vgmul_vv 101000 1 ..... 10001 010 ..... 1110111 @r2_vm_1
67
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/riscv/cpu.c
70
+++ b/target/riscv/cpu.c
71
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
72
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
73
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
74
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
75
+ ISA_EXT_DATA_ENTRY(zvkg, PRIV_VERSION_1_12_0, ext_zvkg),
76
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
77
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
78
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
79
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
80
* In principle Zve*x would also suffice here, were they supported
81
* in qemu
82
*/
83
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
84
- cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
85
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
86
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) && !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
/* Vector cryptography extensions */
92
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
93
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
94
+ DEFINE_PROP_BOOL("x-zvkg", RISCVCPU, cfg.ext_zvkg, false),
95
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
96
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
97
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
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)
216
--
217
2.41.0
diff view generated by jsdifflib
New patch
1
From: Max Chou <max.chou@sifive.com>
1
2
3
Allows sharing of sm4_subword between different targets.
4
5
Signed-off-by: Max Chou <max.chou@sifive.com>
6
Reviewed-by: Frank Chang <frank.chang@sifive.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Max Chou <max.chou@sifive.com>
9
Message-ID: <20230711165917.2629866-14-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
include/crypto/sm4.h | 8 ++++++++
13
target/arm/tcg/crypto_helper.c | 10 ++--------
14
2 files changed, 10 insertions(+), 8 deletions(-)
15
16
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/crypto/sm4.h
19
+++ b/include/crypto/sm4.h
20
@@ -XXX,XX +XXX,XX @@
21
22
extern const uint8_t sm4_sbox[256];
23
24
+static inline uint32_t sm4_subword(uint32_t word)
25
+{
26
+ return sm4_sbox[word & 0xff] |
27
+ sm4_sbox[(word >> 8) & 0xff] << 8 |
28
+ sm4_sbox[(word >> 16) & 0xff] << 16 |
29
+ sm4_sbox[(word >> 24) & 0xff] << 24;
30
+}
31
+
32
#endif
33
diff --git a/target/arm/tcg/crypto_helper.c b/target/arm/tcg/crypto_helper.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/tcg/crypto_helper.c
36
+++ b/target/arm/tcg/crypto_helper.c
37
@@ -XXX,XX +XXX,XX @@ static void do_crypto_sm4e(uint64_t *rd, uint64_t *rn, uint64_t *rm)
38
CR_ST_WORD(d, (i + 3) % 4) ^
39
CR_ST_WORD(n, i);
40
41
- t = sm4_sbox[t & 0xff] |
42
- sm4_sbox[(t >> 8) & 0xff] << 8 |
43
- sm4_sbox[(t >> 16) & 0xff] << 16 |
44
- sm4_sbox[(t >> 24) & 0xff] << 24;
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
}
61
--
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
New patch
1
1
From: Max Chou <max.chou@sifive.com>
2
3
This commit adds support for the Zvksed vector-crypto extension, which
4
consists of the following instructions:
5
6
* vsm4k.vi
7
* vsm4r.[vv,vs]
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
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>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
---
23
target/riscv/cpu_cfg.h | 1 +
24
target/riscv/helper.h | 4 +
25
target/riscv/insn32.decode | 5 +
26
target/riscv/cpu.c | 5 +-
27
target/riscv/vcrypto_helper.c | 127 +++++++++++++++++++++++
28
target/riscv/insn_trans/trans_rvvk.c.inc | 43 ++++++++
29
6 files changed, 184 insertions(+), 1 deletion(-)
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_zvksed;
40
bool ext_zvksh;
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)
291
--
292
2.41.0
diff view generated by jsdifflib
1
From: Huang Tao <eric.huang@linux.alibaba.com>
1
From: Rob Bradford <rbradford@rivosinc.com>
2
2
3
In RVV and vcrypto instructions, the masked and tail elements are set to 1s
3
These are WARL fields - zero out the bits for unavailable counters and
4
using vext_set_elems_1s function if the vma/vta bit is set. It is the element
4
special case the TM bit in mcountinhibit which is hardwired to zero.
5
agnostic policy.
5
This patch achieves this by modifying the value written so that any use
6
of the field will see the correctly masked bits.
6
7
7
However, this function can't deal the big endian situation. This patch fixes
8
Tested by modifying OpenSBI to write max value to these CSRs and upon
8
the problem by adding handling of such case.
9
subsequent read the appropriate number of bits for number of PMUs is
10
enabled and the TM bit is zero in mcountinhibit.
9
11
10
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
12
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
11
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
14
Reviewed-by: Atish Patra <atishp@rivosinc.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
15
Message-ID: <20230802124906.24197-1-rbradford@rivosinc.com>
14
Message-ID: <20240325021654.6594-1-eric.huang@linux.alibaba.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
---
17
target/riscv/vector_internals.c | 22 ++++++++++++++++++++++
18
target/riscv/csr.c | 11 +++++++++--
18
1 file changed, 22 insertions(+)
19
1 file changed, 9 insertions(+), 2 deletions(-)
19
20
20
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
21
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
21
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/vector_internals.c
23
--- a/target/riscv/csr.c
23
+++ b/target/riscv/vector_internals.c
24
+++ b/target/riscv/csr.c
24
@@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
25
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
25
if (tot - cnt == 0) {
26
{
26
return ;
27
int cidx;
27
}
28
PMUCTRState *counter;
29
+ RISCVCPU *cpu = env_archcpu(env);
30
31
- env->mcountinhibit = val;
32
+ /* WARL register - disable unavailable counters; TM bit is always 0 */
33
+ env->mcountinhibit =
34
+ val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_IR);
35
36
/* Check if any other counter is also monitoring cycles/instructions */
37
for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
38
@@ -XXX,XX +XXX,XX @@ static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
39
static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
40
target_ulong val)
41
{
42
- env->mcounteren = val;
43
+ RISCVCPU *cpu = env_archcpu(env);
28
+
44
+
29
+ if (HOST_BIG_ENDIAN) {
45
+ /* WARL register - disable unavailable counters */
30
+ /*
46
+ env->mcounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
31
+ * Deal the situation when the elements are insdie
47
+ COUNTEREN_IR);
32
+ * only one uint64 block including setting the
48
return RISCV_EXCP_NONE;
33
+ * masked-off element.
34
+ */
35
+ if (((tot - 1) ^ cnt) < 8) {
36
+ memset(base + H1(tot - 1), -1, tot - cnt);
37
+ return;
38
+ }
39
+ /*
40
+ * Otherwise, at least cross two uint64_t blocks.
41
+ * Set first unaligned block.
42
+ */
43
+ if (cnt % 8 != 0) {
44
+ uint32_t j = ROUND_UP(cnt, 8);
45
+ memset(base + H1(j - 1), -1, j - cnt);
46
+ cnt = j;
47
+ }
48
+ /* Set other 64bit aligend blocks */
49
+ }
50
memset(base + cnt, -1, tot - cnt);
51
}
49
}
52
50
53
--
51
--
54
2.45.1
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
1
From: Alistair Francis <alistair23@gmail.com>
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
2
3
When running the instruction
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.
4
6
5
```
7
Fixes: a47842d ("riscv: Add support for the Zfa extension")
6
cbo.flush 0(x0)
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
7
```
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
QEMU would segfault.
11
Message-ID: <20230728003906.768-1-zhiwei_liu@linux.alibaba.com>
10
11
The issue was in cpu_gpr[a->rs1] as QEMU does not have cpu_gpr[0]
12
allocated.
13
14
In order to fix this let's use the existing get_address()
15
helper. This also has the benefit of performing pointer mask
16
calculations on the address specified in rs1.
17
18
The pointer masking specificiation specifically states:
19
20
"""
21
Cache Management Operations: All instructions in Zicbom, Zicbop and Zicboz
22
"""
23
24
So this is the correct behaviour and we previously have been incorrectly
25
not masking the address.
26
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
Reported-by: Fabian Thomas <fabian.thomas@cispa.de>
29
Fixes: e05da09b7cfd ("target/riscv: implement Zicbom extension")
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Cc: qemu-stable <qemu-stable@nongnu.org>
32
Message-ID: <20240514023910.301766-1-alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
34
---
13
---
35
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++++++++++++----
14
target/riscv/insn_trans/trans_rvzfa.c.inc | 4 ++--
36
1 file changed, 12 insertions(+), 4 deletions(-)
15
1 file changed, 2 insertions(+), 2 deletions(-)
37
16
38
diff --git a/target/riscv/insn_trans/trans_rvzicbo.c.inc b/target/riscv/insn_trans/trans_rvzicbo.c.inc
17
diff --git a/target/riscv/insn_trans/trans_rvzfa.c.inc b/target/riscv/insn_trans/trans_rvzfa.c.inc
39
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/insn_trans/trans_rvzicbo.c.inc
19
--- a/target/riscv/insn_trans/trans_rvzfa.c.inc
41
+++ b/target/riscv/insn_trans/trans_rvzicbo.c.inc
20
+++ b/target/riscv/insn_trans/trans_rvzfa.c.inc
42
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ bool trans_fleq_d(DisasContext *ctx, arg_fleq_d *a)
43
static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a)
22
TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
44
{
23
TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
45
REQUIRE_ZICBOM(ctx);
24
46
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
25
- gen_helper_fltq_s(dest, cpu_env, src1, src2);
47
+ TCGv src = get_address(ctx, a->rs1, 0);
26
+ gen_helper_fleq_d(dest, cpu_env, src1, src2);
48
+
27
gen_set_gpr(ctx, a->rd, dest);
49
+ gen_helper_cbo_clean_flush(tcg_env, src);
50
return true;
28
return true;
51
}
29
}
52
30
@@ -XXX,XX +XXX,XX @@ bool trans_fltq_d(DisasContext *ctx, arg_fltq_d *a)
53
static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a)
31
TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
54
{
32
TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
55
REQUIRE_ZICBOM(ctx);
33
56
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
34
- gen_helper_fltq_s(dest, cpu_env, src1, src2);
57
+ TCGv src = get_address(ctx, a->rs1, 0);
35
+ gen_helper_fltq_d(dest, cpu_env, src1, src2);
58
+
36
gen_set_gpr(ctx, a->rd, dest);
59
+ gen_helper_cbo_clean_flush(tcg_env, src);
60
return true;
61
}
62
63
static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a)
64
{
65
REQUIRE_ZICBOM(ctx);
66
- gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]);
67
+ TCGv src = get_address(ctx, a->rs1, 0);
68
+
69
+ gen_helper_cbo_inval(tcg_env, src);
70
return true;
71
}
72
73
static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a)
74
{
75
REQUIRE_ZICBOZ(ctx);
76
- gen_helper_cbo_zero(tcg_env, cpu_gpr[a->rs1]);
77
+ TCGv src = get_address(ctx, a->rs1, 0);
78
+
79
+ gen_helper_cbo_zero(tcg_env, src);
80
return true;
37
return true;
81
}
38
}
82
--
39
--
83
2.45.1
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
1
From: Jason Chien <jason.chien@sifive.com>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
In current implementation, the gdbstub allows reading vector registers
3
The variables whose values are given by cpu_riscv_read_rtc() should be named
4
only if V extension is supported. However, all vector extensions and
4
"rtc". The variables whose value are given by cpu_riscv_read_rtc_raw()
5
vector crypto extensions have the vector registers and they all depend
5
should be named "rtc_r".
6
on Zve32x. The gdbstub should check for Zve32x instead.
7
6
8
Signed-off-by: Jason Chien <jason.chien@sifive.com>
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
9
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Max Chou <max.chou@sifive.com>
9
Message-ID: <20230728082502.26439-2-jason.chien@sifive.com>
11
Message-ID: <20240328022343.6871-4-jason.chien@sifive.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
11
---
14
target/riscv/gdbstub.c | 2 +-
12
hw/intc/riscv_aclint.c | 6 +++---
15
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 3 insertions(+), 3 deletions(-)
16
14
17
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
15
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/gdbstub.c
17
--- a/hw/intc/riscv_aclint.c
20
+++ b/target/riscv/gdbstub.c
18
+++ b/hw/intc/riscv_aclint.c
21
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
19
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
22
gdb_find_static_feature("riscv-32bit-fpu.xml"),
20
uint64_t next;
23
0);
21
uint64_t diff;
24
}
22
25
- if (env->misa_ext & RVV) {
23
- uint64_t rtc_r = cpu_riscv_read_rtc(mtimer);
26
+ if (cpu->cfg.ext_zve32x) {
24
+ uint64_t rtc = cpu_riscv_read_rtc(mtimer);
27
gdb_register_coprocessor(cs, riscv_gdb_get_vector,
25
28
riscv_gdb_set_vector,
26
/* Compute the relative hartid w.r.t the socket */
29
ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs),
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
30
--
44
--
31
2.45.1
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: Huang Tao <eric.huang@linux.alibaba.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
In this patch, we modify the decoder to be a freely composable data
3
In this patch, we create the APLIC and IMSIC FDT helper functions and
4
structure instead of a hardcoded one. It can be dynamically builded up
4
remove M mode AIA devices when using KVM acceleration.
5
according to the extensions.
6
This approach has several benefits:
7
1. Provides support for heterogeneous cpu architectures. As we add decoder in
8
RISCVCPU, each cpu can have their own decoder, and the decoders can be
9
different due to cpu's features.
10
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
11
can be added to the dynamic_decoder when building up the decoder. Therefore,
12
there is no need to run the guard_func when decoding each instruction. It can
13
improve the decoding efficiency
14
3. For vendor or dynamic cpus, it allows them to customize their own decoder
15
functions to improve decoding efficiency, especially when vendor-defined
16
instruction sets increase. Because of dynamic building up, it can skip the other
17
decoder guard functions when decoding.
18
4. Pre patch for allowing adding a vendor decoder before decode_insn32() with minimal
19
overhead for users that don't need this particular vendor decoder.
20
5
21
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
6
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
22
Suggested-by: Christoph Muellner <christoph.muellner@vrull.eu>
7
Reviewed-by: Jim Shu <jim.shu@sifive.com>
23
Co-authored-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
25
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-ID: <20230727102439.22554-2-yongxuan.wang@sifive.com>
26
Message-ID: <20240506023607.29544-1-eric.huang@linux.alibaba.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
12
---
29
target/riscv/cpu.h | 1 +
13
hw/riscv/virt.c | 290 +++++++++++++++++++++++-------------------------
30
target/riscv/tcg/tcg-cpu.h | 15 +++++++++++++++
14
1 file changed, 137 insertions(+), 153 deletions(-)
31
target/riscv/cpu.c | 1 +
32
target/riscv/tcg/tcg-cpu.c | 15 +++++++++++++++
33
target/riscv/translate.c | 31 +++++++++++++++----------------
34
5 files changed, 47 insertions(+), 16 deletions(-)
35
15
36
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
16
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
37
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/cpu.h
18
--- a/hw/riscv/virt.c
39
+++ b/target/riscv/cpu.h
19
+++ b/hw/riscv/virt.c
40
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
20
@@ -XXX,XX +XXX,XX @@ static uint32_t imsic_num_bits(uint32_t count)
41
uint32_t pmu_avail_ctrs;
21
return ret;
42
/* Mapping of events to counters */
22
}
43
GHashTable *pmu_event_ctr_map;
23
44
+ const GPtrArray *decoders;
24
-static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
45
};
25
- uint32_t *phandle, uint32_t *intc_phandles,
46
26
- uint32_t *msi_m_phandle, uint32_t *msi_s_phandle)
47
/**
27
+static void create_fdt_one_imsic(RISCVVirtState *s, hwaddr base_addr,
48
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
28
+ uint32_t *intc_phandles, uint32_t msi_phandle,
49
index XXXXXXX..XXXXXXX 100644
29
+ bool m_mode, uint32_t imsic_guest_bits)
50
--- a/target/riscv/tcg/tcg-cpu.h
30
{
51
+++ b/target/riscv/tcg/tcg-cpu.h
31
int cpu, socket;
52
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
32
char *imsic_name;
53
void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
33
MachineState *ms = MACHINE(s);
54
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);
34
int socket_count = riscv_socket_count(ms);
55
35
- uint32_t imsic_max_hart_per_socket, imsic_guest_bits;
56
+struct DisasContext;
36
+ uint32_t imsic_max_hart_per_socket;
57
+struct RISCVCPUConfig;
37
uint32_t *imsic_cells, *imsic_regs, imsic_addr, imsic_size;
58
+typedef struct RISCVDecoder {
38
59
+ bool (*guard_func)(const struct RISCVCPUConfig *);
39
- *msi_m_phandle = (*phandle)++;
60
+ bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
40
- *msi_s_phandle = (*phandle)++;
61
+} RISCVDecoder;
41
imsic_cells = g_new0(uint32_t, ms->smp.cpus * 2);
62
+
42
imsic_regs = g_new0(uint32_t, socket_count * 4);
63
+typedef bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
43
64
+
44
- /* M-level IMSIC node */
65
+extern const size_t decoder_table_size;
45
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
66
+
46
imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
67
+extern const RISCVDecoder decoder_table[];
47
- imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
68
+
48
+ imsic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
69
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu);
49
}
70
+
50
- imsic_max_hart_per_socket = 0;
71
#endif
51
- for (socket = 0; socket < socket_count; socket++) {
72
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
52
- imsic_addr = memmap[VIRT_IMSIC_M].base +
73
index XXXXXXX..XXXXXXX 100644
53
- socket * VIRT_IMSIC_GROUP_MAX_SIZE;
74
--- a/target/riscv/cpu.c
54
- imsic_size = IMSIC_HART_SIZE(0) * s->soc[socket].num_harts;
75
+++ b/target/riscv/cpu.c
55
- imsic_regs[socket * 4 + 0] = 0;
76
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
56
- imsic_regs[socket * 4 + 1] = cpu_to_be32(imsic_addr);
77
error_propagate(errp, local_err);
57
- imsic_regs[socket * 4 + 2] = 0;
78
return;
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;
79
}
108
}
80
+ riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
109
}
81
} else if (kvm_enabled()) {
110
- imsic_name = g_strdup_printf("/soc/imsics@%lx",
82
riscv_kvm_cpu_finalize_features(cpu, &local_err);
111
- (unsigned long)memmap[VIRT_IMSIC_S].base);
83
if (local_err != NULL) {
112
+
84
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
113
+ imsic_name = g_strdup_printf("/soc/imsics@%lx", (unsigned long)base_addr);
85
index XXXXXXX..XXXXXXX 100644
114
qemu_fdt_add_subnode(ms->fdt, imsic_name);
86
--- a/target/riscv/tcg/tcg-cpu.c
115
- qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
87
+++ b/target/riscv/tcg/tcg-cpu.c
116
- "riscv,imsics");
88
@@ -XXX,XX +XXX,XX @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
117
+ qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible", "riscv,imsics");
89
}
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);
90
}
161
}
91
162
92
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
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)
93
+{
173
+{
94
+ GPtrArray *dynamic_decoders;
174
+ *msi_m_phandle = (*phandle)++;
95
+ dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
175
+ *msi_s_phandle = (*phandle)++;
96
+ for (size_t i = 0; i < decoder_table_size; ++i) {
176
+
97
+ if (decoder_table[i].guard_func &&
177
+ if (!kvm_enabled()) {
98
+ decoder_table[i].guard_func(&cpu->cfg)) {
178
+ /* M-level IMSIC node */
99
+ g_ptr_array_add(dynamic_decoders,
179
+ create_fdt_one_imsic(s, memmap[VIRT_IMSIC_M].base, intc_phandles,
100
+ (gpointer)decoder_table[i].riscv_cpu_decode_fn);
180
+ *msi_m_phandle, true, 0);
101
+ }
102
+ }
181
+ }
103
+
182
+
104
+ cpu->decoders = dynamic_decoders;
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
+
105
+}
188
+}
106
+
189
+
107
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu)
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)
108
{
197
{
109
return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL;
198
int cpu;
110
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
199
char *aplic_name;
111
index XXXXXXX..XXXXXXX 100644
200
uint32_t *aplic_cells;
112
--- a/target/riscv/translate.c
201
- unsigned long aplic_addr;
113
+++ b/target/riscv/translate.c
202
MachineState *ms = MACHINE(s);
114
@@ -XXX,XX +XXX,XX @@
203
- uint32_t aplic_m_phandle, aplic_s_phandle;
115
#include "exec/helper-info.c.inc"
204
116
#undef HELPER_H
205
- aplic_m_phandle = (*phandle)++;
117
206
- aplic_s_phandle = (*phandle)++;
118
+#include "tcg/tcg-cpu.h"
207
aplic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
119
+
208
120
/* global register indices */
209
- /* M-level APLIC node */
121
static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
210
for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
122
static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
211
aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
123
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
212
- aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
124
/* FRM is known to contain a valid value. */
213
+ aplic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
125
bool frm_valid;
214
}
126
bool insn_start_updated;
215
- aplic_addr = memmap[VIRT_APLIC_M].base +
127
+ const GPtrArray *decoders;
216
- (memmap[VIRT_APLIC_M].size * socket);
128
} DisasContext;
217
+
129
218
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
130
static inline bool has_ext(DisasContext *ctx, uint32_t ext)
219
qemu_fdt_add_subnode(ms->fdt, aplic_name);
131
@@ -XXX,XX +XXX,XX @@ static inline int insn_len(uint16_t first_word)
220
qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
132
return (first_word & 3) == 3 ? 4 : 2;
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;
133
}
330
}
134
331
135
+const RISCVDecoder decoder_table[] = {
332
@@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
136
+ { always_true_p, decode_insn32 },
333
int i;
137
+ { has_xthead_p, decode_xthead},
334
hwaddr addr;
138
+ { has_XVentanaCondOps_p, decode_XVentanaCodeOps},
335
uint32_t guest_bits;
139
+};
336
- DeviceState *aplic_m;
140
+
337
- bool msimode = (aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) ? true : false;
141
+const size_t decoder_table_size = ARRAY_SIZE(decoder_table);
338
+ DeviceState *aplic_s = NULL;
142
+
339
+ DeviceState *aplic_m = NULL;
143
static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
340
+ bool msimode = aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
144
{
341
145
- /*
342
if (msimode) {
146
- * A table with predicate (i.e., guard) functions and decoder functions
343
- /* Per-socket M-level IMSICs */
147
- * that are tested in-order until a decoder matches onto the opcode.
344
- addr = memmap[VIRT_IMSIC_M].base + socket * VIRT_IMSIC_GROUP_MAX_SIZE;
148
- */
345
- for (i = 0; i < hart_count; i++) {
149
- static const struct {
346
- riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0),
150
- bool (*guard_func)(const RISCVCPUConfig *);
347
- base_hartid + i, true, 1,
151
- bool (*decode_func)(DisasContext *, uint32_t);
348
- VIRT_IRQCHIP_NUM_MSIS);
152
- } decoders[] = {
349
+ if (!kvm_enabled()) {
153
- { always_true_p, decode_insn32 },
350
+ /* Per-socket M-level IMSICs */
154
- { has_xthead_p, decode_xthead },
351
+ addr = memmap[VIRT_IMSIC_M].base +
155
- { has_XVentanaCondOps_p, decode_XVentanaCodeOps },
352
+ socket * VIRT_IMSIC_GROUP_MAX_SIZE;
156
- };
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);
157
-
374
-
158
ctx->virt_inst_excp = false;
375
- if (aplic_m) {
159
ctx->cur_insn_len = insn_len(opcode);
376
- /* Per-socket S-level APLIC */
160
/* Check for compressed insn */
377
- riscv_aplic_create(
161
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
378
- memmap[VIRT_APLIC_S].base + socket * memmap[VIRT_APLIC_S].size,
162
ctx->base.pc_next + 2));
379
- memmap[VIRT_APLIC_S].size,
163
ctx->opcode = opcode32;
380
- (msimode) ? 0 : base_hartid,
164
381
- (msimode) ? 0 : hart_count,
165
- for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) {
382
- VIRT_IRQCHIP_NUM_SOURCES,
166
- if (decoders[i].guard_func(ctx->cfg_ptr) &&
383
- VIRT_IRQCHIP_NUM_PRIO_BITS,
167
- decoders[i].decode_func(ctx, opcode32)) {
384
- msimode, false, aplic_m);
168
+ for (guint i = 0; i < ctx->decoders->len; ++i) {
385
+ if (!kvm_enabled()) {
169
+ riscv_cpu_decode_fn func = g_ptr_array_index(ctx->decoders, i);
386
+ /* Per-socket M-level APLIC */
170
+ if (func(ctx, opcode32)) {
387
+ aplic_m = riscv_aplic_create(memmap[VIRT_APLIC_M].base +
171
return;
388
+ socket * memmap[VIRT_APLIC_M].size,
172
}
389
+ memmap[VIRT_APLIC_M].size,
173
}
390
+ (msimode) ? 0 : base_hartid,
174
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
391
+ (msimode) ? 0 : hart_count,
175
ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
392
+ VIRT_IRQCHIP_NUM_SOURCES,
176
ctx->zero = tcg_constant_tl(0);
393
+ VIRT_IRQCHIP_NUM_PRIO_BITS,
177
ctx->virt_inst_excp = false;
394
+ msimode, true, NULL);
178
+ ctx->decoders = cpu->decoders;
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;
179
}
409
}
180
410
181
static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
411
static void create_platform_bus(RISCVVirtState *s, DeviceState *irqchip)
182
--
412
--
183
2.45.1
413
2.41.0
diff view generated by jsdifflib
New patch
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
1
2
3
We check the in-kernel irqchip support when using KVM acceleration.
4
5
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
6
Reviewed-by: Jim Shu <jim.shu@sifive.com>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
9
Message-ID: <20230727102439.22554-3-yongxuan.wang@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/kvm.c | 10 +++++++++-
13
1 file changed, 9 insertions(+), 1 deletion(-)
14
15
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/kvm.c
18
+++ b/target/riscv/kvm.c
19
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
20
21
int kvm_arch_irqchip_create(KVMState *s)
22
{
23
- return 0;
24
+ if (kvm_kernel_irqchip_split()) {
25
+ error_report("-machine kernel_irqchip=split is not supported on RISC-V.");
26
+ exit(1);
27
+ }
28
+
29
+ /*
30
+ * We can create the VAIA using the newer device control API.
31
+ */
32
+ return kvm_check_extension(s, KVM_CAP_DEVICE_CTRL);
33
}
34
35
int kvm_arch_process_async_events(CPUState *cs)
36
--
37
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
SBI defines a Debug Console extension "DBCN" that will, in time, replace
3
We create a vAIA chip by using the KVM_DEV_TYPE_RISCV_AIA and then set up
4
the legacy console putchar and getchar SBI extensions.
4
the chip with the KVM_DEV_RISCV_AIA_GRP_* APIs.
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.
5
11
6
The appeal of the DBCN extension is that it allows multiple bytes to be
12
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
7
read/written in the SBI console in a single SBI call.
13
Reviewed-by: Jim Shu <jim.shu@sifive.com>
8
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
As far as KVM goes, the DBCN calls are forwarded by an in-kernel KVM
10
module to userspace. But this will only happens if the KVM module
11
actually supports this SBI extension and we activate it.
12
13
We'll check for DBCN support during init time, checking if get-reg-list
14
is advertising KVM_RISCV_SBI_EXT_DBCN. In that case, we'll enable it via
15
kvm_set_one_reg() during kvm_arch_init_vcpu().
16
17
Finally, change kvm_riscv_handle_sbi() to handle the incoming calls for
18
SBI_EXT_DBCN, reading and writing as required.
19
20
A simple KVM guest with 'earlycon=sbi', running in an emulated RISC-V
21
host, takes around 20 seconds to boot without using DBCN. With this
22
patch we're taking around 14 seconds to boot due to the speed-up in the
23
terminal output. There's no change in boot time if the guest isn't
24
using earlycon.
25
26
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
27
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
15
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
28
Message-ID: <20240425155012.581366-1-dbarboza@ventanamicro.com>
16
Message-ID: <20230727102439.22554-4-yongxuan.wang@sifive.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
---
18
---
31
target/riscv/sbi_ecall_interface.h | 17 +++++
19
target/riscv/kvm_riscv.h | 4 +
32
target/riscv/kvm/kvm-cpu.c | 111 +++++++++++++++++++++++++++++
20
target/riscv/kvm.c | 186 +++++++++++++++++++++++++++++++++++++++
33
2 files changed, 128 insertions(+)
21
2 files changed, 190 insertions(+)
34
22
35
diff --git a/target/riscv/sbi_ecall_interface.h b/target/riscv/sbi_ecall_interface.h
23
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
36
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/sbi_ecall_interface.h
25
--- a/target/riscv/kvm_riscv.h
38
+++ b/target/riscv/sbi_ecall_interface.h
26
+++ b/target/riscv/kvm_riscv.h
39
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@
40
28
void kvm_riscv_init_user_properties(Object *cpu_obj);
41
/* clang-format off */
29
void kvm_riscv_reset_vcpu(RISCVCPU *cpu);
42
30
void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level);
43
+#define SBI_SUCCESS 0
31
+void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
44
+#define SBI_ERR_FAILED -1
32
+ uint64_t aia_irq_num, uint64_t aia_msi_num,
45
+#define SBI_ERR_NOT_SUPPORTED -2
33
+ uint64_t aplic_base, uint64_t imsic_base,
46
+#define SBI_ERR_INVALID_PARAM -3
34
+ uint64_t guest_num);
47
+#define SBI_ERR_DENIED -4
35
48
+#define SBI_ERR_INVALID_ADDRESS -5
36
#endif
49
+#define SBI_ERR_ALREADY_AVAILABLE -6
37
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
50
+#define SBI_ERR_ALREADY_STARTED -7
38
index XXXXXXX..XXXXXXX 100644
51
+#define SBI_ERR_ALREADY_STOPPED -8
39
--- a/target/riscv/kvm.c
52
+#define SBI_ERR_NO_SHMEM -9
40
+++ b/target/riscv/kvm.c
53
+
54
/* SBI Extension IDs */
55
#define SBI_EXT_0_1_SET_TIMER 0x0
56
#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1
57
@@ -XXX,XX +XXX,XX @@
41
@@ -XXX,XX +XXX,XX @@
58
#define SBI_EXT_IPI 0x735049
42
#include "exec/address-spaces.h"
59
#define SBI_EXT_RFENCE 0x52464E43
43
#include "hw/boards.h"
60
#define SBI_EXT_HSM 0x48534D
44
#include "hw/irq.h"
61
+#define SBI_EXT_DBCN 0x4442434E
45
+#include "hw/intc/riscv_imsic.h"
62
46
#include "qemu/log.h"
63
/* SBI function IDs for BASE extension */
47
#include "hw/loader.h"
64
#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
48
#include "kvm_riscv.h"
65
@@ -XXX,XX +XXX,XX @@
49
@@ -XXX,XX +XXX,XX @@
66
#define SBI_EXT_HSM_HART_STOP 0x1
50
#include "chardev/char-fe.h"
67
#define SBI_EXT_HSM_HART_GET_STATUS 0x2
51
#include "migration/migration.h"
68
52
#include "sysemu/runstate.h"
69
+/* SBI function IDs for DBCN extension */
53
+#include "hw/riscv/numa.h"
70
+#define SBI_EXT_DBCN_CONSOLE_WRITE 0x0
54
71
+#define SBI_EXT_DBCN_CONSOLE_READ 0x1
55
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
72
+#define SBI_EXT_DBCN_CONSOLE_WRITE_BYTE 0x2
56
uint64_t idx)
73
+
57
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_cpu_check_are_resettable(void)
74
#define SBI_HSM_HART_STATUS_STARTED 0x0
75
#define SBI_HSM_HART_STATUS_STOPPED 0x1
76
#define SBI_HSM_HART_STATUS_START_PENDING 0x2
77
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/riscv/kvm/kvm-cpu.c
80
+++ b/target/riscv/kvm/kvm-cpu.c
81
@@ -XXX,XX +XXX,XX @@ static KVMCPUConfig kvm_v_vlenb = {
82
KVM_REG_RISCV_VECTOR_CSR_REG(vlenb)
83
};
84
85
+static KVMCPUConfig kvm_sbi_dbcn = {
86
+ .name = "sbi_dbcn",
87
+ .kvm_reg_id = KVM_REG_RISCV | KVM_REG_SIZE_U64 |
88
+ KVM_REG_RISCV_SBI_EXT | KVM_RISCV_SBI_EXT_DBCN
89
+};
90
+
91
static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
92
{
93
CPURISCVState *env = &cpu->env;
94
@@ -XXX,XX +XXX,XX @@ static int uint64_cmp(const void *a, const void *b)
95
return 0;
96
}
97
98
+static void kvm_riscv_check_sbi_dbcn_support(RISCVCPU *cpu,
99
+ KVMScratchCPU *kvmcpu,
100
+ struct kvm_reg_list *reglist)
101
+{
102
+ struct kvm_reg_list *reg_search;
103
+
104
+ reg_search = bsearch(&kvm_sbi_dbcn.kvm_reg_id, reglist->reg, reglist->n,
105
+ sizeof(uint64_t), uint64_cmp);
106
+
107
+ if (reg_search) {
108
+ kvm_sbi_dbcn.supported = true;
109
+ }
110
+}
111
+
112
static void kvm_riscv_read_vlenb(RISCVCPU *cpu, KVMScratchCPU *kvmcpu,
113
struct kvm_reg_list *reglist)
114
{
115
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
116
if (riscv_has_ext(&cpu->env, RVV)) {
117
kvm_riscv_read_vlenb(cpu, kvmcpu, reglist);
118
}
119
+
120
+ kvm_riscv_check_sbi_dbcn_support(cpu, kvmcpu, reglist);
121
}
122
123
static void riscv_init_kvm_registers(Object *cpu_obj)
124
@@ -XXX,XX +XXX,XX @@ static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, CPUState *cs)
125
return ret;
126
}
127
128
+static int kvm_vcpu_enable_sbi_dbcn(RISCVCPU *cpu, CPUState *cs)
129
+{
130
+ target_ulong reg = 1;
131
+
132
+ if (!kvm_sbi_dbcn.supported) {
133
+ return 0;
134
+ }
135
+
136
+ return kvm_set_one_reg(cs, kvm_sbi_dbcn.kvm_reg_id, &reg);
137
+}
138
+
139
int kvm_arch_init_vcpu(CPUState *cs)
140
{
141
int ret = 0;
142
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
143
kvm_riscv_update_cpu_misa_ext(cpu, cs);
144
kvm_riscv_update_cpu_cfg_isa_ext(cpu, cs);
145
146
+ ret = kvm_vcpu_enable_sbi_dbcn(cpu, cs);
147
+
148
return ret;
149
}
150
151
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
152
return true;
58
return true;
153
}
59
}
154
60
155
+static void kvm_riscv_handle_sbi_dbcn(CPUState *cs, struct kvm_run *run)
61
+static int aia_mode;
156
+{
62
+
157
+ g_autofree uint8_t *buf = NULL;
63
+static const char *kvm_aia_mode_str(uint64_t mode)
158
+ RISCVCPU *cpu = RISCV_CPU(cs);
64
+{
159
+ target_ulong num_bytes;
65
+ switch (mode) {
160
+ uint64_t addr;
66
+ case KVM_DEV_RISCV_AIA_MODE_EMUL:
161
+ unsigned char ch;
67
+ return "emul";
162
+ int ret;
68
+ case KVM_DEV_RISCV_AIA_MODE_HWACCEL:
163
+
69
+ return "hwaccel";
164
+ switch (run->riscv_sbi.function_id) {
70
+ case KVM_DEV_RISCV_AIA_MODE_AUTO:
165
+ case SBI_EXT_DBCN_CONSOLE_READ:
71
+ default:
166
+ case SBI_EXT_DBCN_CONSOLE_WRITE:
72
+ return "auto";
167
+ num_bytes = run->riscv_sbi.args[0];
73
+ };
168
+
74
+}
169
+ if (num_bytes == 0) {
75
+
170
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
76
+static char *riscv_get_kvm_aia(Object *obj, Error **errp)
171
+ run->riscv_sbi.ret[1] = 0;
77
+{
172
+ break;
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)
96
{
97
+ object_class_property_add_str(oc, "riscv-aia", riscv_get_kvm_aia,
98
+ riscv_set_kvm_aia);
99
+ object_class_property_set_description(oc, "riscv-aia",
100
+ "Set KVM AIA mode. Valid values are "
101
+ "emul, hwaccel, and auto. Default "
102
+ "is auto.");
103
+ object_property_set_default_str(object_class_property_find(oc, "riscv-aia"),
104
+ "auto");
105
+}
106
+
107
+void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
108
+ uint64_t aia_irq_num, uint64_t aia_msi_num,
109
+ uint64_t aplic_base, uint64_t imsic_base,
110
+ uint64_t guest_num)
111
+{
112
+ int ret, i;
113
+ int aia_fd = -1;
114
+ uint64_t default_aia_mode;
115
+ uint64_t socket_count = riscv_socket_count(machine);
116
+ uint64_t max_hart_per_socket = 0;
117
+ uint64_t socket, base_hart, hart_count, socket_imsic_base, imsic_addr;
118
+ uint64_t socket_bits, hart_bits, guest_bits;
119
+
120
+ aia_fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_RISCV_AIA, false);
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;
173
+ }
206
+ }
174
+
207
+
175
+ addr = run->riscv_sbi.args[1];
208
+ for (i = 0; i < hart_count; i++) {
176
+
209
+ imsic_addr = socket_imsic_base + i * IMSIC_HART_SIZE(guest_bits);
177
+ /*
210
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_ADDR,
178
+ * Handle the case where a 32 bit CPU is running in a
211
+ KVM_DEV_RISCV_AIA_ADDR_IMSIC(i + base_hart),
179
+ * 64 bit addressing env.
212
+ &imsic_addr, true, NULL);
180
+ */
181
+ if (riscv_cpu_mxl(&cpu->env) == MXL_RV32) {
182
+ addr |= (uint64_t)run->riscv_sbi.args[2] << 32;
183
+ }
184
+
185
+ buf = g_malloc0(num_bytes);
186
+
187
+ if (run->riscv_sbi.function_id == SBI_EXT_DBCN_CONSOLE_READ) {
188
+ ret = qemu_chr_fe_read_all(serial_hd(0)->be, buf, num_bytes);
189
+ if (ret < 0) {
213
+ if (ret < 0) {
190
+ error_report("SBI_EXT_DBCN_CONSOLE_READ: error when "
214
+ error_report("KVM AIA: failed to set the IMSIC address for hart %d", i);
191
+ "reading chardev");
192
+ exit(1);
193
+ }
194
+
195
+ cpu_physical_memory_write(addr, buf, ret);
196
+ } else {
197
+ cpu_physical_memory_read(addr, buf, num_bytes);
198
+
199
+ ret = qemu_chr_fe_write_all(serial_hd(0)->be, buf, num_bytes);
200
+ if (ret < 0) {
201
+ error_report("SBI_EXT_DBCN_CONSOLE_WRITE: error when "
202
+ "writing chardev");
203
+ exit(1);
215
+ exit(1);
204
+ }
216
+ }
205
+ }
217
+ }
206
+
218
+ }
207
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
219
+
208
+ run->riscv_sbi.ret[1] = ret;
220
+ hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
209
+ break;
221
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
210
+ case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE:
222
+ KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
211
+ ch = run->riscv_sbi.args[0];
223
+ &hart_bits, true, NULL);
212
+ ret = qemu_chr_fe_write(serial_hd(0)->be, &ch, sizeof(ch));
224
+ if (ret < 0) {
213
+
225
+ error_report("KVM AIA: failed to set hart_bits");
214
+ if (ret < 0) {
226
+ exit(1);
215
+ error_report("SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: error when "
227
+ }
216
+ "writing chardev");
228
+
217
+ exit(1);
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);
218
+ }
233
+ }
219
+
234
+ kvm_gsi_routing_allowed = true;
220
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
235
+ kvm_irqchip_commit_routes(kvm_state);
221
+ run->riscv_sbi.ret[1] = 0;
236
+ }
222
+ break;
237
+
223
+ default:
238
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CTRL,
224
+ run->riscv_sbi.ret[0] = SBI_ERR_NOT_SUPPORTED;
239
+ KVM_DEV_RISCV_AIA_CTRL_INIT,
225
+ }
240
+ NULL, true, NULL);
226
+}
241
+ if (ret < 0) {
227
+
242
+ error_report("KVM AIA: initialized fail");
228
static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
243
+ exit(1);
229
{
244
+ }
230
int ret = 0;
245
+
231
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
246
+ kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();
232
}
247
}
233
ret = 0;
234
break;
235
+ case SBI_EXT_DBCN:
236
+ kvm_riscv_handle_sbi_dbcn(cs, run);
237
+ break;
238
default:
239
qemu_log_mask(LOG_UNIMP,
240
"%s: un-handled SBI EXIT, specific reasons is %lu\n",
241
--
248
--
242
2.45.1
249
2.41.0
diff view generated by jsdifflib
1
From: "yang.zhang" <yang.zhang@hexintek.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
Since only root APLICs can have hw IRQ lines, aplic->parent should
3
KVM AIA can't emulate APLIC only. When "aia=aplic" parameter is passed,
4
be initialized first.
4
APLIC devices is emulated by QEMU. For "aia=aplic-imsic", remove the
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.
5
9
6
Fixes: e8f79343cf ("hw/intc: Add RISC-V AIA APLIC device emulation")
10
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
11
Reviewed-by: Jim Shu <jim.shu@sifive.com>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Signed-off-by: yang.zhang <yang.zhang@hexintek.com>
13
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
9
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Message-ID: <20230727102439.22554-5-yongxuan.wang@sifive.com>
10
Message-ID: <20240409014445.278-1-gaoshanliukou@163.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
16
---
13
hw/intc/riscv_aplic.c | 8 ++++----
17
hw/intc/riscv_aplic.c | 56 ++++++++++++++++++++++++++++++-------------
14
1 file changed, 4 insertions(+), 4 deletions(-)
18
hw/intc/riscv_imsic.c | 25 +++++++++++++++----
19
2 files changed, 61 insertions(+), 20 deletions(-)
15
20
16
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
21
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
17
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/riscv_aplic.c
23
--- a/hw/intc/riscv_aplic.c
19
+++ b/hw/intc/riscv_aplic.c
24
+++ b/hw/intc/riscv_aplic.c
25
@@ -XXX,XX +XXX,XX @@
26
#include "hw/irq.h"
27
#include "target/riscv/cpu.h"
28
#include "sysemu/sysemu.h"
29
+#include "sysemu/kvm.h"
30
#include "migration/vmstate.h"
31
32
#define APLIC_MAX_IDC (1UL << 14)
33
@@ -XXX,XX +XXX,XX @@
34
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 */
20
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
112
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
21
qdev_prop_set_bit(dev, "msimode", msimode);
22
qdev_prop_set_bit(dev, "mmode", mmode);
113
qdev_prop_set_bit(dev, "mmode", mmode);
23
114
24
+ if (parent) {
115
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
25
+ riscv_aplic_add_child(parent, dev);
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);
26
+ }
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
125
index XXXXXXX..XXXXXXX 100644
126
--- a/hw/intc/riscv_imsic.c
127
+++ b/hw/intc/riscv_imsic.c
128
@@ -XXX,XX +XXX,XX @@
129
#include "target/riscv/cpu.h"
130
#include "target/riscv/cpu_bits.h"
131
#include "sysemu/sysemu.h"
132
+#include "sysemu/kvm.h"
133
#include "migration/vmstate.h"
134
135
#define IMSIC_MMIO_PAGE_LE 0x00
136
@@ -XXX,XX +XXX,XX @@ static void riscv_imsic_write(void *opaque, hwaddr addr, uint64_t value,
137
goto err;
138
}
139
140
+#if defined(CONFIG_KVM)
141
+ if (kvm_irqchip_in_kernel()) {
142
+ struct kvm_msi msi;
27
+
143
+
28
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
144
+ msi.address_lo = extract64(imsic->mmio.addr + addr, 0, 32);
29
145
+ msi.address_hi = extract64(imsic->mmio.addr + addr, 32, 32);
30
if (!is_kvm_aia(msimode)) {
146
+ msi.data = le32_to_cpu(value);
31
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
147
+
32
}
148
+ kvm_vm_ioctl(kvm_state, KVM_SIGNAL_MSI, &msi);
33
149
+
34
- if (parent) {
150
+ return;
35
- riscv_aplic_add_child(parent, dev);
151
+ }
36
- }
152
+#endif
37
-
153
+
38
if (!msimode) {
154
/* Writes only supported for MSI little-endian registers */
39
for (i = 0; i < num_harts; i++) {
155
page = addr >> IMSIC_MMIO_PAGE_SHIFT;
40
CPUState *cpu = cpu_by_arch_id(hartid_base + i);
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,
41
--
174
--
42
2.45.1
175
2.41.0
diff view generated by jsdifflib
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
In AIA spec, each hart (or each hart within a group) has a unique hart
3
Select KVM AIA when the host kernel has in-kernel AIA chip support.
4
number to locate the memory pages of interrupt files in the address
4
Since KVM AIA only has one APLIC instance, we map the QEMU APLIC
5
space. The number of bits required to represent any hart number is equal
5
devices to KVM APLIC.
6
to ceil(log2(hmax + 1)), where hmax is the largest hart number among
7
groups.
8
9
However, if the largest hart number among groups is a power of 2, QEMU
10
will pass an inaccurate hart-index-bit setting to Linux. For example, when
11
the guest OS has 4 harts, only ceil(log2(3 + 1)) = 2 bits are sufficient
12
to represent 4 harts, but we passes 3 to Linux. The code needs to be
13
updated to ensure accurate hart-index-bit settings.
14
15
Additionally, a Linux patch[1] is necessary to correctly recover the hart
16
index when the guest OS has only 1 hart, where the hart-index-bit is 0.
17
18
[1] https://lore.kernel.org/lkml/20240415064905.25184-1-yongxuan.wang@sifive.com/t/
19
6
20
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
7
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
8
Reviewed-by: Jim Shu <jim.shu@sifive.com>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
21
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
10
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
22
Cc: qemu-stable <qemu-stable@nongnu.org>
11
Message-ID: <20230727102439.22554-6-yongxuan.wang@sifive.com>
23
Message-ID: <20240515091129.28116-1-yongxuan.wang@sifive.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
13
---
26
target/riscv/kvm/kvm-cpu.c | 9 ++++++++-
14
hw/riscv/virt.c | 94 +++++++++++++++++++++++++++++++++----------------
27
1 file changed, 8 insertions(+), 1 deletion(-)
15
1 file changed, 63 insertions(+), 31 deletions(-)
28
16
29
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
17
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
30
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/kvm/kvm-cpu.c
19
--- a/hw/riscv/virt.c
32
+++ b/target/riscv/kvm/kvm-cpu.c
20
+++ b/hw/riscv/virt.c
33
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/riscv/virt.h"
23
#include "hw/riscv/boot.h"
24
#include "hw/riscv/numa.h"
25
+#include "kvm_riscv.h"
26
#include "hw/intc/riscv_aclint.h"
27
#include "hw/intc/riscv_aplic.h"
28
#include "hw/intc/riscv_imsic.h"
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
+ }
34
}
137
}
35
}
138
}
36
139
37
- hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
140
g_free(intc_phandles);
38
+
141
39
+ if (max_hart_per_socket > 1) {
142
- for (socket = 0; socket < socket_count; socket++) {
40
+ max_hart_per_socket--;
143
- if (socket == 0) {
41
+ hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
144
- *irq_mmio_phandle = xplic_phandles[socket];
145
- *irq_virtio_phandle = xplic_phandles[socket];
146
- *irq_pcie_phandle = xplic_phandles[socket];
147
- }
148
- if (socket == 1) {
149
- *irq_virtio_phandle = xplic_phandles[socket];
150
- *irq_pcie_phandle = xplic_phandles[socket];
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];
42
+ } else {
158
+ } else {
43
+ hart_bits = 0;
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);
44
+ }
185
+ }
45
+
186
+
46
ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
187
if (riscv_is_32bit(&s->soc[0])) {
47
KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
188
#if HOST_LONG_BITS == 64
48
&hart_bits, true, NULL);
189
/* limit RAM size in a 32-bit system */
49
--
190
--
50
2.45.1
191
2.41.0
diff view generated by jsdifflib
New patch
1
From: Conor Dooley <conor.dooley@microchip.com>
1
2
3
On a dtb dumped from the virt machine, dt-validate complains:
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
9
10
Moving the riscv,pmu node out of the soc bus solves the problem.
11
12
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Message-ID: <20230727-groom-decline-2c57ce42841c@spud>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
hw/riscv/virt.c | 2 +-
19
1 file changed, 1 insertion(+), 1 deletion(-)
20
21
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/riscv/virt.c
24
+++ b/hw/riscv/virt.c
25
@@ -XXX,XX +XXX,XX @@ static void create_fdt_pmu(RISCVVirtState *s)
26
MachineState *ms = MACHINE(s);
27
RISCVCPU hart = s->soc[0].harts[0];
28
29
- pmu_name = g_strdup_printf("/soc/pmu");
30
+ pmu_name = g_strdup_printf("/pmu");
31
qemu_fdt_add_subnode(ms->fdt, pmu_name);
32
qemu_fdt_setprop_string(ms->fdt, pmu_name, "compatible", "riscv,pmu");
33
riscv_pmu_generate_fdt_node(ms->fdt, hart.cfg.pmu_num, pmu_name);
34
--
35
2.41.0
diff view generated by jsdifflib
1
From: Clément Léger <cleger@rivosinc.com>
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
2
2
3
The current semihost exception number (16) is a reserved number (range
3
The Svadu specification updated the name of the *envcfg bit from
4
[16-17]). The upcoming double trap specification uses that number for
4
HADE to ADUE.
5
the double trap exception. Since the privileged spec (Table 22) defines
6
ranges for custom uses change the semihosting exception number to 63
7
which belongs to the range [48-63] in order to avoid any future
8
collisions with reserved exception.
9
5
10
Signed-off-by: Clément Léger <cleger@rivosinc.com>
6
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
11
7
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Message-ID: <20240422135840.1959967-1-cleger@rivosinc.com>
9
Message-ID: <20230816141916.66898-1-liweiwei@iscas.ac.cn>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
11
---
16
target/riscv/cpu_bits.h | 2 +-
12
target/riscv/cpu_bits.h | 8 ++++----
17
1 file changed, 1 insertion(+), 1 deletion(-)
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(-)
18
17
19
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
18
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
20
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu_bits.h
20
--- a/target/riscv/cpu_bits.h
22
+++ b/target/riscv/cpu_bits.h
21
+++ b/target/riscv/cpu_bits.h
23
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
22
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
24
RISCV_EXCP_INST_PAGE_FAULT = 0xc, /* since: priv-1.10.0 */
23
#define MENVCFG_CBIE (3UL << 4)
25
RISCV_EXCP_LOAD_PAGE_FAULT = 0xd, /* since: priv-1.10.0 */
24
#define MENVCFG_CBCFE BIT(6)
26
RISCV_EXCP_STORE_PAGE_FAULT = 0xf, /* since: priv-1.10.0 */
25
#define MENVCFG_CBZE BIT(7)
27
- RISCV_EXCP_SEMIHOST = 0x10,
26
-#define MENVCFG_HADE (1ULL << 61)
28
RISCV_EXCP_INST_GUEST_PAGE_FAULT = 0x14,
27
+#define MENVCFG_ADUE (1ULL << 61)
29
RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT = 0x15,
28
#define MENVCFG_PBMTE (1ULL << 62)
30
RISCV_EXCP_VIRT_INSTRUCTION_FAULT = 0x16,
29
#define MENVCFG_STCE (1ULL << 63)
31
RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT = 0x17,
30
32
+ RISCV_EXCP_SEMIHOST = 0x3f,
31
/* For RV32 */
33
} RISCVException;
32
-#define MENVCFGH_HADE BIT(29)
34
33
+#define MENVCFGH_ADUE BIT(29)
35
#define RISCV_EXCP_INT_FLAG 0x80000000
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,
73
}
74
75
bool pbmte = env->menvcfg & MENVCFG_PBMTE;
76
- bool hade = env->menvcfg & MENVCFG_HADE;
77
+ bool adue = env->menvcfg & MENVCFG_ADUE;
78
79
if (first_stage && two_stage && env->virt_enabled) {
80
pbmte = pbmte && (env->henvcfg & HENVCFG_PBMTE);
81
- hade = hade && (env->henvcfg & HENVCFG_HADE);
82
+ adue = adue && (env->henvcfg & HENVCFG_ADUE);
83
}
84
85
int ptshift = (levels - 1) * ptidxbits;
86
@@ -XXX,XX +XXX,XX @@ restart:
87
88
/* Page table updates need to be atomic with MTTCG enabled */
89
if (updated_pte != pte && !is_debug) {
90
- if (!hade) {
91
+ if (!adue) {
92
return TRANSLATE_FAIL;
93
}
94
95
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
96
index XXXXXXX..XXXXXXX 100644
97
--- a/target/riscv/csr.c
98
+++ b/target/riscv/csr.c
99
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
100
if (riscv_cpu_mxl(env) == MXL_RV64) {
101
mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
102
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
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
36
--
153
--
37
2.45.1
154
2.41.0
38
39
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Running a KVM guest using a 6.9-rc3 kernel, in a 6.8 host that has zkr
3
In the same emulated RISC-V host, the 'host' KVM CPU takes 4 times
4
enabled, will fail with a kernel oops SIGILL right at the start. The
4
longer to boot than the 'rv64' KVM CPU.
5
reason is that we can't expose zkr without implementing the SEED CSR.
6
Disabling zkr in the guest would be a workaround, but if the KVM doesn't
7
allow it we'll error out and never boot.
8
5
9
In hindsight this is too strict. If we keep proceeding, despite not
6
The reason is an unintended behavior of riscv_cpu_satp_mode_finalize()
10
disabling the extension in the KVM vcpu, we'll not add the extension in
7
when satp_mode.supported = 0, i.e. when cpu_init() does not set
11
the riscv,isa. The guest kernel will be unaware of the extension, i.e.
8
satp_mode_max_supported(). satp_mode_max_from_map(map) does:
12
it doesn't matter if the KVM vcpu has it enabled underneath or not. So
13
it's ok to keep booting in this case.
14
9
15
Change our current logic to not error out if we fail to disable an
10
31 - __builtin_clz(map)
16
extension in kvm_set_one_reg(), but show a warning and keep booting. It
17
is important to throw a warning because we must make the user aware that
18
the extension is still available in the vcpu, meaning that an
19
ill-behaved guest can ignore the riscv,isa settings and use the
20
extension.
21
11
22
The case we're handling happens with an EINVAL error code. If we fail to
12
This means that, if satp_mode.supported = 0, satp_mode_supported_max
23
disable the extension in KVM for any other reason, error out.
13
wil be '31 - 32'. But this is C, so satp_mode_supported_max will gladly
14
set it to UINT_MAX (4294967295). After that, if the user didn't set a
15
satp_mode, set_satp_mode_default_map(cpu) will make
24
16
25
We'll also keep erroring out when we fail to enable an extension in KVM,
17
cfg.satp_mode.map = cfg.satp_mode.supported
26
since adding the extension in riscv,isa at this point will cause a guest
27
malfunction because the extension isn't enabled in the vcpu.
28
18
29
Suggested-by: Andrew Jones <ajones@ventanamicro.com>
19
So satp_mode.map = 0. And then satp_mode_map_max will be set to
20
satp_mode_max_from_map(cpu->cfg.satp_mode.map), i.e. also UINT_MAX. The
21
guard "satp_mode_map_max > satp_mode_supported_max" doesn't protect us
22
here since both are UINT_MAX.
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")
30
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
41
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
31
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
42
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
32
Cc: qemu-stable <qemu-stable@nongnu.org>
43
Message-ID: <20230817152903.694926-1-dbarboza@ventanamicro.com>
33
Message-ID: <20240422171425.333037-2-dbarboza@ventanamicro.com>
34
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
44
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
---
45
---
36
target/riscv/kvm/kvm-cpu.c | 12 ++++++++----
46
target/riscv/cpu.c | 23 ++++++++++++++++++++---
37
1 file changed, 8 insertions(+), 4 deletions(-)
47
1 file changed, 20 insertions(+), 3 deletions(-)
38
48
39
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
49
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
40
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/kvm/kvm-cpu.c
51
--- a/target/riscv/cpu.c
42
+++ b/target/riscv/kvm/kvm-cpu.c
52
+++ b/target/riscv/cpu.c
43
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
53
@@ -XXX,XX +XXX,XX @@ static uint8_t satp_mode_from_str(const char *satp_mode_str)
44
reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
54
45
ret = kvm_set_one_reg(cs, id, &reg);
55
uint8_t satp_mode_max_from_map(uint32_t map)
46
if (ret != 0) {
56
{
47
- error_report("Unable to %s extension %s in KVM, error %d",
57
+ /*
48
- reg ? "enable" : "disable",
58
+ * 'map = 0' will make us return (31 - 32), which C will
49
- multi_ext_cfg->name, ret);
59
+ * happily overflow to UINT_MAX. There's no good result to
50
- exit(EXIT_FAILURE);
60
+ * return if 'map = 0' (e.g. returning 0 will be ambiguous
51
+ if (!reg && ret == -EINVAL) {
61
+ * with the result for 'map = 1').
52
+ warn_report("KVM cannot disable extension %s",
62
+ *
53
+ multi_ext_cfg->name);
63
+ * Assert out if map = 0. Callers will have to deal with
54
+ } else {
64
+ * it outside of this function.
55
+ error_report("Unable to enable extension %s in KVM, error %d",
65
+ */
56
+ multi_ext_cfg->name, ret);
66
+ g_assert(map > 0);
57
+ exit(EXIT_FAILURE);
67
+
58
+ }
68
/* map here has at least one bit set, so no problem with clz */
59
}
69
return 31 - __builtin_clz(map);
60
}
61
}
70
}
71
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
72
static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
73
{
74
bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
75
- uint8_t satp_mode_map_max;
76
- uint8_t satp_mode_supported_max =
77
- satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
78
+ uint8_t satp_mode_map_max, satp_mode_supported_max;
79
+
80
+ /* The CPU wants the OS to decide which satp mode to use */
81
+ if (cpu->cfg.satp_mode.supported == 0) {
82
+ return;
83
+ }
84
+
85
+ satp_mode_supported_max =
86
+ satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
87
88
if (cpu->cfg.satp_mode.map == 0) {
89
if (cpu->cfg.satp_mode.init == 0) {
62
--
90
--
63
2.45.1
91
2.41.0
diff view generated by jsdifflib
1
From: Yangyu Chen <cyy@cyyself.name>
1
From: Vineet Gupta <vineetg@rivosinc.com>
2
2
3
This code has a typo that writes zvkb to zvkg, causing users can't
3
zicond is now codegen supported in both llvm and gcc.
4
enable zvkb through the config. This patch gets this fixed.
5
4
6
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
5
This change allows seamless enabling/testing of zicond in downstream
7
Fixes: ea61ef7097d0 ("target/riscv: Move vector crypto extensions to riscv_cpu_extensions")
6
projects. e.g. currently riscv-gnu-toolchain parses elf attributes
8
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.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>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Max Chou <max.chou@sifive.com>
11
Reviewed-by:  Weiwei Li <liwei1518@gmail.com>
12
Message-ID: <tencent_7E34EEF0F90B9A68BF38BEE09EC6D4877C0A@qq.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
14
---
16
target/riscv/cpu.c | 2 +-
15
target/riscv/cpu.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
16
1 file changed, 1 insertion(+), 1 deletion(-)
18
17
19
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
20
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.c
20
--- a/target/riscv/cpu.c
22
+++ b/target/riscv/cpu.c
21
+++ b/target/riscv/cpu.c
23
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
22
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
24
/* Vector cryptography extensions */
23
DEFINE_PROP_BOOL("zcf", RISCVCPU, cfg.ext_zcf, false),
25
MULTI_EXT_CFG_BOOL("zvbb", ext_zvbb, false),
24
DEFINE_PROP_BOOL("zcmp", RISCVCPU, cfg.ext_zcmp, false),
26
MULTI_EXT_CFG_BOOL("zvbc", ext_zvbc, false),
25
DEFINE_PROP_BOOL("zcmt", RISCVCPU, cfg.ext_zcmt, false),
27
- MULTI_EXT_CFG_BOOL("zvkb", ext_zvkg, false),
26
+ DEFINE_PROP_BOOL("zicond", RISCVCPU, cfg.ext_zicond, false),
28
+ MULTI_EXT_CFG_BOOL("zvkb", ext_zvkb, false),
27
29
MULTI_EXT_CFG_BOOL("zvkg", ext_zvkg, false),
28
/* Vendor-specific custom extensions */
30
MULTI_EXT_CFG_BOOL("zvkned", ext_zvkned, false),
29
DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
31
MULTI_EXT_CFG_BOOL("zvknha", ext_zvknha, false),
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),
32
--
38
--
33
2.45.1
39
2.41.0
34
35
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Commit 33a24910ae changed 'reg_width' to use 'vlenb', i.e. vector length
3
A build with --enable-debug and without KVM will fail as follows:
4
in bytes, when in this context we want 'reg_width' as the length in
5
bits.
6
4
7
Fix 'reg_width' back to the value in bits like 7cb59921c05a
5
/usr/bin/ld: libqemu-riscv64-softmmu.fa.p/hw_riscv_virt.c.o: in function `virt_machine_init':
8
("target/riscv/gdbstub.c: use 'vlenb' instead of shifting 'vlen'") set
6
./qemu/build/../hw/riscv/virt.c:1465: undefined reference to `kvm_riscv_aia_create'
9
beforehand.
10
7
11
While we're at it, rename 'reg_width' to 'bitsize' to provide a bit more
8
This happens because the code block with "if virt_use_kvm_aia(s)" isn't
12
clarity about what the variable represents. 'bitsize' is also used in
9
being ignored by the debug build, resulting in an undefined reference to
13
riscv_gen_dynamic_csr_feature() with the same purpose, i.e. as an input to
10
a KVM only function.
14
gdb_feature_builder_append_reg().
15
11
16
Cc: Akihiko Odaki <akihiko.odaki@daynix.com>
12
Add a 'kvm_enabled()' conditional together with virt_use_kvm_aia() will
17
Cc: Alex Bennée <alex.bennee@linaro.org>
13
make the compiler crop the kvm_riscv_aia_create() call entirely from a
18
Reported-by: Robin Dapp <rdapp.gcc@gmail.com>
14
non-KVM build. Note that adding the 'kvm_enabled()' conditional inside
19
Fixes: 33a24910ae ("target/riscv: Use GDBFeature for dynamic XML")
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")
20
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
25
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
21
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
26
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
22
Acked-by: Alex Bennée <alex.bennee@linaro.org>
27
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
23
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
29
Message-ID: <20230830133503.711138-2-dbarboza@ventanamicro.com>
25
Cc: qemu-stable <qemu-stable@nongnu.org>
26
Message-ID: <20240517203054.880861-2-dbarboza@ventanamicro.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
31
---
29
target/riscv/gdbstub.c | 6 +++---
32
hw/riscv/virt.c | 6 +++---
30
1 file changed, 3 insertions(+), 3 deletions(-)
33
1 file changed, 3 insertions(+), 3 deletions(-)
31
34
32
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
35
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
33
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/gdbstub.c
37
--- a/hw/riscv/virt.c
35
+++ b/target/riscv/gdbstub.c
38
+++ b/hw/riscv/virt.c
36
@@ -XXX,XX +XXX,XX @@ static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg)
39
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
37
static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
38
{
39
RISCVCPU *cpu = RISCV_CPU(cs);
40
- int reg_width = cpu->cfg.vlenb;
41
+ int bitsize = cpu->cfg.vlenb << 3;
42
GDBFeatureBuilder builder;
43
int i;
44
45
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
46
47
/* First define types and totals in a whole VL */
48
for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
49
- int count = reg_width / vec_lanes[i].size;
50
+ int count = bitsize / vec_lanes[i].size;
51
gdb_feature_builder_append_tag(
52
&builder, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
53
vec_lanes[i].id, vec_lanes[i].gdb_type, count);
54
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
55
/* Define vector registers */
56
for (i = 0; i < 32; i++) {
57
gdb_feature_builder_append_reg(&builder, g_strdup_printf("v%d", i),
58
- reg_width, i, "riscv_vector", "vector");
59
+ bitsize, i, "riscv_vector", "vector");
60
}
40
}
61
41
62
gdb_feature_builder_end(&builder);
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)
58
}
59
}
60
61
- if (virt_use_kvm_aia(s)) {
62
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
63
kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT,
64
VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS,
65
memmap[VIRT_APLIC_S].base,
63
--
66
--
64
2.45.1
67
2.41.0
65
68
66
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
Privileged spec section 4.1.9 mentions:
3
Commit 6df0b37e2ab breaks a --enable-debug build in a non-KVM
4
environment with the following error:
4
5
5
"When a trap is taken into S-mode, stval is written with
6
/usr/bin/ld: libqemu-riscv64-softmmu.fa.p/hw_intc_riscv_aplic.c.o: in function `riscv_kvm_aplic_request':
6
exception-specific information to assist software in handling the trap.
7
./qemu/build/../hw/intc/riscv_aplic.c:486: undefined reference to `kvm_set_irq'
7
(...)
8
collect2: error: ld returned 1 exit status
8
9
9
If stval is written with a nonzero value when a breakpoint,
10
This happens because the debug build will poke into the
10
address-misaligned, access-fault, or page-fault exception occurs on an
11
'if (is_kvm_aia(aplic->msimode))' block and fail to find a reference to
11
instruction fetch, load, or store, then stval will contain the faulting
12
the KVM only function riscv_kvm_aplic_request().
12
virtual address."
13
13
14
A similar text is found for mtval in section 3.1.16.
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]:
15
20
16
Setting mtval/stval in this scenario is optional, but some softwares read
21
"(...) the compiler won't eliminate entire unused functions with -O0"
17
these regs when handling ebreaks.
18
22
19
Write 'badaddr' in all ebreak breakpoints to write the appropriate
23
We'll solve it by moving riscv_kvm_aplic_request() to kvm.c and add its
20
'tval' during riscv_do_cpu_interrrupt().
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/
21
29
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
30
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
31
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
24
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
32
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-ID: <20240416230437.1869024-3-dbarboza@ventanamicro.com>
34
Message-ID: <20230830133503.711138-3-dbarboza@ventanamicro.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
36
---
29
target/riscv/insn_trans/trans_privileged.c.inc | 2 ++
37
target/riscv/kvm_riscv.h | 1 +
30
1 file changed, 2 insertions(+)
38
hw/intc/riscv_aplic.c | 8 ++------
39
target/riscv/kvm.c | 5 +++++
40
3 files changed, 8 insertions(+), 6 deletions(-)
31
41
32
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
42
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
33
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/insn_trans/trans_privileged.c.inc
44
--- a/target/riscv/kvm_riscv.h
35
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
45
+++ b/target/riscv/kvm_riscv.h
36
@@ -XXX,XX +XXX,XX @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
46
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
37
if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) {
47
uint64_t aia_irq_num, uint64_t aia_msi_num,
38
generate_exception(ctx, RISCV_EXCP_SEMIHOST);
48
uint64_t aplic_base, uint64_t imsic_base,
39
} else {
49
uint64_t guest_num);
40
+ tcg_gen_st_tl(tcg_constant_tl(ebreak_addr), tcg_env,
50
+void riscv_kvm_aplic_request(void *opaque, int irq, int level);
41
+ offsetof(CPURISCVState, badaddr));
51
42
generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
52
#endif
43
}
53
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
44
return true;
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;
67
}
68
69
-static void riscv_kvm_aplic_request(void *opaque, int irq, int level)
70
-{
71
- kvm_set_irq(kvm_state, irq, !!level);
72
-}
73
-
74
static void riscv_aplic_request(void *opaque, int irq, int level)
75
{
76
bool update = false;
77
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
78
* have IRQ lines delegated by their parent APLIC.
79
*/
80
if (!aplic->parent) {
81
- if (is_kvm_aia(aplic->msimode)) {
82
+ if (kvm_enabled() && is_kvm_aia(aplic->msimode)) {
83
qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs);
84
} else {
85
qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
86
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
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
{
45
--
102
--
46
2.45.1
103
2.41.0
104
105
diff view generated by jsdifflib
New patch
1
From: Robbin Ehn <rehn@rivosinc.com>
1
2
3
This patch adds the new extensions in
4
linux 6.5 to the hwprobe syscall.
5
6
And fixes RVC check to OR with correct value.
7
The previous variable contains 0 therefore it
8
did work.
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>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
linux-user/syscall.c | 14 +++++++++++++-
17
1 file changed, 13 insertions(+), 1 deletion(-)
18
19
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/linux-user/syscall.c
22
+++ b/linux-user/syscall.c
23
@@ -XXX,XX +XXX,XX @@ static int do_getdents64(abi_long dirfd, abi_long arg2, abi_long count)
24
#define RISCV_HWPROBE_KEY_IMA_EXT_0 4
25
#define RISCV_HWPROBE_IMA_FD (1 << 0)
26
#define RISCV_HWPROBE_IMA_C (1 << 1)
27
+#define RISCV_HWPROBE_IMA_V (1 << 2)
28
+#define RISCV_HWPROBE_EXT_ZBA (1 << 3)
29
+#define RISCV_HWPROBE_EXT_ZBB (1 << 4)
30
+#define RISCV_HWPROBE_EXT_ZBS (1 << 5)
31
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:
51
--
52
2.41.0
diff view generated by jsdifflib
New patch
1
From: Ard Biesheuvel <ardb@kernel.org>
1
2
3
Use the accelerated SubBytes/ShiftRows/AddRoundKey AES helper to
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.
7
8
Cc: Richard Henderson <richard.henderson@linaro.org>
9
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Cc: Palmer Dabbelt <palmer@dabbelt.com>
11
Cc: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-ID: <20230831154118.138727-1-ardb@kernel.org>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
target/riscv/crypto_helper.c | 17 +++++------------
19
1 file changed, 5 insertions(+), 12 deletions(-)
20
21
diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/crypto_helper.c
24
+++ b/target/riscv/crypto_helper.c
25
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(aes64ks1i)(target_ulong rs1, target_ulong rnum)
26
27
uint8_t enc_rnum = rnum;
28
uint32_t temp = (RS1 >> 32) & 0xFFFFFFFF;
29
- uint8_t rcon_ = 0;
30
- target_ulong result;
31
+ AESState t, rc = {};
32
33
if (enc_rnum != 0xA) {
34
temp = ror32(temp, 8); /* Rotate right by 8 */
35
- rcon_ = round_consts[enc_rnum];
36
+ rc.w[0] = rc.w[1] = round_consts[enc_rnum];
37
}
38
39
- temp = ((uint32_t)AES_sbox[(temp >> 24) & 0xFF] << 24) |
40
- ((uint32_t)AES_sbox[(temp >> 16) & 0xFF] << 16) |
41
- ((uint32_t)AES_sbox[(temp >> 8) & 0xFF] << 8) |
42
- ((uint32_t)AES_sbox[(temp >> 0) & 0xFF] << 0);
43
+ t.w[0] = t.w[1] = t.w[2] = t.w[3] = temp;
44
+ aesenc_SB_SR_AK(&t, &t, &rc, false);
45
46
- temp ^= rcon_;
47
-
48
- result = ((uint64_t)temp << 32) | temp;
49
-
50
- return result;
51
+ return t.d[0];
52
}
53
54
target_ulong HELPER(aes64im)(target_ulong rs1)
55
--
56
2.41.0
57
58
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
We're not setting (s/m)tval when triggering breakpoints of type 2
3
riscv_trigger_init() had been called on reset events that can happen
4
(mcontrol) and 6 (mcontrol6). According to the debug spec section
4
several times for a CPU and it allocated timers for itrigger. If old
5
5.7.12, "Match Control Type 6":
5
timers were present, they were simply overwritten by the new timers,
6
resulting in a memory leak.
6
7
7
"The Privileged Spec says that breakpoint exceptions that occur on
8
Divide riscv_trigger_init() into two functions, namely
8
instruction fetches, loads, or stores update the tval CSR with either
9
riscv_trigger_realize() and riscv_trigger_reset() and call them in
9
zero or the faulting virtual address. The faulting virtual address for
10
appropriate timing. The timer allocation will happen only once for a
10
an mcontrol6 trigger with action = 0 is the address being accessed and
11
CPU in riscv_trigger_realize().
11
which caused that trigger to fire."
12
12
13
A similar text is also found in the Debug spec section 5.7.11 w.r.t.
13
Fixes: 5a4ae64cac ("target/riscv: Add itrigger support when icount is enabled")
14
mcontrol.
14
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
15
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Note that what we're doing ATM is not violating the spec, but it's
16
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
17
simple enough to set mtval/stval and it makes life easier for any
18
software that relies on this info.
19
20
Given that we always use action = 0, save the faulting address for the
21
mcontrol and mcontrol6 trigger breakpoints into env->badaddr, which is
22
used as as scratch area for traps with address information. 'tval' is
23
then set during riscv_cpu_do_interrupt().
24
25
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
26
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
27
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
18
Message-ID: <20230818034059.9146-1-akihiko.odaki@daynix.com>
28
Message-ID: <20240416230437.1869024-2-dbarboza@ventanamicro.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
---
20
---
31
target/riscv/cpu_helper.c | 1 +
21
target/riscv/debug.h | 3 ++-
32
target/riscv/debug.c | 3 +++
22
target/riscv/cpu.c | 8 +++++++-
33
2 files changed, 4 insertions(+)
23
target/riscv/debug.c | 15 ++++++++++++---
24
3 files changed, 21 insertions(+), 5 deletions(-)
34
25
35
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
26
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
36
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/cpu_helper.c
28
--- a/target/riscv/debug.h
38
+++ b/target/riscv/cpu_helper.c
29
+++ b/target/riscv/debug.h
39
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
30
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_debug_excp_handler(CPUState *cs);
40
tval = env->bins;
31
bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
41
break;
32
bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
42
case RISCV_EXCP_BREAKPOINT:
33
43
+ tval = env->badaddr;
34
-void riscv_trigger_init(CPURISCVState *env);
44
if (cs->watchpoint_hit) {
35
+void riscv_trigger_realize(CPURISCVState *env);
45
tval = cs->watchpoint_hit->hitaddr;
36
+void riscv_trigger_reset_hold(CPURISCVState *env);
46
cs->watchpoint_hit = NULL;
37
38
bool riscv_itrigger_enabled(CPURISCVState *env);
39
void riscv_itrigger_update_priv(CPURISCVState *env);
40
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/riscv/cpu.c
43
+++ b/target/riscv/cpu.c
44
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj)
45
46
#ifndef CONFIG_USER_ONLY
47
if (cpu->cfg.debug) {
48
- riscv_trigger_init(env);
49
+ riscv_trigger_reset_hold(env);
50
}
51
52
if (kvm_enabled()) {
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
47
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
66
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
48
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
49
--- a/target/riscv/debug.c
68
--- a/target/riscv/debug.c
50
+++ b/target/riscv/debug.c
69
+++ b/target/riscv/debug.c
51
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
70
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
52
if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
71
return false;
53
/* check U/S/M bit against current privilege level */
72
}
54
if ((ctrl >> 3) & BIT(env->priv)) {
73
55
+ env->badaddr = pc;
74
-void riscv_trigger_init(CPURISCVState *env)
56
return true;
75
+void riscv_trigger_realize(CPURISCVState *env)
57
}
76
+{
58
}
77
+ int i;
59
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
78
+
60
if (env->virt_enabled) {
79
+ for (i = 0; i < RV_MAX_TRIGGERS; i++) {
61
/* check VU/VS bit against current privilege level */
80
+ env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
62
if ((ctrl >> 23) & BIT(env->priv)) {
81
+ riscv_itrigger_timer_cb, env);
63
+ env->badaddr = pc;
82
+ }
64
return true;
83
+}
65
}
84
+
66
} else {
85
+void riscv_trigger_reset_hold(CPURISCVState *env)
67
/* check U/S/M bit against current privilege level */
86
{
68
if ((ctrl >> 3) & BIT(env->priv)) {
87
target_ulong tdata1 = build_tdata1(env, TRIGGER_TYPE_AD_MATCH, 0, 0);
69
+ env->badaddr = pc;
88
int i;
70
return true;
89
@@ -XXX,XX +XXX,XX @@ void riscv_trigger_init(CPURISCVState *env)
71
}
90
env->tdata3[i] = 0;
72
}
91
env->cpu_breakpoint[i] = NULL;
92
env->cpu_watchpoint[i] = NULL;
93
- env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
94
- riscv_itrigger_timer_cb, env);
95
+ timer_del(env->itrigger_timer[i]);
96
}
97
}
73
--
98
--
74
2.45.1
99
2.41.0
100
101
diff view generated by jsdifflib
1
From: Alistair Francis <alistair23@gmail.com>
1
From: Leon Schuermann <leons@opentitan.org>
2
2
3
Previously we only listed a single pmpcfg CSR and the first 16 pmpaddr
3
When the rule-lock bypass (RLB) bit is set in the mseccfg CSR, the PMP
4
CSRs. This patch fixes this to list all 16 pmpcfg and all 64 pmpaddr
4
configuration lock bits must not apply. While this behavior is
5
CSRs are part of the disassembly.
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.
6
9
7
Reported-by: Eric DeVolder <eric_devolder@yahoo.com>
10
Signed-off-by: Leon Schuermann <leons@opentitan.org>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Mayuresh Chitale <mchitale@ventanamicro.com>
9
Fixes: ea10325917 ("RISC-V Disassembler")
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Message-ID: <20230829215046.1430463-1-leon@is.currently.online>
11
Cc: qemu-stable <qemu-stable@nongnu.org>
12
Message-ID: <20240514051615.330979-1-alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
---
15
disas/riscv.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++-
16
target/riscv/pmp.c | 4 ++++
16
1 file changed, 64 insertions(+), 1 deletion(-)
17
1 file changed, 4 insertions(+)
17
18
18
diff --git a/disas/riscv.c b/disas/riscv.c
19
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
19
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
20
--- a/disas/riscv.c
21
--- a/target/riscv/pmp.c
21
+++ b/disas/riscv.c
22
+++ b/target/riscv/pmp.c
22
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
23
@@ -XXX,XX +XXX,XX @@ static inline uint8_t pmp_get_a_field(uint8_t cfg)
23
case 0x0383: return "mibound";
24
*/
24
case 0x0384: return "mdbase";
25
static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
25
case 0x0385: return "mdbound";
26
{
26
- case 0x03a0: return "pmpcfg3";
27
+ /* mseccfg.RLB is set */
27
+ case 0x03a0: return "pmpcfg0";
28
+ if (MSECCFG_RLB_ISSET(env)) {
28
+ case 0x03a1: return "pmpcfg1";
29
+ return 0;
29
+ case 0x03a2: return "pmpcfg2";
30
+ }
30
+ case 0x03a3: return "pmpcfg3";
31
31
+ case 0x03a4: return "pmpcfg4";
32
if (env->pmp_state.pmp[pmp_index].cfg_reg & PMP_LOCK) {
32
+ case 0x03a5: return "pmpcfg5";
33
return 1;
33
+ case 0x03a6: return "pmpcfg6";
34
+ case 0x03a7: return "pmpcfg7";
35
+ case 0x03a8: return "pmpcfg8";
36
+ case 0x03a9: return "pmpcfg9";
37
+ case 0x03aa: return "pmpcfg10";
38
+ case 0x03ab: return "pmpcfg11";
39
+ case 0x03ac: return "pmpcfg12";
40
+ case 0x03ad: return "pmpcfg13";
41
+ case 0x03ae: return "pmpcfg14";
42
+ case 0x03af: return "pmpcfg15";
43
case 0x03b0: return "pmpaddr0";
44
case 0x03b1: return "pmpaddr1";
45
case 0x03b2: return "pmpaddr2";
46
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
47
case 0x03bd: return "pmpaddr13";
48
case 0x03be: return "pmpaddr14";
49
case 0x03bf: return "pmpaddr15";
50
+ case 0x03c0: return "pmpaddr16";
51
+ case 0x03c1: return "pmpaddr17";
52
+ case 0x03c2: return "pmpaddr18";
53
+ case 0x03c3: return "pmpaddr19";
54
+ case 0x03c4: return "pmpaddr20";
55
+ case 0x03c5: return "pmpaddr21";
56
+ case 0x03c6: return "pmpaddr22";
57
+ case 0x03c7: return "pmpaddr23";
58
+ case 0x03c8: return "pmpaddr24";
59
+ case 0x03c9: return "pmpaddr25";
60
+ case 0x03ca: return "pmpaddr26";
61
+ case 0x03cb: return "pmpaddr27";
62
+ case 0x03cc: return "pmpaddr28";
63
+ case 0x03cd: return "pmpaddr29";
64
+ case 0x03ce: return "pmpaddr30";
65
+ case 0x03cf: return "pmpaddr31";
66
+ case 0x03d0: return "pmpaddr32";
67
+ case 0x03d1: return "pmpaddr33";
68
+ case 0x03d2: return "pmpaddr34";
69
+ case 0x03d3: return "pmpaddr35";
70
+ case 0x03d4: return "pmpaddr36";
71
+ case 0x03d5: return "pmpaddr37";
72
+ case 0x03d6: return "pmpaddr38";
73
+ case 0x03d7: return "pmpaddr39";
74
+ case 0x03d8: return "pmpaddr40";
75
+ case 0x03d9: return "pmpaddr41";
76
+ case 0x03da: return "pmpaddr42";
77
+ case 0x03db: return "pmpaddr43";
78
+ case 0x03dc: return "pmpaddr44";
79
+ case 0x03dd: return "pmpaddr45";
80
+ case 0x03de: return "pmpaddr46";
81
+ case 0x03df: return "pmpaddr47";
82
+ case 0x03e0: return "pmpaddr48";
83
+ case 0x03e1: return "pmpaddr49";
84
+ case 0x03e2: return "pmpaddr50";
85
+ case 0x03e3: return "pmpaddr51";
86
+ case 0x03e4: return "pmpaddr52";
87
+ case 0x03e5: return "pmpaddr53";
88
+ case 0x03e6: return "pmpaddr54";
89
+ case 0x03e7: return "pmpaddr55";
90
+ case 0x03e8: return "pmpaddr56";
91
+ case 0x03e9: return "pmpaddr57";
92
+ case 0x03ea: return "pmpaddr58";
93
+ case 0x03eb: return "pmpaddr59";
94
+ case 0x03ec: return "pmpaddr60";
95
+ case 0x03ed: return "pmpaddr61";
96
+ case 0x03ee: return "pmpaddr62";
97
+ case 0x03ef: return "pmpaddr63";
98
case 0x0780: return "mtohost";
99
case 0x0781: return "mfromhost";
100
case 0x0782: return "mreset";
101
--
34
--
102
2.45.1
35
2.41.0
diff view generated by jsdifflib
1
From: Andrew Jones <ajones@ventanamicro.com>
1
From: Tommy Wu <tommy.wu@sifive.com>
2
2
3
The Zkr extension may only be exposed to KVM guests if the VMM
3
According to the new spec, when vsiselect has a reserved value, attempts
4
implements the SEED CSR. Use the same implementation as TCG.
4
from M-mode or HS-mode to access vsireg, or from VS-mode to access
5
sireg, should preferably raise an illegal instruction exception.
5
6
6
Without this patch, running with a KVM which does not forward the
7
Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
7
SEED CSR access to QEMU will result in an ILL exception being
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
injected into the guest (this results in Linux guests crashing on
9
Message-ID: <20230816061647.600672-1-tommy.wu@sifive.com>
9
boot). And, when running with a KVM which does forward the access,
10
QEMU will crash, since QEMU doesn't know what to do with the exit.
11
12
Fixes: 3108e2f1c69d ("target/riscv/kvm: update KVM exts to Linux 6.8")
13
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Cc: qemu-stable <qemu-stable@nongnu.org>
16
Message-ID: <20240422134605.534207-2-ajones@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
target/riscv/cpu.h | 3 +++
12
target/riscv/csr.c | 7 +++++--
20
target/riscv/csr.c | 18 ++++++++++++++----
13
1 file changed, 5 insertions(+), 2 deletions(-)
21
target/riscv/kvm/kvm-cpu.c | 25 +++++++++++++++++++++++++
22
3 files changed, 42 insertions(+), 4 deletions(-)
23
14
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
28
@@ -XXX,XX +XXX,XX @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
29
30
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
31
32
+target_ulong riscv_new_csr_seed(target_ulong new_value,
33
+ target_ulong write_mask);
34
+
35
uint8_t satp_mode_max_from_map(uint32_t map);
36
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
37
38
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
39
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/csr.c
17
--- a/target/riscv/csr.c
41
+++ b/target/riscv/csr.c
18
+++ b/target/riscv/csr.c
42
@@ -XXX,XX +XXX,XX @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
19
@@ -XXX,XX +XXX,XX @@ static int rmw_iprio(target_ulong xlen,
43
#endif
20
static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
44
21
target_ulong new_val, target_ulong wr_mask)
45
/* Crypto Extension */
46
-static RISCVException rmw_seed(CPURISCVState *env, int csrno,
47
- target_ulong *ret_value,
48
- target_ulong new_value,
49
- target_ulong write_mask)
50
+target_ulong riscv_new_csr_seed(target_ulong new_value,
51
+ target_ulong write_mask)
52
{
22
{
53
uint16_t random_v;
23
- bool virt;
54
Error *random_e = NULL;
24
+ bool virt, isel_reserved;
55
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
25
uint8_t *iprio;
56
rval = random_v | SEED_OPST_ES16;
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;
57
}
42
}
58
43
59
+ return rval;
44
done:
60
+}
45
if (ret) {
61
+
46
- return (env->virt_enabled && virt) ?
62
+static RISCVException rmw_seed(CPURISCVState *env, int csrno,
47
+ return (env->virt_enabled && virt && !isel_reserved) ?
63
+ target_ulong *ret_value,
48
RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
64
+ target_ulong new_value,
65
+ target_ulong write_mask)
66
+{
67
+ target_ulong rval;
68
+
69
+ rval = riscv_new_csr_seed(new_value, write_mask);
70
+
71
if (ret_value) {
72
*ret_value = rval;
73
}
49
}
74
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
50
return RISCV_EXCP_NONE;
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/riscv/kvm/kvm-cpu.c
77
+++ b/target/riscv/kvm/kvm-cpu.c
78
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
79
return ret;
80
}
81
82
+static int kvm_riscv_handle_csr(CPUState *cs, struct kvm_run *run)
83
+{
84
+ target_ulong csr_num = run->riscv_csr.csr_num;
85
+ target_ulong new_value = run->riscv_csr.new_value;
86
+ target_ulong write_mask = run->riscv_csr.write_mask;
87
+ int ret = 0;
88
+
89
+ switch (csr_num) {
90
+ case CSR_SEED:
91
+ run->riscv_csr.ret_value = riscv_new_csr_seed(new_value, write_mask);
92
+ break;
93
+ default:
94
+ qemu_log_mask(LOG_UNIMP,
95
+ "%s: un-handled CSR EXIT for CSR %lx\n",
96
+ __func__, csr_num);
97
+ ret = -1;
98
+ break;
99
+ }
100
+
101
+ return ret;
102
+}
103
+
104
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
105
{
106
int ret = 0;
107
@@ -XXX,XX +XXX,XX @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
108
case KVM_EXIT_RISCV_SBI:
109
ret = kvm_riscv_handle_sbi(cs, run);
110
break;
111
+ case KVM_EXIT_RISCV_CSR:
112
+ ret = kvm_riscv_handle_csr(cs, run);
113
+ break;
114
default:
115
qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
116
__func__, run->exit_reason);
117
--
51
--
118
2.45.1
52
2.41.0
diff view generated by jsdifflib
1
From: Yu-Ming Chang <yumin686@andestech.com>
1
From: Nikita Shubin <n.shubin@yadro.com>
2
2
3
Both CSRRS and CSRRC always read the addressed CSR and cause any read side
3
As per ISA:
4
effects regardless of rs1 and rd fields. Note that if rs1 specifies a register
5
holding a zero value other than x0, the instruction will still attempt to write
6
the unmodified value back to the CSR and will cause any attendant side effects.
7
4
8
So if CSRRS or CSRRC tries to write a read-only CSR with rs1 which specifies
5
"For CSRRWI, if rd=x0, then the instruction shall not read the CSR and
9
a register holding a zero value, an illegal instruction exception should be
6
shall not cause any of the side effects that might occur on a CSR read."
10
raised.
11
7
12
Signed-off-by: Yu-Ming Chang <yumin686@andestech.com>
8
trans_csrrwi() and trans_csrrw() call do_csrw() if rd=x0, do_csrw() calls
9
riscv_csrrw_do64(), via helper_csrw() passing NULL as *ret_value.
10
11
Signed-off-by: Nikita Shubin <n.shubin@yadro.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-ID: <20240403070823.80897-1-yumin686@andestech.com>
13
Message-ID: <20230808090914.17634-1-nikita.shubin@maquefel.me>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
15
---
17
target/riscv/cpu.h | 4 ++++
16
target/riscv/csr.c | 24 +++++++++++++++---------
18
target/riscv/csr.c | 51 ++++++++++++++++++++++++++++++++++++----
17
1 file changed, 15 insertions(+), 9 deletions(-)
19
target/riscv/op_helper.c | 6 ++---
20
3 files changed, 53 insertions(+), 8 deletions(-)
21
18
22
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/cpu.h
25
+++ b/target/riscv/cpu.h
26
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
27
void riscv_cpu_update_mask(CPURISCVState *env);
28
bool riscv_cpu_is_32bit(RISCVCPU *cpu);
29
30
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
31
+ target_ulong *ret_value);
32
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
33
target_ulong *ret_value,
34
target_ulong new_value, target_ulong write_mask);
35
@@ -XXX,XX +XXX,XX @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
36
target_ulong new_value,
37
target_ulong write_mask);
38
39
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
40
+ Int128 *ret_value);
41
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
42
Int128 *ret_value,
43
Int128 new_value, Int128 write_mask);
44
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
45
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
46
--- a/target/riscv/csr.c
21
--- a/target/riscv/csr.c
47
+++ b/target/riscv/csr.c
22
+++ b/target/riscv/csr.c
48
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
49
50
static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
51
int csrno,
52
- bool write_mask)
53
+ bool write)
54
{
55
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
56
bool read_only = get_field(csrno, 0xC00) == 3;
57
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
58
}
59
60
/* read / write check */
61
- if (write_mask && read_only) {
62
+ if (write && read_only) {
63
return RISCV_EXCP_ILLEGAL_INST;
64
}
65
66
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
23
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
67
return RISCV_EXCP_NONE;
24
target_ulong write_mask)
68
}
69
70
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
71
+ target_ulong *ret_value)
72
+{
73
+ RISCVException ret = riscv_csrrw_check(env, csrno, false);
74
+ if (ret != RISCV_EXCP_NONE) {
75
+ return ret;
76
+ }
77
+
78
+ return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
79
+}
80
+
81
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
82
target_ulong *ret_value,
83
target_ulong new_value, target_ulong write_mask)
84
{
85
- RISCVException ret = riscv_csrrw_check(env, csrno, write_mask);
86
+ RISCVException ret = riscv_csrrw_check(env, csrno, true);
87
if (ret != RISCV_EXCP_NONE) {
88
return ret;
89
}
90
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
91
return RISCV_EXCP_NONE;
92
}
93
94
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
95
+ Int128 *ret_value)
96
+{
97
+ RISCVException ret;
98
+
99
+ ret = riscv_csrrw_check(env, csrno, false);
100
+ if (ret != RISCV_EXCP_NONE) {
101
+ return ret;
102
+ }
103
+
104
+ if (csr_ops[csrno].read128) {
105
+ return riscv_csrrw_do128(env, csrno, ret_value,
106
+ int128_zero(), int128_zero());
107
+ }
108
+
109
+ /*
110
+ * Fall back to 64-bit version for now, if the 128-bit alternative isn't
111
+ * at all defined.
112
+ * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
113
+ * significant), for those, this fallback is correctly handling the
114
+ * accesses
115
+ */
116
+ target_ulong old_value;
117
+ ret = riscv_csrrw_do64(env, csrno, &old_value,
118
+ (target_ulong)0,
119
+ (target_ulong)0);
120
+ if (ret == RISCV_EXCP_NONE && ret_value) {
121
+ *ret_value = int128_make64(old_value);
122
+ }
123
+ return ret;
124
+}
125
+
126
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
127
Int128 *ret_value,
128
Int128 new_value, Int128 write_mask)
129
{
25
{
130
RISCVException ret;
26
RISCVException ret;
131
27
- target_ulong old_value;
132
- ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask));
28
+ target_ulong old_value = 0;
133
+ ret = riscv_csrrw_check(env, csrno, true);
29
134
if (ret != RISCV_EXCP_NONE) {
30
/* execute combined read/write operation if it exists */
135
return ret;
31
if (csr_ops[csrno].op) {
32
return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
136
}
33
}
137
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
34
138
index XXXXXXX..XXXXXXX 100644
35
- /* if no accessor exists then return failure */
139
--- a/target/riscv/op_helper.c
36
- if (!csr_ops[csrno].read) {
140
+++ b/target/riscv/op_helper.c
37
- return RISCV_EXCP_ILLEGAL_INST;
141
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
38
- }
39
- /* read old value */
40
- ret = csr_ops[csrno].read(env, csrno, &old_value);
41
- if (ret != RISCV_EXCP_NONE) {
42
- return ret;
43
+ /*
44
+ * ret_value == NULL means that rd=x0 and we're coming from helper_csrw()
45
+ * and we can't throw side effects caused by CSR reads.
46
+ */
47
+ if (ret_value) {
48
+ /* if no accessor exists then return failure */
49
+ if (!csr_ops[csrno].read) {
50
+ return RISCV_EXCP_ILLEGAL_INST;
51
+ }
52
+ /* read old value */
53
+ ret = csr_ops[csrno].read(env, csrno, &old_value);
54
+ if (ret != RISCV_EXCP_NONE) {
55
+ return ret;
56
+ }
142
}
57
}
143
58
144
target_ulong val = 0;
59
/* write value if writable and write mask set, otherwise drop writes */
145
- RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
146
+ RISCVException ret = riscv_csrr(env, csr, &val);
147
148
if (ret != RISCV_EXCP_NONE) {
149
riscv_raise_exception(env, ret, GETPC());
150
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
151
target_ulong helper_csrr_i128(CPURISCVState *env, int csr)
152
{
153
Int128 rv = int128_zero();
154
- RISCVException ret = riscv_csrrw_i128(env, csr, &rv,
155
- int128_zero(),
156
- int128_zero());
157
+ RISCVException ret = riscv_csrr_i128(env, csr, &rv);
158
159
if (ret != RISCV_EXCP_NONE) {
160
riscv_raise_exception(env, ret, GETPC());
161
--
60
--
162
2.45.1
61
2.41.0
diff view generated by jsdifflib