1
From: Alistair Francis <alistair.francis@wdc.com>
1
The following changes since commit c5ea91da443b458352c1b629b490ee6631775cb4:
2
2
3
The following changes since commit 6661b8c7fe3f8b5687d2d90f7b4f3f23d70e3e8b:
3
Merge tag 'pull-trivial-patches' of https://gitlab.com/mjt0k/qemu into staging (2023-09-08 10:06:25 -0400)
4
5
Merge tag 'pull-ppc-20230205' of https://gitlab.com/danielhb/qemu into staging (2023-02-05 16:49:09 +0000)
6
4
7
are available in the Git repository at:
5
are available in the Git repository at:
8
6
9
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20230207
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20230911
10
8
11
for you to fetch changes up to 5474aa4f3e0a3e9c171db7c55b5baf15f2e2778c:
9
for you to fetch changes up to e7a03409f29e2da59297d55afbaec98c96e43e3a:
12
10
13
hw/riscv: virt: Simplify virt_{get,set}_aclint() (2023-02-07 08:21:32 +1000)
11
target/riscv: don't read CSR in riscv_csrrw_do64 (2023-09-11 11:45:55 +1000)
14
12
15
----------------------------------------------------------------
13
----------------------------------------------------------------
16
Third RISC-V PR for QEMU 8.0
14
First RISC-V PR for 8.2
17
15
18
* Update disas for xnor/orn/andn and slli.uw
16
* Remove 'host' CPU from TCG
19
* Update opentitan IRQs
17
* riscv_htif Fixup printing on big endian hosts
20
* Fix rom code when Zicsr is disabled
18
* Add zmmul isa string
21
* Update VS timer whenever htimedelta changes
19
* Add smepmp isa string
22
* A collection of fixes for virtulisation
20
* Fix page_check_range use in fault-only-first
23
* Set tval for triggered watchpoints
21
* Use existing lookup tables for MixColumns
24
* Cleanups for board and FDT creation
22
* Add RISC-V vector cryptographic instruction set support
25
* Add support for the T-Head vendor extensions
23
* Implement WARL behaviour for mcountinhibit/mcounteren
26
* A fix for virtual instr exception
24
* Add Zihintntl extension ISA string to DTS
27
* Fix ctzw behavior
25
* Fix zfa fleq.d and fltq.d
28
* Fix SBI getchar handler for KVM
26
* Fix upper/lower mtime write calculation
27
* Make rtc variable names consistent
28
* Use abi type for linux-user target_ucontext
29
* Add RISC-V KVM AIA Support
30
* Fix riscv,pmu DT node path in the virt machine
31
* Update CSR bits name for svadu extension
32
* Mark zicond non-experimental
33
* Fix satp_mode_finalize() when satp_mode.supported = 0
34
* Fix non-KVM --enable-debug build
35
* Add new extensions to hwprobe
36
* Use accelerated helper for AES64KS1I
37
* Allocate itrigger timers only once
38
* Respect mseccfg.RLB for pmpaddrX changes
39
* Align the AIA model to v1.0 ratified spec
40
* Don't read the CSR in riscv_csrrw_do64
29
41
30
----------------------------------------------------------------
42
----------------------------------------------------------------
31
Alistair Francis (1):
43
Akihiko Odaki (1):
32
hw/riscv: boot: Don't use CSRs if they are disabled
44
target/riscv: Allocate itrigger timers only once
33
45
34
Anup Patel (4):
46
Ard Biesheuvel (2):
35
target/riscv: Update VS timer whenever htimedelta changes
47
target/riscv: Use existing lookup tables for MixColumns
36
target/riscv: Don't clear mask in riscv_cpu_update_mip() for VSTIP
48
target/riscv: Use accelerated helper for AES64KS1I
37
target/riscv: No need to re-start QEMU timer when timecmp == UINT64_MAX
38
target/riscv: Ensure opcode is saved for all relevant instructions
39
49
40
Bin Meng (1):
50
Conor Dooley (1):
41
hw/riscv: virt: Simplify virt_{get,set}_aclint()
51
hw/riscv: virt: Fix riscv,pmu DT node path
42
43
Christoph Müllner (14):
44
RISC-V: Adding XTheadCmo ISA extension
45
RISC-V: Adding XTheadSync ISA extension
46
RISC-V: Adding XTheadBa ISA extension
47
RISC-V: Adding XTheadBb ISA extension
48
RISC-V: Adding XTheadBs ISA extension
49
RISC-V: Adding XTheadCondMov ISA extension
50
RISC-V: Adding T-Head multiply-accumulate instructions
51
RISC-V: Adding T-Head MemPair extension
52
RISC-V: Adding T-Head MemIdx extension
53
RISC-V: Adding T-Head FMemIdx extension
54
RISC-V: Set minimum priv version for Zfh to 1.11
55
RISC-V: Add initial support for T-Head C906
56
RISC-V: Adding XTheadFmv ISA extension
57
target/riscv: add a MAINTAINERS entry for XThead* extension support
58
52
59
Daniel Henrique Barboza (6):
53
Daniel Henrique Barboza (6):
60
hw/riscv/virt.c: calculate socket count once in create_fdt_imsic()
54
target/riscv/cpu.c: do not run 'host' CPU with TCG
61
hw/riscv/virt.c: rename MachineState 'mc' pointers to 'ms'
55
target/riscv/cpu.c: add zmmul isa string
62
hw/riscv/spike.c: rename MachineState 'mc' pointers to' ms'
56
target/riscv/cpu.c: add smepmp isa string
63
hw/riscv/boot.c: calculate fdt size after fdt_pack()
57
target/riscv: fix satp_mode_finalize() when satp_mode.supported = 0
64
hw/riscv: split fdt address calculation from fdt load
58
hw/riscv/virt.c: fix non-KVM --enable-debug build
65
hw/riscv: change riscv_compute_fdt_addr() semantics
59
hw/intc/riscv_aplic.c fix non-KVM --enable-debug build
66
60
67
Deepak Gupta (1):
61
Dickon Hood (2):
68
target/riscv: fix for virtual instr exception
62
target/riscv: Refactor translation of vector-widening instruction
63
target/riscv: Add Zvbb ISA extension support
69
64
70
Philipp Tomsich (1):
65
Jason Chien (3):
71
target/riscv: update disas.c for xnor/orn/andn and slli.uw
66
target/riscv: Add Zihintntl extension ISA string to DTS
67
hw/intc: Fix upper/lower mtime write calculation
68
hw/intc: Make rtc variable names consistent
72
69
73
Sergey Matyukevich (1):
70
Kiran Ostrolenk (4):
74
target/riscv: set tval for triggered watchpoints
71
target/riscv: Refactor some of the generic vector functionality
72
target/riscv: Refactor vector-vector translation macro
73
target/riscv: Refactor some of the generic vector functionality
74
target/riscv: Add Zvknh ISA extension support
75
75
76
Vladimir Isaev (2):
76
LIU Zhiwei (3):
77
target/riscv: fix ctzw behavior
77
target/riscv: Fix page_check_range use in fault-only-first
78
target/riscv: fix SBI getchar handler for KVM
78
target/riscv: Fix zfa fleq.d and fltq.d
79
linux-user/riscv: Use abi type for target_ucontext
79
80
80
Wilfred Mallawa (1):
81
Lawrence Hunter (2):
81
include/hw/riscv/opentitan: update opentitan IRQs
82
target/riscv: Add Zvbc ISA extension support
83
target/riscv: Add Zvksh ISA extension support
82
84
83
MAINTAINERS | 8 +
85
Leon Schuermann (1):
84
include/hw/riscv/boot.h | 4 +-
86
target/riscv/pmp.c: respect mseccfg.RLB for pmpaddrX changes
85
include/hw/riscv/opentitan.h | 14 +-
87
86
target/riscv/cpu.h | 12 +
88
Max Chou (3):
87
target/riscv/cpu_vendorid.h | 6 +
89
crypto: Create sm4_subword
88
target/riscv/helper.h | 1 +
90
crypto: Add SM4 constant parameter CK
89
target/riscv/xthead.decode | 185 +++++
91
target/riscv: Add Zvksed ISA extension support
90
disas/riscv.c | 8 +-
92
91
hw/riscv/boot.c | 62 +-
93
Nazar Kazakov (4):
92
hw/riscv/microchip_pfsoc.c | 7 +-
94
target/riscv: Remove redundant "cpu_vl == 0" checks
93
hw/riscv/opentitan.c | 80 +-
95
target/riscv: Move vector translation checks
94
hw/riscv/sifive_u.c | 8 +-
96
target/riscv: Add Zvkned ISA extension support
95
hw/riscv/spike.c | 25 +-
97
target/riscv: Add Zvkg ISA extension support
96
hw/riscv/virt.c | 476 ++++++------
98
97
target/riscv/cpu.c | 55 +-
99
Nikita Shubin (1):
98
target/riscv/cpu_helper.c | 8 +-
100
target/riscv: don't read CSR in riscv_csrrw_do64
99
target/riscv/csr.c | 16 +
101
100
target/riscv/debug.c | 1 -
102
Rob Bradford (1):
101
target/riscv/kvm.c | 5 +-
103
target/riscv: Implement WARL behaviour for mcountinhibit/mcounteren
102
target/riscv/op_helper.c | 6 +
104
103
target/riscv/time_helper.c | 36 +-
105
Robbin Ehn (1):
104
target/riscv/translate.c | 32 +
106
linux-user/riscv: Add new extensions to hwprobe
105
target/riscv/insn_trans/trans_rva.c.inc | 10 +-
107
106
target/riscv/insn_trans/trans_rvb.c.inc | 1 +
108
Thomas Huth (2):
107
target/riscv/insn_trans/trans_rvd.c.inc | 2 +
109
hw/char/riscv_htif: Fix printing of console characters on big endian hosts
108
target/riscv/insn_trans/trans_rvf.c.inc | 2 +
110
hw/char/riscv_htif: Fix the console syscall on big endian hosts
109
target/riscv/insn_trans/trans_rvh.c.inc | 3 +
111
110
target/riscv/insn_trans/trans_rvi.c.inc | 2 +
112
Tommy Wu (1):
111
target/riscv/insn_trans/trans_rvzfh.c.inc | 2 +
113
target/riscv: Align the AIA model to v1.0 ratified spec
112
target/riscv/insn_trans/trans_svinval.c.inc | 3 +
114
113
target/riscv/insn_trans/trans_xthead.c.inc | 1094 +++++++++++++++++++++++++++
115
Vineet Gupta (1):
114
target/riscv/meson.build | 1 +
116
riscv: zicond: make non-experimental
115
32 files changed, 1847 insertions(+), 328 deletions(-)
117
116
create mode 100644 target/riscv/cpu_vendorid.h
118
Weiwei Li (1):
117
create mode 100644 target/riscv/xthead.decode
119
target/riscv: Update CSR bits name for svadu extension
118
create mode 100644 target/riscv/insn_trans/trans_xthead.c.inc
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: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
This patch adds support for the T-Head MemPair instructions.
3
The 'host' CPU is available in a CONFIG_KVM build and it's currently
4
The patch uses the T-Head specific decoder and translation.
4
available for all accels, but is a KVM only CPU. This means that in a
5
RISC-V KVM capable host we can do things like this:
5
6
6
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
7
$ ./build/qemu-system-riscv64 -M virt,accel=tcg -cpu host --nographic
8
qemu-system-riscv64: H extension requires priv spec 1.12.0
9
10
This CPU does not have a priv spec because we don't filter its extensions
11
via priv spec. We shouldn't be reaching riscv_cpu_realize_tcg() at all
12
with the 'host' CPU.
13
14
We don't have a way to filter the 'host' CPU out of the available CPU
15
options (-cpu help) if the build includes both KVM and TCG. What we can
16
do is to error out during riscv_cpu_realize_tcg() if the user chooses
17
the 'host' CPU with accel=tcg:
18
19
$ ./build/qemu-system-riscv64 -M virt,accel=tcg -cpu host --nographic
20
qemu-system-riscv64: 'host' CPU is not compatible with TCG acceleration
21
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
25
Message-Id: <20230721133411.474105-1-dbarboza@ventanamicro.com>
10
Message-Id: <20230131202013.2541053-9-christoph.muellner@vrull.eu>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
26
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
27
---
13
target/riscv/cpu.h | 1 +
28
target/riscv/cpu.c | 5 +++++
14
target/riscv/xthead.decode | 13 +++
29
1 file changed, 5 insertions(+)
15
target/riscv/cpu.c | 2 +
16
target/riscv/translate.c | 2 +-
17
target/riscv/insn_trans/trans_xthead.c.inc | 92 ++++++++++++++++++++++
18
5 files changed, 109 insertions(+), 1 deletion(-)
19
30
20
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/cpu.h
23
+++ b/target/riscv/cpu.h
24
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
25
bool ext_xtheadcmo;
26
bool ext_xtheadcondmov;
27
bool ext_xtheadmac;
28
+ bool ext_xtheadmempair;
29
bool ext_xtheadsync;
30
bool ext_XVentanaCondOps;
31
32
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/xthead.decode
35
+++ b/target/riscv/xthead.decode
36
@@ -XXX,XX +XXX,XX @@
37
38
# Fields:
39
%rd 7:5
40
+%rd1 7:5
41
+%rs 15:5
42
%rs1 15:5
43
+%rd2 20:5
44
%rs2 20:5
45
%sh5 20:5
46
%sh6 20:6
47
+%sh2 25:2
48
49
# Argument sets
50
&r rd rs1 rs2 !extern
51
&r2 rd rs1 !extern
52
&shift shamt rs1 rd !extern
53
&th_bfext msb lsb rs1 rd
54
+&th_pair rd1 rs rd2 sh2
55
56
# Formats
57
@sfence_vm ....... ..... ..... ... ..... ....... %rs1
58
@@ -XXX,XX +XXX,XX @@
59
@th_bfext msb:6 lsb:6 ..... ... ..... ....... &th_bfext %rs1 %rd
60
@sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd
61
@sh6 ...... ...... ..... ... ..... ....... &shift shamt=%sh6 %rs1 %rd
62
+@th_pair ..... .. ..... ..... ... ..... ....... &th_pair %rd1 %rs %rd2 %sh2
63
64
# XTheadBa
65
# Instead of defining a new encoding, we simply use the decoder to
66
@@ -XXX,XX +XXX,XX @@ th_muls 00100 01 ..... ..... 001 ..... 0001011 @r
67
th_mulsh 00101 01 ..... ..... 001 ..... 0001011 @r
68
th_mulsw 00100 11 ..... ..... 001 ..... 0001011 @r
69
70
+# XTheadMemPair
71
+th_ldd 11111 .. ..... ..... 100 ..... 0001011 @th_pair
72
+th_lwd 11100 .. ..... ..... 100 ..... 0001011 @th_pair
73
+th_lwud 11110 .. ..... ..... 100 ..... 0001011 @th_pair
74
+th_sdd 11111 .. ..... ..... 101 ..... 0001011 @th_pair
75
+th_swd 11100 .. ..... ..... 101 ..... 0001011 @th_pair
76
+
77
# XTheadSync
78
th_sfence_vmas 0000010 ..... ..... 000 00000 0001011 @rs2_s
79
th_sync 0000000 11000 00000 000 00000 0001011
80
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
31
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
81
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
82
--- a/target/riscv/cpu.c
33
--- a/target/riscv/cpu.c
83
+++ b/target/riscv/cpu.c
34
+++ b/target/riscv/cpu.c
84
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
35
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize_tcg(DeviceState *dev, Error **errp)
85
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
36
CPURISCVState *env = &cpu->env;
86
ISA_EXT_DATA_ENTRY(xtheadcondmov, true, PRIV_VERSION_1_11_0, ext_xtheadcondmov),
37
Error *local_err = NULL;
87
ISA_EXT_DATA_ENTRY(xtheadmac, true, PRIV_VERSION_1_11_0, ext_xtheadmac),
38
88
+ ISA_EXT_DATA_ENTRY(xtheadmempair, true, PRIV_VERSION_1_11_0, ext_xtheadmempair),
39
+ if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_CPU_HOST)) {
89
ISA_EXT_DATA_ENTRY(xtheadsync, true, PRIV_VERSION_1_11_0, ext_xtheadsync),
40
+ error_setg(errp, "'host' CPU is not compatible with TCG acceleration");
90
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
41
+ return;
91
};
92
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
93
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
94
DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
95
DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false),
96
+ DEFINE_PROP_BOOL("xtheadmempair", RISCVCPU, cfg.ext_xtheadmempair, false),
97
DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
98
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
99
100
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/riscv/translate.c
103
+++ b/target/riscv/translate.c
104
@@ -XXX,XX +XXX,XX @@ static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
105
return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
106
ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
107
ctx->cfg_ptr->ext_xtheadcondmov || ctx->cfg_ptr->ext_xtheadmac ||
108
- ctx->cfg_ptr->ext_xtheadsync;
109
+ ctx->cfg_ptr->ext_xtheadmempair || ctx->cfg_ptr->ext_xtheadsync;
110
}
111
112
#define MATERIALISE_EXT_PREDICATE(ext) \
113
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/riscv/insn_trans/trans_xthead.c.inc
116
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
117
@@ -XXX,XX +XXX,XX @@
118
} \
119
} while (0)
120
121
+#define REQUIRE_XTHEADMEMPAIR(ctx) do { \
122
+ if (!ctx->cfg_ptr->ext_xtheadmempair) { \
123
+ return false; \
124
+ } \
125
+} while (0)
126
+
127
#define REQUIRE_XTHEADSYNC(ctx) do { \
128
if (!ctx->cfg_ptr->ext_xtheadsync) { \
129
return false; \
130
@@ -XXX,XX +XXX,XX @@ static bool trans_th_mulsw(DisasContext *ctx, arg_th_mulsw *a)
131
return gen_th_mac(ctx, a, tcg_gen_sub_tl, NULL);
132
}
133
134
+/* XTheadMemPair */
135
+
136
+static bool gen_loadpair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop,
137
+ int shamt)
138
+{
139
+ if (a->rs == a->rd1 || a->rs == a->rd2 || a->rd1 == a->rd2) {
140
+ return false;
141
+ }
42
+ }
142
+
43
+
143
+ TCGv t1 = tcg_temp_new();
44
riscv_cpu_validate_misa_mxl(cpu, &local_err);
144
+ TCGv t2 = tcg_temp_new();
45
if (local_err != NULL) {
145
+ TCGv addr1 = tcg_temp_new();
46
error_propagate(errp, local_err);
146
+ TCGv addr2 = tcg_temp_new();
147
+ int imm = a->sh2 << shamt;
148
+
149
+ addr1 = get_address(ctx, a->rs, imm);
150
+ addr2 = get_address(ctx, a->rs, memop_size(memop) + imm);
151
+
152
+ tcg_gen_qemu_ld_tl(t1, addr1, ctx->mem_idx, memop);
153
+ tcg_gen_qemu_ld_tl(t2, addr2, ctx->mem_idx, memop);
154
+ gen_set_gpr(ctx, a->rd1, t1);
155
+ gen_set_gpr(ctx, a->rd2, t2);
156
+
157
+ tcg_temp_free(t1);
158
+ tcg_temp_free(t2);
159
+ tcg_temp_free(addr1);
160
+ tcg_temp_free(addr2);
161
+ return true;
162
+}
163
+
164
+static bool trans_th_ldd(DisasContext *ctx, arg_th_pair *a)
165
+{
166
+ REQUIRE_XTHEADMEMPAIR(ctx);
167
+ REQUIRE_64BIT(ctx);
168
+ return gen_loadpair_tl(ctx, a, MO_TESQ, 4);
169
+}
170
+
171
+static bool trans_th_lwd(DisasContext *ctx, arg_th_pair *a)
172
+{
173
+ REQUIRE_XTHEADMEMPAIR(ctx);
174
+ return gen_loadpair_tl(ctx, a, MO_TESL, 3);
175
+}
176
+
177
+static bool trans_th_lwud(DisasContext *ctx, arg_th_pair *a)
178
+{
179
+ REQUIRE_XTHEADMEMPAIR(ctx);
180
+ return gen_loadpair_tl(ctx, a, MO_TEUL, 3);
181
+}
182
+
183
+static bool gen_storepair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop,
184
+ int shamt)
185
+{
186
+ if (a->rs == a->rd1 || a->rs == a->rd2 || a->rd1 == a->rd2) {
187
+ return false;
188
+ }
189
+
190
+ TCGv data1 = get_gpr(ctx, a->rd1, EXT_NONE);
191
+ TCGv data2 = get_gpr(ctx, a->rd2, EXT_NONE);
192
+ TCGv addr1 = tcg_temp_new();
193
+ TCGv addr2 = tcg_temp_new();
194
+ int imm = a->sh2 << shamt;
195
+
196
+ addr1 = get_address(ctx, a->rs, imm);
197
+ addr2 = get_address(ctx, a->rs, memop_size(memop) + imm);
198
+
199
+ tcg_gen_qemu_st_tl(data1, addr1, ctx->mem_idx, memop);
200
+ tcg_gen_qemu_st_tl(data2, addr2, ctx->mem_idx, memop);
201
+
202
+ tcg_temp_free(addr1);
203
+ tcg_temp_free(addr2);
204
+ return true;
205
+}
206
+
207
+static bool trans_th_sdd(DisasContext *ctx, arg_th_pair *a)
208
+{
209
+ REQUIRE_XTHEADMEMPAIR(ctx);
210
+ REQUIRE_64BIT(ctx);
211
+ return gen_storepair_tl(ctx, a, MO_TESQ, 4);
212
+}
213
+
214
+static bool trans_th_swd(DisasContext *ctx, arg_th_pair *a)
215
+{
216
+ REQUIRE_XTHEADMEMPAIR(ctx);
217
+ return gen_storepair_tl(ctx, a, MO_TESL, 3);
218
+}
219
+
220
/* XTheadSync */
221
222
static bool trans_th_sfence_vmas(DisasContext *ctx, arg_th_sfence_vmas *a)
223
--
47
--
224
2.39.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
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
This patch adds support for the XTheadFmv ISA extension.
3
zmmul was promoted from experimental to ratified in commit 6d00ffad4e95.
4
The patch uses the T-Head specific decoder and translation.
4
Add a riscv,isa string for it.
5
5
6
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
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>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
10
Message-Id: <20230720132424.371132-2-dbarboza@ventanamicro.com>
9
Message-Id: <20230131202013.2541053-14-christoph.muellner@vrull.eu>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
---
12
target/riscv/cpu.h | 1 +
13
target/riscv/cpu.c | 1 +
13
target/riscv/xthead.decode | 4 ++
14
1 file changed, 1 insertion(+)
14
target/riscv/cpu.c | 2 +
15
target/riscv/translate.c | 6 +--
16
target/riscv/insn_trans/trans_xthead.c.inc | 45 ++++++++++++++++++++++
17
5 files changed, 55 insertions(+), 3 deletions(-)
18
15
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.h
22
+++ b/target/riscv/cpu.h
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
24
bool ext_xtheadcmo;
25
bool ext_xtheadcondmov;
26
bool ext_xtheadfmemidx;
27
+ bool ext_xtheadfmv;
28
bool ext_xtheadmac;
29
bool ext_xtheadmemidx;
30
bool ext_xtheadmempair;
31
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/xthead.decode
34
+++ b/target/riscv/xthead.decode
35
@@ -XXX,XX +XXX,XX @@ th_fsrw 01000 .. ..... ..... 111 ..... 0001011 @th_memidx
36
th_fsurd 01110 .. ..... ..... 111 ..... 0001011 @th_memidx
37
th_fsurw 01010 .. ..... ..... 111 ..... 0001011 @th_memidx
38
39
+# XTheadFmv
40
+th_fmv_hw_x 1010000 00000 ..... 001 ..... 0001011 @r2
41
+th_fmv_x_hw 1100000 00000 ..... 001 ..... 0001011 @r2
42
+
43
# XTheadMac
44
th_mula 00100 00 ..... ..... 001 ..... 0001011 @r
45
th_mulah 00101 00 ..... ..... 001 ..... 0001011 @r
46
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
16
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
47
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/cpu.c
18
--- a/target/riscv/cpu.c
49
+++ b/target/riscv/cpu.c
19
+++ b/target/riscv/cpu.c
50
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
20
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
51
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
21
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
52
ISA_EXT_DATA_ENTRY(xtheadcondmov, true, PRIV_VERSION_1_11_0, ext_xtheadcondmov),
22
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
53
ISA_EXT_DATA_ENTRY(xtheadfmemidx, true, PRIV_VERSION_1_11_0, ext_xtheadfmemidx),
23
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
54
+ ISA_EXT_DATA_ENTRY(xtheadfmv, true, PRIV_VERSION_1_11_0, ext_xtheadfmv),
24
+ ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
55
ISA_EXT_DATA_ENTRY(xtheadmac, true, PRIV_VERSION_1_11_0, ext_xtheadmac),
25
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
56
ISA_EXT_DATA_ENTRY(xtheadmemidx, true, PRIV_VERSION_1_11_0, ext_xtheadmemidx),
26
ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
57
ISA_EXT_DATA_ENTRY(xtheadmempair, true, PRIV_VERSION_1_11_0, ext_xtheadmempair),
27
ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
58
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
59
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
60
DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
61
DEFINE_PROP_BOOL("xtheadfmemidx", RISCVCPU, cfg.ext_xtheadfmemidx, false),
62
+ DEFINE_PROP_BOOL("xtheadfmv", RISCVCPU, cfg.ext_xtheadfmv, false),
63
DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false),
64
DEFINE_PROP_BOOL("xtheadmemidx", RISCVCPU, cfg.ext_xtheadmemidx, false),
65
DEFINE_PROP_BOOL("xtheadmempair", RISCVCPU, cfg.ext_xtheadmempair, false),
66
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/translate.c
69
+++ b/target/riscv/translate.c
70
@@ -XXX,XX +XXX,XX @@ static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
71
return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
72
ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
73
ctx->cfg_ptr->ext_xtheadcondmov ||
74
- ctx->cfg_ptr->ext_xtheadfmemidx || ctx->cfg_ptr->ext_xtheadmac ||
75
- ctx->cfg_ptr->ext_xtheadmemidx || ctx->cfg_ptr->ext_xtheadmempair ||
76
- ctx->cfg_ptr->ext_xtheadsync;
77
+ ctx->cfg_ptr->ext_xtheadfmemidx || ctx->cfg_ptr->ext_xtheadfmv ||
78
+ ctx->cfg_ptr->ext_xtheadmac || ctx->cfg_ptr->ext_xtheadmemidx ||
79
+ ctx->cfg_ptr->ext_xtheadmempair || ctx->cfg_ptr->ext_xtheadsync;
80
}
81
82
#define MATERIALISE_EXT_PREDICATE(ext) \
83
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
84
index XXXXXXX..XXXXXXX 100644
85
--- a/target/riscv/insn_trans/trans_xthead.c.inc
86
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
87
@@ -XXX,XX +XXX,XX @@
88
} \
89
} while (0)
90
91
+#define REQUIRE_XTHEADFMV(ctx) do { \
92
+ if (!ctx->cfg_ptr->ext_xtheadfmv) { \
93
+ return false; \
94
+ } \
95
+} while (0)
96
+
97
#define REQUIRE_XTHEADMAC(ctx) do { \
98
if (!ctx->cfg_ptr->ext_xtheadmac) { \
99
return false; \
100
@@ -XXX,XX +XXX,XX @@ static bool trans_th_fsurw(DisasContext *ctx, arg_th_memidx *a)
101
return gen_fstore_idx(ctx, a, MO_TEUL, true);
102
}
103
104
+/* XTheadFmv */
105
+
106
+static bool trans_th_fmv_hw_x(DisasContext *ctx, arg_th_fmv_hw_x *a)
107
+{
108
+ REQUIRE_XTHEADFMV(ctx);
109
+ REQUIRE_32BIT(ctx);
110
+ REQUIRE_FPU;
111
+ REQUIRE_EXT(ctx, RVD);
112
+
113
+ TCGv src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
114
+ TCGv_i64 t1 = tcg_temp_new_i64();
115
+
116
+ tcg_gen_extu_tl_i64(t1, src1);
117
+ tcg_gen_deposit_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], t1, 32, 32);
118
+ tcg_temp_free_i64(t1);
119
+ mark_fs_dirty(ctx);
120
+ return true;
121
+}
122
+
123
+static bool trans_th_fmv_x_hw(DisasContext *ctx, arg_th_fmv_x_hw *a)
124
+{
125
+ REQUIRE_XTHEADFMV(ctx);
126
+ REQUIRE_32BIT(ctx);
127
+ REQUIRE_FPU;
128
+ REQUIRE_EXT(ctx, RVD);
129
+ TCGv dst;
130
+ TCGv_i64 t1;
131
+
132
+ dst = dest_gpr(ctx, a->rd);
133
+ t1 = tcg_temp_new_i64();
134
+
135
+ tcg_gen_extract_i64(t1, cpu_fpr[a->rs1], 32, 32);
136
+ tcg_gen_trunc_i64_tl(dst, t1);
137
+ gen_set_gpr(ctx, a->rd, dst);
138
+ tcg_temp_free_i64(t1);
139
+ mark_fs_dirty(ctx);
140
+ return true;
141
+}
142
+
143
/* XTheadMac */
144
145
static bool gen_th_mac(DisasContext *ctx, arg_r *a,
146
--
28
--
147
2.39.1
29
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
fdt_pack() can change the fdt size, meaning that fdt_totalsize() can
3
The cpu->cfg.epmp extension is still experimental, but it already has a
4
contain a now deprecated (bigger) value.
4
'smepmp' riscv,isa string. Add it.
5
5
6
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Message-Id: <20230720132424.371132-3-dbarboza@ventanamicro.com>
8
Message-Id: <20230201171212.1219375-2-dbarboza@ventanamicro.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
---
11
hw/riscv/boot.c | 10 ++++++----
12
target/riscv/cpu.c | 1 +
12
1 file changed, 6 insertions(+), 4 deletions(-)
13
1 file changed, 1 insertion(+)
13
14
14
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
15
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/boot.c
17
--- a/target/riscv/cpu.c
17
+++ b/hw/riscv/boot.c
18
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
19
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
19
{
20
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
20
uint64_t temp, fdt_addr;
21
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
21
hwaddr dram_end = dram_base + mem_size;
22
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
22
- int ret, fdtsize = fdt_totalsize(fdt);
23
+ ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, epmp),
23
+ int ret = fdt_pack(fdt);
24
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
24
+ int fdtsize;
25
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
25
26
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
26
+ /* Should only fail if we've built a corrupted tree */
27
+ g_assert(ret == 0);
28
+
29
+ fdtsize = fdt_totalsize(fdt);
30
if (fdtsize <= 0) {
31
error_report("invalid device-tree");
32
exit(1);
33
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
34
temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end;
35
fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB);
36
37
- ret = fdt_pack(fdt);
38
- /* Should only fail if we've built a corrupted tree */
39
- g_assert(ret == 0);
40
/* copy in the device tree */
41
qemu_fdt_dumpdtb(fdt, fdtsize);
42
43
--
27
--
44
2.39.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: Sergey Matyukevich <sergey.matyukevich@syntacore.com>
1
From: Ard Biesheuvel <ardb@kernel.org>
2
2
3
According to privileged spec, if [sm]tval is written with a nonzero
3
The AES MixColumns and InvMixColumns operations are relatively
4
value when a breakpoint exception occurs, then [sm]tval will contain
4
expensive 4x4 matrix multiplications in GF(2^8), which is why C
5
the faulting virtual address. Set tval to hit address when breakpoint
5
implementations usually rely on precomputed lookup tables rather than
6
exception is triggered by hardware watchpoint.
6
performing the calculations on demand.
7
7
8
Signed-off-by: Sergey Matyukevich <sergey.matyukevich@syntacore.com>
8
Given that we already carry those tables in QEMU, we can just grab the
9
Reviewed-by: Bin Meng <bmeng@tinylab.org>
9
right value in the implementation of the RISC-V AES32 instructions. Note
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
that the tables in question are permuted according to the respective
11
Message-Id: <20230131170955.752743-1-geomatsi@gmail.com>
11
Sbox, so we can omit the Sbox lookup as well in this case.
12
13
Cc: Richard Henderson <richard.henderson@linaro.org>
14
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Cc: Zewen Ye <lustrew@foxmail.com>
16
Cc: Weiwei Li <liweiwei@iscas.ac.cn>
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>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
22
---
14
target/riscv/cpu_helper.c | 6 ++++++
23
include/crypto/aes.h | 7 +++++++
15
target/riscv/debug.c | 1 -
24
crypto/aes.c | 4 ++--
16
2 files changed, 6 insertions(+), 1 deletion(-)
25
target/riscv/crypto_helper.c | 34 ++++------------------------------
26
3 files changed, 13 insertions(+), 32 deletions(-)
17
27
18
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
19
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/cpu_helper.c
30
--- a/include/crypto/aes.h
21
+++ b/target/riscv/cpu_helper.c
31
+++ b/include/crypto/aes.h
22
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
32
@@ -XXX,XX +XXX,XX @@ void AES_decrypt(const unsigned char *in, unsigned char *out,
23
case RISCV_EXCP_VIRT_INSTRUCTION_FAULT:
33
extern const uint8_t AES_sbox[256];
24
tval = env->bins;
34
extern const uint8_t AES_isbox[256];
25
break;
35
26
+ case RISCV_EXCP_BREAKPOINT:
36
+/*
27
+ if (cs->watchpoint_hit) {
37
+AES_Te0[x] = S [x].[02, 01, 01, 03];
28
+ tval = cs->watchpoint_hit->hitaddr;
38
+AES_Td0[x] = Si[x].[0e, 09, 0d, 0b];
29
+ cs->watchpoint_hit = NULL;
39
+*/
30
+ }
40
+
31
+ break;
41
+extern const uint32_t AES_Te0[256], AES_Td0[256];
32
default:
42
+
33
break;
43
#endif
34
}
44
diff --git a/crypto/aes.c b/crypto/aes.c
35
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
36
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/debug.c
46
--- a/crypto/aes.c
38
+++ b/target/riscv/debug.c
47
+++ b/crypto/aes.c
39
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_debug_excp_handler(CPUState *cs)
48
@@ -XXX,XX +XXX,XX @@ AES_Td3[x] = Si[x].[09, 0d, 0b, 0e];
40
49
AES_Td4[x] = Si[x].[01, 01, 01, 01];
41
if (cs->watchpoint_hit) {
50
*/
42
if (cs->watchpoint_hit->flags & BP_CPU) {
51
43
- cs->watchpoint_hit = NULL;
52
-static const uint32_t AES_Te0[256] = {
44
do_trigger_action(env, DBG_ACTION_BP);
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))
76
-
77
-#define AES_GFMUL(a, b) (( \
78
- (((b) & 0x1) ? (a) : 0) ^ \
79
- (((b) & 0x2) ? AES_XTIME(a) : 0) ^ \
80
- (((b) & 0x4) ? AES_XTIME(AES_XTIME(a)) : 0) ^ \
81
- (((b) & 0x8) ? AES_XTIME(AES_XTIME(AES_XTIME(a))) : 0)) & 0xFF)
82
-
83
-static inline uint32_t aes_mixcolumn_byte(uint8_t x, bool fwd)
84
-{
85
- uint32_t u;
86
-
87
- if (fwd) {
88
- u = (AES_GFMUL(x, 3) << 24) | (x << 16) | (x << 8) |
89
- (AES_GFMUL(x, 2) << 0);
90
- } else {
91
- u = (AES_GFMUL(x, 0xb) << 24) | (AES_GFMUL(x, 0xd) << 16) |
92
- (AES_GFMUL(x, 0x9) << 8) | (AES_GFMUL(x, 0xe) << 0);
93
- }
94
- return u;
95
-}
96
-
97
#define sext32_xlen(x) (target_ulong)(int32_t)(x)
98
99
static inline target_ulong aes32_operation(target_ulong shamt,
100
@@ -XXX,XX +XXX,XX @@ static inline target_ulong aes32_operation(target_ulong shamt,
101
bool enc, bool mix)
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];
45
}
116
}
46
} 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);
47
--
128
--
48
2.39.1
129
2.41.0
130
131
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
This patch adds support for the XTheadCmo ISA extension.
3
Take some functions/macros out of `vector_helper` and put them in a new
4
To avoid interfering with standard extensions, decoder and translation
4
module called `vector_internals`. This ensures they can be used by both
5
are in its own xthead* specific files.
5
vector and vector-crypto helpers (latter implemented in proceeding
6
Future patches should be able to easily add additional T-Head extension.
6
commits).
7
7
8
The implementation does not have much functionality (besides accepting
8
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
9
the instructions and not qualifying them as illegal instructions if
9
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
10
the hart executes in the required privilege level for the instruction),
10
Signed-off-by: Max Chou <max.chou@sifive.com>
11
as QEMU does not model CPU caches and instructions are documented
11
Acked-by: Alistair Francis <alistair.francis@wdc.com>
12
to not raise any exceptions.
12
Message-ID: <20230711165917.2629866-2-max.chou@sifive.com>
13
14
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
15
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-Id: <20230131202013.2541053-2-christoph.muellner@vrull.eu>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
14
---
20
target/riscv/cpu.h | 1 +
15
target/riscv/vector_internals.h | 182 +++++++++++++++++++++++++++++
21
target/riscv/xthead.decode | 38 ++++++++++
16
target/riscv/vector_helper.c | 201 +-------------------------------
22
target/riscv/cpu.c | 2 +
17
target/riscv/vector_internals.c | 81 +++++++++++++
23
target/riscv/translate.c | 8 +++
18
target/riscv/meson.build | 1 +
24
target/riscv/insn_trans/trans_xthead.c.inc | 81 ++++++++++++++++++++++
19
4 files changed, 265 insertions(+), 200 deletions(-)
25
target/riscv/meson.build | 1 +
20
create mode 100644 target/riscv/vector_internals.h
26
6 files changed, 131 insertions(+)
21
create mode 100644 target/riscv/vector_internals.c
27
create mode 100644 target/riscv/xthead.decode
28
create mode 100644 target/riscv/insn_trans/trans_xthead.c.inc
29
22
30
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
23
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/riscv/cpu.h
33
+++ b/target/riscv/cpu.h
34
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
35
uint64_t mimpid;
36
37
/* Vendor-specific custom extensions */
38
+ bool ext_xtheadcmo;
39
bool ext_XVentanaCondOps;
40
41
uint8_t pmu_num;
42
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
43
new file mode 100644
24
new file mode 100644
44
index XXXXXXX..XXXXXXX
25
index XXXXXXX..XXXXXXX
45
--- /dev/null
26
--- /dev/null
46
+++ b/target/riscv/xthead.decode
27
+++ b/target/riscv/vector_internals.h
47
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
48
+#
29
+/*
49
+# Translation routines for the instructions of the XThead* ISA extensions
30
+ * RISC-V Vector Extension Internals
50
+#
31
+ *
51
+# Copyright (c) 2022 Christoph Muellner, christoph.muellner@vrull.eu
32
+ * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
52
+#
53
+# SPDX-License-Identifier: LGPL-2.1-or-later
54
+#
55
+# The documentation of the ISA extensions can be found here:
56
+# https://github.com/T-head-Semi/thead-extension-spec/releases/latest
57
+
58
+# Fields:
59
+%rs1 15:5
60
+
61
+# Formats
62
+@sfence_vm ....... ..... ..... ... ..... ....... %rs1
63
+
64
+# XTheadCmo
65
+th_dcache_call 0000000 00001 00000 000 00000 0001011
66
+th_dcache_ciall 0000000 00011 00000 000 00000 0001011
67
+th_dcache_iall 0000000 00010 00000 000 00000 0001011
68
+th_dcache_cpa 0000001 01001 ..... 000 00000 0001011 @sfence_vm
69
+th_dcache_cipa 0000001 01011 ..... 000 00000 0001011 @sfence_vm
70
+th_dcache_ipa 0000001 01010 ..... 000 00000 0001011 @sfence_vm
71
+th_dcache_cva 0000001 00101 ..... 000 00000 0001011 @sfence_vm
72
+th_dcache_civa 0000001 00111 ..... 000 00000 0001011 @sfence_vm
73
+th_dcache_iva 0000001 00110 ..... 000 00000 0001011 @sfence_vm
74
+th_dcache_csw 0000001 00001 ..... 000 00000 0001011 @sfence_vm
75
+th_dcache_cisw 0000001 00011 ..... 000 00000 0001011 @sfence_vm
76
+th_dcache_isw 0000001 00010 ..... 000 00000 0001011 @sfence_vm
77
+th_dcache_cpal1 0000001 01000 ..... 000 00000 0001011 @sfence_vm
78
+th_dcache_cval1 0000001 00100 ..... 000 00000 0001011 @sfence_vm
79
+th_icache_iall 0000000 10000 00000 000 00000 0001011
80
+th_icache_ialls 0000000 10001 00000 000 00000 0001011
81
+th_icache_ipa 0000001 11000 ..... 000 00000 0001011 @sfence_vm
82
+th_icache_iva 0000001 10000 ..... 000 00000 0001011 @sfence_vm
83
+th_l2cache_call 0000000 10101 00000 000 00000 0001011
84
+th_l2cache_ciall 0000000 10111 00000 000 00000 0001011
85
+th_l2cache_iall 0000000 10110 00000 000 00000 0001011
86
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/riscv/cpu.c
89
+++ b/target/riscv/cpu.c
90
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
91
ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
92
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
93
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
94
+ ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
95
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
96
};
97
98
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
99
DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false),
100
101
/* Vendor-specific custom extensions */
102
+ DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
103
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
104
105
/* These are experimental so mark with 'x-' */
106
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/riscv/translate.c
109
+++ b/target/riscv/translate.c
110
@@ -XXX,XX +XXX,XX @@ static bool always_true_p(DisasContext *ctx __attribute__((__unused__)))
111
return true;
112
}
113
114
+static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
115
+{
116
+ return ctx->cfg_ptr->ext_xtheadcmo;
117
+}
118
+
119
#define MATERIALISE_EXT_PREDICATE(ext) \
120
static bool has_ ## ext ## _p(DisasContext *ctx) \
121
{ \
122
@@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
123
#include "insn_trans/trans_rvk.c.inc"
124
#include "insn_trans/trans_privileged.c.inc"
125
#include "insn_trans/trans_svinval.c.inc"
126
+#include "decode-xthead.c.inc"
127
+#include "insn_trans/trans_xthead.c.inc"
128
#include "insn_trans/trans_xventanacondops.c.inc"
129
130
/* Include the auto-generated decoder for 16 bit insn */
131
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
132
bool (*decode_func)(DisasContext *, uint32_t);
133
} decoders[] = {
134
{ always_true_p, decode_insn32 },
135
+ { has_xthead_p, decode_xthead },
136
{ has_XVentanaCondOps_p, decode_XVentanaCodeOps },
137
};
138
139
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
140
new file mode 100644
141
index XXXXXXX..XXXXXXX
142
--- /dev/null
143
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
144
@@ -XXX,XX +XXX,XX @@
145
+/*
146
+ * RISC-V translation routines for the T-Head vendor extensions (xthead*).
147
+ *
148
+ * Copyright (c) 2022 VRULL GmbH.
149
+ *
33
+ *
150
+ * This program is free software; you can redistribute it and/or modify it
34
+ * This program is free software; you can redistribute it and/or modify it
151
+ * under the terms and conditions of the GNU General Public License,
35
+ * under the terms and conditions of the GNU General Public License,
152
+ * version 2 or later, as published by the Free Software Foundation.
36
+ * version 2 or later, as published by the Free Software Foundation.
153
+ *
37
+ *
...
...
158
+ *
42
+ *
159
+ * You should have received a copy of the GNU General Public License along with
43
+ * You should have received a copy of the GNU General Public License along with
160
+ * this program. If not, see <http://www.gnu.org/licenses/>.
44
+ * this program. If not, see <http://www.gnu.org/licenses/>.
161
+ */
45
+ */
162
+
46
+
163
+#define REQUIRE_XTHEADCMO(ctx) do { \
47
+#ifndef TARGET_RISCV_VECTOR_INTERNALS_H
164
+ if (!ctx->cfg_ptr->ext_xtheadcmo) { \
48
+#define TARGET_RISCV_VECTOR_INTERNALS_H
165
+ return false; \
49
+
166
+ } \
50
+#include "qemu/osdep.h"
167
+} while (0)
51
+#include "qemu/bitops.h"
168
+
52
+#include "cpu.h"
169
+/* XTheadCmo */
53
+#include "tcg/tcg-gvec-desc.h"
170
+
54
+#include "internals.h"
171
+static inline int priv_level(DisasContext *ctx)
55
+
172
+{
56
+static inline uint32_t vext_nf(uint32_t desc)
173
+#ifdef CONFIG_USER_ONLY
57
+{
174
+ return PRV_U;
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))
175
+#else
72
+#else
176
+ /* Priv level is part of mem_idx. */
73
+#define H1(x) (x)
177
+ return ctx->mem_idx & TB_FLAGS_PRIV_MMU_MASK;
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)
178
+#endif
79
+#endif
179
+}
80
+
180
+
81
+/*
181
+/* Test if priv level is M, S, or U (cannot fail). */
82
+ * Encode LMUL to lmul as following:
182
+#define REQUIRE_PRIV_MSU(ctx)
83
+ * LMUL vlmul lmul
183
+
84
+ * 1 000 0
184
+/* Test if priv level is M or S. */
85
+ * 2 001 1
185
+#define REQUIRE_PRIV_MS(ctx) \
86
+ * 4 010 2
186
+do { \
87
+ * 8 011 3
187
+ int priv = priv_level(ctx); \
88
+ * - 100 -
188
+ if (!(priv == PRV_M || \
89
+ * 1/8 101 -3
189
+ priv == PRV_S)) { \
90
+ * 1/4 110 -2
190
+ return false; \
91
+ * 1/2 111 -1
191
+ } \
92
+ */
192
+} while (0)
93
+static inline int32_t vext_lmul(uint32_t desc)
193
+
94
+{
194
+#define NOP_PRIVCHECK(insn, extcheck, privcheck) \
95
+ return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3);
195
+static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn * a) \
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) \
196
+{ \
163
+{ \
197
+ (void) a; \
164
+ TX1 s1 = *((T1 *)vs1 + HS1(i)); \
198
+ extcheck(ctx); \
165
+ TX2 s2 = *((T2 *)vs2 + HS2(i)); \
199
+ privcheck(ctx); \
166
+ *((TD *)vd + HD(i)) = OP(s2, s1); \
200
+ return true; \
167
+}
201
+}
168
+
202
+
169
+void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
203
+NOP_PRIVCHECK(th_dcache_call, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
170
+ CPURISCVState *env, uint32_t desc,
204
+NOP_PRIVCHECK(th_dcache_ciall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
171
+ opivv2_fn *fn, uint32_t esz);
205
+NOP_PRIVCHECK(th_dcache_iall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
172
+
206
+NOP_PRIVCHECK(th_dcache_cpa, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
173
+/* generate the helpers for OPIVV */
207
+NOP_PRIVCHECK(th_dcache_cipa, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
174
+#define GEN_VEXT_VV(NAME, ESZ) \
208
+NOP_PRIVCHECK(th_dcache_ipa, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
175
+void HELPER(NAME)(void *vd, void *v0, void *vs1, \
209
+NOP_PRIVCHECK(th_dcache_cva, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU)
176
+ void *vs2, CPURISCVState *env, \
210
+NOP_PRIVCHECK(th_dcache_civa, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU)
177
+ uint32_t desc) \
211
+NOP_PRIVCHECK(th_dcache_iva, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU)
178
+{ \
212
+NOP_PRIVCHECK(th_dcache_csw, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
179
+ do_vext_vv(vd, v0, vs1, vs2, env, desc, \
213
+NOP_PRIVCHECK(th_dcache_cisw, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
180
+ do_##NAME, ESZ); \
214
+NOP_PRIVCHECK(th_dcache_isw, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
181
+}
215
+NOP_PRIVCHECK(th_dcache_cpal1, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
182
+
216
+NOP_PRIVCHECK(th_dcache_cval1, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
183
+typedef void opivx2_fn(void *vd, target_long s1, void *vs2, int i);
217
+
184
+
218
+NOP_PRIVCHECK(th_icache_iall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
185
+/*
219
+NOP_PRIVCHECK(th_icache_ialls, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
186
+ * (T1)s1 gives the real operator type.
220
+NOP_PRIVCHECK(th_icache_ipa, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
187
+ * (TX1)(T1)s1 expands the operator type of widen or narrow operations.
221
+NOP_PRIVCHECK(th_icache_iva, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU)
188
+ */
222
+
189
+#define OPIVX2(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \
223
+NOP_PRIVCHECK(th_l2cache_call, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
190
+static void do_##NAME(void *vd, target_long s1, void *vs2, int i) \
224
+NOP_PRIVCHECK(th_l2cache_ciall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
191
+{ \
225
+NOP_PRIVCHECK(th_l2cache_iall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
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
212
index XXXXXXX..XXXXXXX 100644
213
--- a/target/riscv/vector_helper.c
214
+++ b/target/riscv/vector_helper.c
215
@@ -XXX,XX +XXX,XX @@
216
#include "fpu/softfloat.h"
217
#include "tcg/tcg-gvec-desc.h"
218
#include "internals.h"
219
+#include "vector_internals.h"
220
#include <math.h>
221
222
target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
223
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
224
return vl;
225
}
226
227
-/*
228
- * Note that vector data is stored in host-endian 64-bit chunks,
229
- * so addressing units smaller than that needs a host-endian fixup.
230
- */
231
-#if HOST_BIG_ENDIAN
232
-#define H1(x) ((x) ^ 7)
233
-#define H1_2(x) ((x) ^ 6)
234
-#define H1_4(x) ((x) ^ 4)
235
-#define H2(x) ((x) ^ 3)
236
-#define H4(x) ((x) ^ 1)
237
-#define H8(x) ((x))
238
-#else
239
-#define H1(x) (x)
240
-#define H1_2(x) (x)
241
-#define H1_4(x) (x)
242
-#define H2(x) (x)
243
-#define H4(x) (x)
244
-#define H8(x) (x)
245
-#endif
246
-
247
-static inline uint32_t vext_nf(uint32_t desc)
248
-{
249
- return FIELD_EX32(simd_data(desc), VDATA, NF);
250
-}
251
-
252
-static inline uint32_t vext_vm(uint32_t desc)
253
-{
254
- return FIELD_EX32(simd_data(desc), VDATA, VM);
255
-}
256
-
257
-/*
258
- * Encode LMUL to lmul as following:
259
- * LMUL vlmul lmul
260
- * 1 000 0
261
- * 2 001 1
262
- * 4 010 2
263
- * 8 011 3
264
- * - 100 -
265
- * 1/8 101 -3
266
- * 1/4 110 -2
267
- * 1/2 111 -1
268
- */
269
-static inline int32_t vext_lmul(uint32_t desc)
270
-{
271
- return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3);
272
-}
273
-
274
-static inline uint32_t vext_vta(uint32_t desc)
275
-{
276
- return FIELD_EX32(simd_data(desc), VDATA, VTA);
277
-}
278
-
279
-static inline uint32_t vext_vma(uint32_t desc)
280
-{
281
- return FIELD_EX32(simd_data(desc), VDATA, VMA);
282
-}
283
-
284
-static inline uint32_t vext_vta_all_1s(uint32_t desc)
285
-{
286
- return FIELD_EX32(simd_data(desc), VDATA, VTA_ALL_1S);
287
-}
288
-
289
/*
290
* Get the maximum number of elements can be operated.
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,
315
}
316
}
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
+}
226
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
578
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
227
index XXXXXXX..XXXXXXX 100644
579
index XXXXXXX..XXXXXXX 100644
228
--- a/target/riscv/meson.build
580
--- a/target/riscv/meson.build
229
+++ b/target/riscv/meson.build
581
+++ b/target/riscv/meson.build
230
@@ -XXX,XX +XXX,XX @@
582
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(files(
231
gen = [
583
'gdbstub.c',
232
decodetree.process('insn16.decode', extra_args: ['--static-decode=decode_insn16', '--insnwidth=16']),
584
'op_helper.c',
233
decodetree.process('insn32.decode', extra_args: '--static-decode=decode_insn32'),
585
'vector_helper.c',
234
+ decodetree.process('xthead.decode', extra_args: '--static-decode=decode_xthead'),
586
+ 'vector_internals.c',
235
decodetree.process('XVentanaCondOps.decode', extra_args: '--static-decode=decode_XVentanaCodeOps'),
587
'bitmanip_helper.c',
236
]
588
'translate.c',
237
589
'm128_helper.c',
238
--
590
--
239
2.39.1
591
2.41.0
diff view generated by jsdifflib
New patch
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
1
2
3
Refactor the non SEW-specific stuff out of `GEN_OPIVV_TRANS` into
4
function `opivv_trans` (similar to `opivi_trans`). `opivv_trans` will be
5
used in proceeding vector-crypto commits.
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>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
12
Message-ID: <20230711165917.2629866-3-max.chou@sifive.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/insn_trans/trans_rvv.c.inc | 62 +++++++++++++------------
16
1 file changed, 32 insertions(+), 30 deletions(-)
17
18
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/insn_trans/trans_rvv.c.inc
21
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
22
@@ -XXX,XX +XXX,XX @@ GEN_OPIWX_WIDEN_TRANS(vwadd_wx)
23
GEN_OPIWX_WIDEN_TRANS(vwsubu_wx)
24
GEN_OPIWX_WIDEN_TRANS(vwsub_wx)
25
26
+static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
27
+ gen_helper_gvec_4_ptr *fn, DisasContext *s)
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; \
90
}
91
92
/*
93
--
94
2.41.0
diff view generated by jsdifflib
New patch
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
1
2
3
Remove the redundant "vl == 0" check which is already included within the vstart >= vl check, when vl == 0.
4
5
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
6
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
7
Signed-off-by: Max Chou <max.chou@sifive.com>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20230711165917.2629866-4-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/insn_trans/trans_rvv.c.inc | 31 +------------------------
13
1 file changed, 1 insertion(+), 30 deletions(-)
14
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
20
TCGv_i32 desc;
21
22
TCGLabel *over = gen_new_label();
23
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
24
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
25
26
dest = tcg_temp_new_ptr();
27
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
28
TCGv_i32 desc;
29
30
TCGLabel *over = gen_new_label();
31
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
32
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
33
34
dest = tcg_temp_new_ptr();
35
@@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
36
TCGv_i32 desc;
37
38
TCGLabel *over = gen_new_label();
39
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
40
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
41
42
dest = tcg_temp_new_ptr();
43
@@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
44
TCGv_i32 desc;
45
46
TCGLabel *over = gen_new_label();
47
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
48
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
49
50
dest = tcg_temp_new_ptr();
51
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
52
return false;
53
}
54
55
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
56
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
57
58
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
59
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
60
uint32_t data = 0;
61
62
TCGLabel *over = gen_new_label();
63
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
64
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
65
66
dest = tcg_temp_new_ptr();
67
@@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
68
uint32_t data = 0;
69
70
TCGLabel *over = gen_new_label();
71
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
72
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
73
74
dest = tcg_temp_new_ptr();
75
@@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
76
if (checkfn(s, a)) {
77
uint32_t data = 0;
78
TCGLabel *over = gen_new_label();
79
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
80
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
81
82
data = FIELD_DP32(data, VDATA, VM, a->vm);
83
@@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
84
if (opiwv_widen_check(s, a)) {
85
uint32_t data = 0;
86
TCGLabel *over = gen_new_label();
87
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
88
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
89
90
data = FIELD_DP32(data, VDATA, VM, a->vm);
91
@@ -XXX,XX +XXX,XX @@ static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
92
{
93
uint32_t data = 0;
94
TCGLabel *over = gen_new_label();
95
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
96
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
97
98
data = FIELD_DP32(data, VDATA, VM, vm);
99
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
100
gen_helper_##NAME##_w, \
101
}; \
102
TCGLabel *over = gen_new_label(); \
103
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
104
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
105
\
106
data = FIELD_DP32(data, VDATA, VM, a->vm); \
107
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
108
gen_helper_vmv_v_v_w, gen_helper_vmv_v_v_d,
109
};
110
TCGLabel *over = gen_new_label();
111
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
112
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
113
114
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
115
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
116
vext_check_ss(s, a->rd, 0, 1)) {
117
TCGv s1;
118
TCGLabel *over = gen_new_label();
119
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
120
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
121
122
s1 = get_gpr(s, a->rs1, EXT_SIGN);
123
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
124
gen_helper_vmv_v_x_w, gen_helper_vmv_v_x_d,
125
};
126
TCGLabel *over = gen_new_label();
127
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
128
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
129
130
s1 = tcg_constant_i64(simm);
131
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
132
}; \
133
TCGLabel *over = gen_new_label(); \
134
gen_set_rm(s, RISCV_FRM_DYN); \
135
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
136
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
137
\
138
data = FIELD_DP32(data, VDATA, VM, a->vm); \
139
@@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
140
TCGv_i64 t1;
141
142
TCGLabel *over = gen_new_label();
143
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
144
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
145
146
dest = tcg_temp_new_ptr();
147
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
148
}; \
149
TCGLabel *over = gen_new_label(); \
150
gen_set_rm(s, RISCV_FRM_DYN); \
151
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
152
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);\
153
\
154
data = FIELD_DP32(data, VDATA, VM, a->vm); \
155
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
156
}; \
157
TCGLabel *over = gen_new_label(); \
158
gen_set_rm(s, RISCV_FRM_DYN); \
159
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
160
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
161
\
162
data = FIELD_DP32(data, VDATA, VM, a->vm); \
163
@@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
164
uint32_t data = 0;
165
TCGLabel *over = gen_new_label();
166
gen_set_rm_chkfrm(s, rm);
167
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
168
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
169
170
data = FIELD_DP32(data, VDATA, VM, a->vm);
171
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
172
gen_helper_vmv_v_x_d,
173
};
174
TCGLabel *over = gen_new_label();
175
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
176
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
177
178
t1 = tcg_temp_new_i64();
179
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
180
}; \
181
TCGLabel *over = gen_new_label(); \
182
gen_set_rm_chkfrm(s, FRM); \
183
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
184
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
185
\
186
data = FIELD_DP32(data, VDATA, VM, a->vm); \
187
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
188
}; \
189
TCGLabel *over = gen_new_label(); \
190
gen_set_rm(s, RISCV_FRM_DYN); \
191
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
192
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
193
\
194
data = FIELD_DP32(data, VDATA, VM, a->vm); \
195
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
196
}; \
197
TCGLabel *over = gen_new_label(); \
198
gen_set_rm_chkfrm(s, FRM); \
199
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
200
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
201
\
202
data = FIELD_DP32(data, VDATA, VM, a->vm); \
203
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
204
}; \
205
TCGLabel *over = gen_new_label(); \
206
gen_set_rm_chkfrm(s, FRM); \
207
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
208
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
209
\
210
data = FIELD_DP32(data, VDATA, VM, a->vm); \
211
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \
212
uint32_t data = 0; \
213
gen_helper_gvec_4_ptr *fn = gen_helper_##NAME; \
214
TCGLabel *over = gen_new_label(); \
215
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
216
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
217
\
218
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
219
@@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
220
require_vm(a->vm, a->rd)) {
221
uint32_t data = 0;
222
TCGLabel *over = gen_new_label();
223
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
224
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
225
226
data = FIELD_DP32(data, VDATA, VM, a->vm);
227
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
228
TCGv s1;
229
TCGLabel *over = gen_new_label();
230
231
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
232
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
233
234
t1 = tcg_temp_new_i64();
235
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
236
TCGv_i64 t1;
237
TCGLabel *over = gen_new_label();
238
239
- /* if vl == 0 or vstart >= vl, skip vector register write back */
240
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
241
+ /* if vstart >= vl, skip vector register write back */
242
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
243
244
/* NaN-box f[rs1] */
245
@@ -XXX,XX +XXX,XX @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
246
uint32_t data = 0;
247
gen_helper_gvec_3_ptr *fn;
248
TCGLabel *over = gen_new_label();
249
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
250
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
251
252
static gen_helper_gvec_3_ptr * const fns[6][4] = {
253
--
254
2.41.0
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
2
2
3
This patch adds support for the T-Head MAC instructions.
3
This commit adds support for the Zvbc vector-crypto extension, which
4
The patch uses the T-Head specific decoder and translation.
4
consists of the following instructions:
5
5
6
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
6
* vclmulh.[vx,vv]
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
* vclmul.[vx,vv]
8
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
8
9
Message-Id: <20230131202013.2541053-8-christoph.muellner@vrull.eu>
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: Max Chou <max.chou@sifive.com>
15
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
16
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
17
Signed-off-by: Max Chou <max.chou@sifive.com>
18
[max.chou@sifive.com: Exposed x-zvbc property]
19
Message-ID: <20230711165917.2629866-5-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
21
---
12
target/riscv/cpu.h | 1 +
22
target/riscv/cpu_cfg.h | 1 +
13
target/riscv/xthead.decode | 8 +++
23
target/riscv/helper.h | 6 +++
14
target/riscv/cpu.c | 2 +
24
target/riscv/insn32.decode | 6 +++
15
target/riscv/translate.c | 3 +-
25
target/riscv/cpu.c | 9 ++++
16
target/riscv/insn_trans/trans_xthead.c.inc | 83 ++++++++++++++++++++++
26
target/riscv/translate.c | 1 +
17
5 files changed, 96 insertions(+), 1 deletion(-)
27
target/riscv/vcrypto_helper.c | 59 ++++++++++++++++++++++
18
28
target/riscv/insn_trans/trans_rvvk.c.inc | 62 ++++++++++++++++++++++++
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
29
target/riscv/meson.build | 3 +-
20
index XXXXXXX..XXXXXXX 100644
30
8 files changed, 146 insertions(+), 1 deletion(-)
21
--- a/target/riscv/cpu.h
31
create mode 100644 target/riscv/vcrypto_helper.c
22
+++ b/target/riscv/cpu.h
32
create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc
33
34
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/riscv/cpu_cfg.h
37
+++ b/target/riscv/cpu_cfg.h
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
38
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
24
bool ext_xtheadbs;
39
bool ext_zve32f;
25
bool ext_xtheadcmo;
40
bool ext_zve64f;
26
bool ext_xtheadcondmov;
41
bool ext_zve64d;
27
+ bool ext_xtheadmac;
42
+ bool ext_zvbc;
28
bool ext_xtheadsync;
43
bool ext_zmmul;
29
bool ext_XVentanaCondOps;
44
bool ext_zvfbfmin;
30
45
bool ext_zvfbfwma;
31
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
46
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
32
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/xthead.decode
48
--- a/target/riscv/helper.h
34
+++ b/target/riscv/xthead.decode
49
+++ b/target/riscv/helper.h
35
@@ -XXX,XX +XXX,XX @@ th_l2cache_iall 0000000 10110 00000 000 00000 0001011
50
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vfwcvtbf16_f_f_v, void, ptr, ptr, ptr, env, i32)
36
th_mveqz 0100000 ..... ..... 001 ..... 0001011 @r
51
37
th_mvnez 0100001 ..... ..... 001 ..... 0001011 @r
52
DEF_HELPER_6(vfwmaccbf16_vv, void, ptr, ptr, ptr, ptr, env, i32)
38
53
DEF_HELPER_6(vfwmaccbf16_vf, void, ptr, ptr, i64, ptr, env, i32)
39
+# XTheadMac
54
+
40
+th_mula 00100 00 ..... ..... 001 ..... 0001011 @r
55
+/* Vector crypto functions */
41
+th_mulah 00101 00 ..... ..... 001 ..... 0001011 @r
56
+DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
42
+th_mulaw 00100 10 ..... ..... 001 ..... 0001011 @r
57
+DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
43
+th_muls 00100 01 ..... ..... 001 ..... 0001011 @r
58
+DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
44
+th_mulsh 00101 01 ..... ..... 001 ..... 0001011 @r
59
+DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
45
+th_mulsw 00100 11 ..... ..... 001 ..... 0001011 @r
60
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
46
+
61
index XXXXXXX..XXXXXXX 100644
47
# XTheadSync
62
--- a/target/riscv/insn32.decode
48
th_sfence_vmas 0000010 ..... ..... 000 00000 0001011 @rs2_s
63
+++ b/target/riscv/insn32.decode
49
th_sync 0000000 11000 00000 000 00000 0001011
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
50
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
51
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
52
--- a/target/riscv/cpu.c
76
--- a/target/riscv/cpu.c
53
+++ b/target/riscv/cpu.c
77
+++ b/target/riscv/cpu.c
54
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
78
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
55
ISA_EXT_DATA_ENTRY(xtheadbs, true, PRIV_VERSION_1_11_0, ext_xtheadbs),
79
ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
56
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
80
ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
57
ISA_EXT_DATA_ENTRY(xtheadcondmov, true, PRIV_VERSION_1_11_0, ext_xtheadcondmov),
81
ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
58
+ ISA_EXT_DATA_ENTRY(xtheadmac, true, PRIV_VERSION_1_11_0, ext_xtheadmac),
82
+ ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
59
ISA_EXT_DATA_ENTRY(xtheadsync, true, PRIV_VERSION_1_11_0, ext_xtheadsync),
83
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
60
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
84
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
85
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
86
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
87
return;
88
}
89
90
+ if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
91
+ error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
92
+ return;
93
+ }
94
+
95
if (cpu->cfg.ext_zk) {
96
cpu->cfg.ext_zkn = true;
97
cpu->cfg.ext_zkr = true;
98
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
99
DEFINE_PROP_BOOL("x-zvfbfmin", RISCVCPU, cfg.ext_zvfbfmin, false),
100
DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
101
102
+ /* Vector cryptography extensions */
103
+ DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
104
+
105
DEFINE_PROP_END_OF_LIST(),
61
};
106
};
62
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
63
DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
64
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
65
DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
66
+ DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false),
67
DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
68
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
69
107
70
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
108
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
71
index XXXXXXX..XXXXXXX 100644
109
index XXXXXXX..XXXXXXX 100644
72
--- a/target/riscv/translate.c
110
--- a/target/riscv/translate.c
73
+++ b/target/riscv/translate.c
111
+++ b/target/riscv/translate.c
74
@@ -XXX,XX +XXX,XX @@ static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
112
@@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
75
{
113
#include "insn_trans/trans_rvzfa.c.inc"
76
return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
114
#include "insn_trans/trans_rvzfh.c.inc"
77
ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
115
#include "insn_trans/trans_rvk.c.inc"
78
- ctx->cfg_ptr->ext_xtheadcondmov || ctx->cfg_ptr->ext_xtheadsync;
116
+#include "insn_trans/trans_rvvk.c.inc"
79
+ ctx->cfg_ptr->ext_xtheadcondmov || ctx->cfg_ptr->ext_xtheadmac ||
117
#include "insn_trans/trans_privileged.c.inc"
80
+ ctx->cfg_ptr->ext_xtheadsync;
118
#include "insn_trans/trans_svinval.c.inc"
81
}
119
#include "insn_trans/trans_rvbf16.c.inc"
82
120
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
83
#define MATERIALISE_EXT_PREDICATE(ext) \
121
new file mode 100644
84
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
122
index XXXXXXX..XXXXXXX
85
index XXXXXXX..XXXXXXX 100644
123
--- /dev/null
86
--- a/target/riscv/insn_trans/trans_xthead.c.inc
124
+++ b/target/riscv/vcrypto_helper.c
87
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
88
@@ -XXX,XX +XXX,XX @@
125
@@ -XXX,XX +XXX,XX @@
89
} \
126
+/*
90
} while (0)
127
+ * RISC-V Vector Crypto Extension Helpers for QEMU.
91
128
+ *
92
+#define REQUIRE_XTHEADMAC(ctx) do { \
129
+ * Copyright (C) 2023 SiFive, Inc.
93
+ if (!ctx->cfg_ptr->ext_xtheadmac) { \
130
+ * Written by Codethink Ltd and SiFive.
94
+ return false; \
131
+ *
95
+ } \
132
+ * This program is free software; you can redistribute it and/or modify it
96
+} while (0)
133
+ * under the terms and conditions of the GNU General Public License,
97
+
134
+ * version 2 or later, as published by the Free Software Foundation.
98
#define REQUIRE_XTHEADSYNC(ctx) do { \
135
+ *
99
if (!ctx->cfg_ptr->ext_xtheadsync) { \
136
+ * This program is distributed in the hope it will be useful, but WITHOUT
100
return false; \
137
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
101
@@ -XXX,XX +XXX,XX @@ static bool trans_th_mvnez(DisasContext *ctx, arg_th_mveqz *a)
138
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
102
return gen_th_condmove(ctx, a, TCG_COND_NE);
139
+ * more details.
103
}
140
+ *
104
141
+ * You should have received a copy of the GNU General Public License along with
105
+/* XTheadMac */
142
+ * this program. If not, see <http://www.gnu.org/licenses/>.
106
+
143
+ */
107
+static bool gen_th_mac(DisasContext *ctx, arg_r *a,
144
+
108
+ void (*accumulate_func)(TCGv, TCGv, TCGv),
145
+#include "qemu/osdep.h"
109
+ void (*extend_operand_func)(TCGv, TCGv))
146
+#include "qemu/host-utils.h"
110
+{
147
+#include "qemu/bitops.h"
111
+ TCGv dest = dest_gpr(ctx, a->rd);
148
+#include "cpu.h"
112
+ TCGv src0 = get_gpr(ctx, a->rd, EXT_NONE);
149
+#include "exec/memop.h"
113
+ TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
150
+#include "exec/exec-all.h"
114
+ TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
151
+#include "exec/helper-proto.h"
115
+ TCGv tmp = tcg_temp_new();
152
+#include "internals.h"
116
+
153
+#include "vector_internals.h"
117
+ if (extend_operand_func) {
154
+
118
+ TCGv tmp2 = tcg_temp_new();
155
+static uint64_t clmul64(uint64_t y, uint64_t x)
119
+ extend_operand_func(tmp, src1);
156
+{
120
+ extend_operand_func(tmp2, src2);
157
+ uint64_t result = 0;
121
+ tcg_gen_mul_tl(tmp, tmp, tmp2);
158
+ for (int j = 63; j >= 0; j--) {
122
+ tcg_temp_free(tmp2);
159
+ if ((y >> j) & 1) {
123
+ } else {
160
+ result ^= (x << j);
124
+ tcg_gen_mul_tl(tmp, src1, src2);
161
+ }
125
+ }
162
+ }
126
+
163
+ return result;
127
+ accumulate_func(dest, src0, tmp);
164
+}
128
+ gen_set_gpr(ctx, a->rd, dest);
165
+
129
+ tcg_temp_free(tmp);
166
+static uint64_t clmulh64(uint64_t y, uint64_t x)
130
+
167
+{
131
+ return true;
168
+ uint64_t result = 0;
132
+}
169
+ for (int j = 63; j >= 1; j--) {
133
+
170
+ if ((y >> j) & 1) {
134
+/* th.mula: "rd = rd + rs1 * rs2" */
171
+ result ^= (x >> (64 - j));
135
+static bool trans_th_mula(DisasContext *ctx, arg_th_mula *a)
172
+ }
136
+{
173
+ }
137
+ REQUIRE_XTHEADMAC(ctx);
174
+ return result;
138
+ return gen_th_mac(ctx, a, tcg_gen_add_tl, NULL);
175
+}
139
+}
176
+
140
+
177
+RVVCALL(OPIVV2, vclmul_vv, OP_UUU_D, H8, H8, H8, clmul64)
141
+/* th.mulah: "rd = sext.w(rd + sext.w(rs1[15:0]) * sext.w(rs2[15:0]))" */
178
+GEN_VEXT_VV(vclmul_vv, 8)
142
+static bool trans_th_mulah(DisasContext *ctx, arg_th_mulah *a)
179
+RVVCALL(OPIVX2, vclmul_vx, OP_UUU_D, H8, H8, clmul64)
143
+{
180
+GEN_VEXT_VX(vclmul_vx, 8)
144
+ REQUIRE_XTHEADMAC(ctx);
181
+RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64)
145
+ ctx->ol = MXL_RV32;
182
+GEN_VEXT_VV(vclmulh_vv, 8)
146
+ return gen_th_mac(ctx, a, tcg_gen_add_tl, tcg_gen_ext16s_tl);
183
+RVVCALL(OPIVX2, vclmulh_vx, OP_UUU_D, H8, H8, clmulh64)
147
+}
184
+GEN_VEXT_VX(vclmulh_vx, 8)
148
+
185
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
149
+/* th.mulaw: "rd = sext.w(rd + rs1 * rs2)" */
186
new file mode 100644
150
+static bool trans_th_mulaw(DisasContext *ctx, arg_th_mulaw *a)
187
index XXXXXXX..XXXXXXX
151
+{
188
--- /dev/null
152
+ REQUIRE_XTHEADMAC(ctx);
189
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
153
+ REQUIRE_64BIT(ctx);
190
@@ -XXX,XX +XXX,XX @@
154
+ ctx->ol = MXL_RV32;
191
+/*
155
+ return gen_th_mac(ctx, a, tcg_gen_add_tl, NULL);
192
+ * RISC-V translation routines for the vector crypto extension.
156
+}
193
+ *
157
+
194
+ * Copyright (C) 2023 SiFive, Inc.
158
+/* th.muls: "rd = rd - rs1 * rs2" */
195
+ * Written by Codethink Ltd and SiFive.
159
+static bool trans_th_muls(DisasContext *ctx, arg_th_muls *a)
196
+ *
160
+{
197
+ * This program is free software; you can redistribute it and/or modify it
161
+ REQUIRE_XTHEADMAC(ctx);
198
+ * under the terms and conditions of the GNU General Public License,
162
+ return gen_th_mac(ctx, a, tcg_gen_sub_tl, NULL);
199
+ * version 2 or later, as published by the Free Software Foundation.
163
+}
200
+ *
164
+
201
+ * This program is distributed in the hope it will be useful, but WITHOUT
165
+/* th.mulsh: "rd = sext.w(rd - sext.w(rs1[15:0]) * sext.w(rs2[15:0]))" */
202
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
166
+static bool trans_th_mulsh(DisasContext *ctx, arg_th_mulsh *a)
203
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
167
+{
204
+ * more details.
168
+ REQUIRE_XTHEADMAC(ctx);
205
+ *
169
+ ctx->ol = MXL_RV32;
206
+ * You should have received a copy of the GNU General Public License along with
170
+ return gen_th_mac(ctx, a, tcg_gen_sub_tl, tcg_gen_ext16s_tl);
207
+ * this program. If not, see <http://www.gnu.org/licenses/>.
171
+}
208
+ */
172
+
209
+
173
+/* th.mulsw: "rd = sext.w(rd - rs1 * rs2)" */
210
+/*
174
+static bool trans_th_mulsw(DisasContext *ctx, arg_th_mulsw *a)
211
+ * Zvbc
175
+{
212
+ */
176
+ REQUIRE_XTHEADMAC(ctx);
213
+
177
+ REQUIRE_64BIT(ctx);
214
+#define GEN_VV_MASKED_TRANS(NAME, CHECK) \
178
+ ctx->ol = MXL_RV32;
215
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
179
+ return gen_th_mac(ctx, a, tcg_gen_sub_tl, NULL);
216
+ { \
180
+}
217
+ if (CHECK(s, a)) { \
181
+
218
+ return opivv_trans(a->rd, a->rs1, a->rs2, a->vm, \
182
/* XTheadSync */
219
+ gen_helper_##NAME, s); \
183
220
+ } \
184
static bool trans_th_sfence_vmas(DisasContext *ctx, arg_th_sfence_vmas *a)
221
+ return false; \
222
+ }
223
+
224
+static bool vclmul_vv_check(DisasContext *s, arg_rmrr *a)
225
+{
226
+ return opivv_check(s, a) &&
227
+ s->cfg_ptr->ext_zvbc == true &&
228
+ s->sew == MO_64;
229
+}
230
+
231
+GEN_VV_MASKED_TRANS(vclmul_vv, vclmul_vv_check)
232
+GEN_VV_MASKED_TRANS(vclmulh_vv, vclmul_vv_check)
233
+
234
+#define GEN_VX_MASKED_TRANS(NAME, CHECK) \
235
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
236
+ { \
237
+ if (CHECK(s, a)) { \
238
+ return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, \
239
+ gen_helper_##NAME, s); \
240
+ } \
241
+ return false; \
242
+ }
243
+
244
+static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a)
245
+{
246
+ return opivx_check(s, a) &&
247
+ s->cfg_ptr->ext_zvbc == true &&
248
+ s->sew == MO_64;
249
+}
250
+
251
+GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check)
252
+GEN_VX_MASKED_TRANS(vclmulh_vx, vclmul_vx_check)
253
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
254
index XXXXXXX..XXXXXXX 100644
255
--- a/target/riscv/meson.build
256
+++ b/target/riscv/meson.build
257
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(files(
258
'translate.c',
259
'm128_helper.c',
260
'crypto_helper.c',
261
- 'zce_helper.c'
262
+ 'zce_helper.c',
263
+ 'vcrypto_helper.c'
264
))
265
riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c'))
266
185
--
267
--
186
2.39.1
268
2.41.0
diff view generated by jsdifflib
New patch
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
1
2
3
Move the checks out of `do_opiv{v,x,i}_gvec{,_shift}` functions
4
and into the corresponding macros. This enables the functions to be
5
reused in proceeding commits without check duplication.
6
7
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
10
Signed-off-by: Max Chou <max.chou@sifive.com>
11
Message-ID: <20230711165917.2629866-6-max.chou@sifive.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/insn_trans/trans_rvv.c.inc | 28 +++++++++++--------------
15
1 file changed, 12 insertions(+), 16 deletions(-)
16
17
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/insn_trans/trans_rvv.c.inc
20
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
21
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
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]); \
39
}
40
41
@@ -XXX,XX +XXX,XX @@ static inline bool
42
do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
43
gen_helper_opivx *fn)
44
{
45
- if (!opivx_check(s, a)) {
46
- return false;
47
- }
48
-
49
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
50
TCGv_i64 src1 = tcg_temp_new_i64();
51
52
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
53
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
54
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
55
}; \
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)
65
{
66
- if (!opivx_check(s, a)) {
67
- return false;
68
- }
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); \
82
}
83
@@ -XXX,XX +XXX,XX @@ static inline bool
84
do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
85
gen_helper_opivx *fn)
86
{
87
- if (!opivx_check(s, a)) {
88
- return false;
89
- }
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]); \
103
}
104
105
--
106
2.41.0
diff view generated by jsdifflib
New patch
1
From: Dickon Hood <dickon.hood@codethink.co.uk>
1
2
3
Zvbb (implemented in later commit) has a widening instruction, which
4
requires an extra check on the enabled extensions. Refactor
5
GEN_OPIVX_WIDEN_TRANS() to take a check function to avoid reimplementing
6
it.
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>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
12
Message-ID: <20230711165917.2629866-7-max.chou@sifive.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/insn_trans/trans_rvv.c.inc | 52 +++++++++++--------------
16
1 file changed, 23 insertions(+), 29 deletions(-)
17
18
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/insn_trans/trans_rvv.c.inc
21
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
22
@@ -XXX,XX +XXX,XX @@ static bool opivx_widen_check(DisasContext *s, arg_rmrr *a)
23
vext_check_ds(s, a->rd, a->rs2, a->vm);
24
}
25
26
-static bool do_opivx_widen(DisasContext *s, arg_rmrr *a,
27
- gen_helper_opivx *fn)
28
-{
29
- if (opivx_widen_check(s, a)) {
30
- return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
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; \
56
}
57
58
-GEN_OPIVX_WIDEN_TRANS(vwaddu_vx)
59
-GEN_OPIVX_WIDEN_TRANS(vwadd_vx)
60
-GEN_OPIVX_WIDEN_TRANS(vwsubu_vx)
61
-GEN_OPIVX_WIDEN_TRANS(vwsub_vx)
62
+GEN_OPIVX_WIDEN_TRANS(vwaddu_vx, opivx_widen_check)
63
+GEN_OPIVX_WIDEN_TRANS(vwadd_vx, opivx_widen_check)
64
+GEN_OPIVX_WIDEN_TRANS(vwsubu_vx, opivx_widen_check)
65
+GEN_OPIVX_WIDEN_TRANS(vwsub_vx, opivx_widen_check)
66
67
/* WIDEN OPIVV with WIDEN */
68
static bool opiwv_widen_check(DisasContext *s, arg_rmrr *a)
69
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vrem_vx, opivx_check)
70
GEN_OPIVV_WIDEN_TRANS(vwmul_vv, opivv_widen_check)
71
GEN_OPIVV_WIDEN_TRANS(vwmulu_vv, opivv_widen_check)
72
GEN_OPIVV_WIDEN_TRANS(vwmulsu_vv, opivv_widen_check)
73
-GEN_OPIVX_WIDEN_TRANS(vwmul_vx)
74
-GEN_OPIVX_WIDEN_TRANS(vwmulu_vx)
75
-GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx)
76
+GEN_OPIVX_WIDEN_TRANS(vwmul_vx, opivx_widen_check)
77
+GEN_OPIVX_WIDEN_TRANS(vwmulu_vx, opivx_widen_check)
78
+GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx, opivx_widen_check)
79
80
/* Vector Single-Width Integer Multiply-Add Instructions */
81
GEN_OPIVV_TRANS(vmacc_vv, opivv_check)
82
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vnmsub_vx, opivx_check)
83
GEN_OPIVV_WIDEN_TRANS(vwmaccu_vv, opivv_widen_check)
84
GEN_OPIVV_WIDEN_TRANS(vwmacc_vv, opivv_widen_check)
85
GEN_OPIVV_WIDEN_TRANS(vwmaccsu_vv, opivv_widen_check)
86
-GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx)
87
-GEN_OPIVX_WIDEN_TRANS(vwmacc_vx)
88
-GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx)
89
-GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx)
90
+GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx, opivx_widen_check)
91
+GEN_OPIVX_WIDEN_TRANS(vwmacc_vx, opivx_widen_check)
92
+GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx, opivx_widen_check)
93
+GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx, opivx_widen_check)
94
95
/* Vector Integer Merge and Move Instructions */
96
static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
97
--
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: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Dickon Hood <dickon.hood@codethink.co.uk>
2
2
3
This patch adds support for the T-Head MemIdx instructions.
3
This commit adds support for the Zvbb vector-crypto extension, which
4
The patch uses the T-Head specific decoder and translation.
4
consists of the following instructions:
5
5
6
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
6
* vrol.[vv,vx]
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
* vror.[vv,vx,vi]
8
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
8
* vbrev8.v
9
Message-Id: <20230131202013.2541053-10-christoph.muellner@vrull.eu>
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>
30
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
31
[max.chou@sifive.com: Exposed x-zvbb property]
32
Message-ID: <20230711165917.2629866-9-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
34
---
12
target/riscv/cpu.h | 1 +
35
target/riscv/cpu_cfg.h | 1 +
13
target/riscv/xthead.decode | 54 +++
36
target/riscv/helper.h | 62 +++++++++
14
target/riscv/cpu.c | 2 +
37
target/riscv/insn32.decode | 20 +++
15
target/riscv/translate.c | 21 +-
38
target/riscv/cpu.c | 12 ++
16
target/riscv/insn_trans/trans_xthead.c.inc | 387 +++++++++++++++++++++
39
target/riscv/vcrypto_helper.c | 138 +++++++++++++++++++
17
5 files changed, 464 insertions(+), 1 deletion(-)
40
target/riscv/insn_trans/trans_rvvk.c.inc | 164 +++++++++++++++++++++++
41
6 files changed, 397 insertions(+)
18
42
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
43
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
20
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.h
45
--- a/target/riscv/cpu_cfg.h
22
+++ b/target/riscv/cpu.h
46
+++ b/target/riscv/cpu_cfg.h
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
47
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
24
bool ext_xtheadcmo;
48
bool ext_zve32f;
25
bool ext_xtheadcondmov;
49
bool ext_zve64f;
26
bool ext_xtheadmac;
50
bool ext_zve64d;
27
+ bool ext_xtheadmemidx;
51
+ bool ext_zvbb;
28
bool ext_xtheadmempair;
52
bool ext_zvbc;
29
bool ext_xtheadsync;
53
bool ext_zmmul;
30
bool ext_XVentanaCondOps;
54
bool ext_zvfbfmin;
31
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
55
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
32
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/xthead.decode
57
--- a/target/riscv/helper.h
34
+++ b/target/riscv/xthead.decode
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
35
@@ -XXX,XX +XXX,XX @@
129
@@ -XXX,XX +XXX,XX @@
36
%rd2 20:5
130
%imm_u 12:s20 !function=ex_shift_12
37
%rs2 20:5
131
%imm_bs 30:2 !function=ex_shift_3
38
%sh5 20:5
132
%imm_rnum 20:4
39
+%imm5 20:s5
133
+%imm_z6 26:1 15:5
40
%sh6 20:6
134
41
%sh2 25:2
135
# Argument sets:
42
+%imm2 25:2
136
&empty
43
44
# Argument sets
45
&r rd rs1 rs2 !extern
46
@@ -XXX,XX +XXX,XX @@
137
@@ -XXX,XX +XXX,XX @@
47
&shift shamt rs1 rd !extern
138
@r_vm ...... vm:1 ..... ..... ... ..... ....... &rmrr %rs2 %rs1 %rd
48
&th_bfext msb lsb rs1 rd
139
@r_vm_1 ...... . ..... ..... ... ..... ....... &rmrr vm=1 %rs2 %rs1 %rd
49
&th_pair rd1 rs rd2 sh2
140
@r_vm_0 ...... . ..... ..... ... ..... ....... &rmrr vm=0 %rs2 %rs1 %rd
50
+&th_memidx rd rs1 rs2 imm2
141
+@r2_zimm6 ..... . vm:1 ..... ..... ... ..... ....... &rmrr %rs2 rs1=%imm_z6 %rd
51
+&th_meminc rd rs1 imm5 imm2
142
@r2_zimm11 . zimm:11 ..... ... ..... ....... %rs1 %rd
52
143
@r2_zimm10 .. zimm:10 ..... ... ..... ....... %rs1 %rd
53
# Formats
144
@r2_s ....... ..... ..... ... ..... ....... %rs2 %rs1
54
@sfence_vm ....... ..... ..... ... ..... ....... %rs1
145
@@ -XXX,XX +XXX,XX @@ vclmul_vv 001100 . ..... ..... 010 ..... 1010111 @r_vm
55
@@ -XXX,XX +XXX,XX @@
146
vclmul_vx 001100 . ..... ..... 110 ..... 1010111 @r_vm
56
@sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd
147
vclmulh_vv 001101 . ..... ..... 010 ..... 1010111 @r_vm
57
@sh6 ...... ...... ..... ... ..... ....... &shift shamt=%sh6 %rs1 %rd
148
vclmulh_vx 001101 . ..... ..... 110 ..... 1010111 @r_vm
58
@th_pair ..... .. ..... ..... ... ..... ....... &th_pair %rd1 %rs %rd2 %sh2
149
+
59
+@th_memidx ..... .. ..... ..... ... ..... ....... &th_memidx %rd %rs1 %rs2 %imm2
150
+# *** Zvbb vector crypto extension ***
60
+@th_meminc ..... .. ..... ..... ... ..... ....... &th_meminc %rd %rs1 %imm5 %imm2
151
+vrol_vv 010101 . ..... ..... 000 ..... 1010111 @r_vm
61
152
+vrol_vx 010101 . ..... ..... 100 ..... 1010111 @r_vm
62
# XTheadBa
153
+vror_vv 010100 . ..... ..... 000 ..... 1010111 @r_vm
63
# Instead of defining a new encoding, we simply use the decoder to
154
+vror_vx 010100 . ..... ..... 100 ..... 1010111 @r_vm
64
@@ -XXX,XX +XXX,XX @@ th_muls 00100 01 ..... ..... 001 ..... 0001011 @r
155
+vror_vi 01010. . ..... ..... 011 ..... 1010111 @r2_zimm6
65
th_mulsh 00101 01 ..... ..... 001 ..... 0001011 @r
156
+vbrev8_v 010010 . ..... 01000 010 ..... 1010111 @r2_vm
66
th_mulsw 00100 11 ..... ..... 001 ..... 0001011 @r
157
+vrev8_v 010010 . ..... 01001 010 ..... 1010111 @r2_vm
67
158
+vandn_vv 000001 . ..... ..... 000 ..... 1010111 @r_vm
68
+# XTheadMemIdx
159
+vandn_vx 000001 . ..... ..... 100 ..... 1010111 @r_vm
69
+th_ldia 01111 .. ..... ..... 100 ..... 0001011 @th_meminc
160
+vbrev_v 010010 . ..... 01010 010 ..... 1010111 @r2_vm
70
+th_ldib 01101 .. ..... ..... 100 ..... 0001011 @th_meminc
161
+vclz_v 010010 . ..... 01100 010 ..... 1010111 @r2_vm
71
+th_lwia 01011 .. ..... ..... 100 ..... 0001011 @th_meminc
162
+vctz_v 010010 . ..... 01101 010 ..... 1010111 @r2_vm
72
+th_lwib 01001 .. ..... ..... 100 ..... 0001011 @th_meminc
163
+vcpop_v 010010 . ..... 01110 010 ..... 1010111 @r2_vm
73
+th_lwuia 11011 .. ..... ..... 100 ..... 0001011 @th_meminc
164
+vwsll_vv 110101 . ..... ..... 000 ..... 1010111 @r_vm
74
+th_lwuib 11001 .. ..... ..... 100 ..... 0001011 @th_meminc
165
+vwsll_vx 110101 . ..... ..... 100 ..... 1010111 @r_vm
75
+th_lhia 00111 .. ..... ..... 100 ..... 0001011 @th_meminc
166
+vwsll_vi 110101 . ..... ..... 011 ..... 1010111 @r_vm
76
+th_lhib 00101 .. ..... ..... 100 ..... 0001011 @th_meminc
77
+th_lhuia 10111 .. ..... ..... 100 ..... 0001011 @th_meminc
78
+th_lhuib 10101 .. ..... ..... 100 ..... 0001011 @th_meminc
79
+th_lbia 00011 .. ..... ..... 100 ..... 0001011 @th_meminc
80
+th_lbib 00001 .. ..... ..... 100 ..... 0001011 @th_meminc
81
+th_lbuia 10011 .. ..... ..... 100 ..... 0001011 @th_meminc
82
+th_lbuib 10001 .. ..... ..... 100 ..... 0001011 @th_meminc
83
+th_sdia 01111 .. ..... ..... 101 ..... 0001011 @th_meminc
84
+th_sdib 01101 .. ..... ..... 101 ..... 0001011 @th_meminc
85
+th_swia 01011 .. ..... ..... 101 ..... 0001011 @th_meminc
86
+th_swib 01001 .. ..... ..... 101 ..... 0001011 @th_meminc
87
+th_shia 00111 .. ..... ..... 101 ..... 0001011 @th_meminc
88
+th_shib 00101 .. ..... ..... 101 ..... 0001011 @th_meminc
89
+th_sbia 00011 .. ..... ..... 101 ..... 0001011 @th_meminc
90
+th_sbib 00001 .. ..... ..... 101 ..... 0001011 @th_meminc
91
+
92
+th_lrd 01100 .. ..... ..... 100 ..... 0001011 @th_memidx
93
+th_lrw 01000 .. ..... ..... 100 ..... 0001011 @th_memidx
94
+th_lrwu 11000 .. ..... ..... 100 ..... 0001011 @th_memidx
95
+th_lrh 00100 .. ..... ..... 100 ..... 0001011 @th_memidx
96
+th_lrhu 10100 .. ..... ..... 100 ..... 0001011 @th_memidx
97
+th_lrb 00000 .. ..... ..... 100 ..... 0001011 @th_memidx
98
+th_lrbu 10000 .. ..... ..... 100 ..... 0001011 @th_memidx
99
+th_srd 01100 .. ..... ..... 101 ..... 0001011 @th_memidx
100
+th_srw 01000 .. ..... ..... 101 ..... 0001011 @th_memidx
101
+th_srh 00100 .. ..... ..... 101 ..... 0001011 @th_memidx
102
+th_srb 00000 .. ..... ..... 101 ..... 0001011 @th_memidx
103
+
104
+th_lurd 01110 .. ..... ..... 100 ..... 0001011 @th_memidx
105
+th_lurw 01010 .. ..... ..... 100 ..... 0001011 @th_memidx
106
+th_lurwu 11010 .. ..... ..... 100 ..... 0001011 @th_memidx
107
+th_lurh 00110 .. ..... ..... 100 ..... 0001011 @th_memidx
108
+th_lurhu 10110 .. ..... ..... 100 ..... 0001011 @th_memidx
109
+th_lurb 00010 .. ..... ..... 100 ..... 0001011 @th_memidx
110
+th_lurbu 10010 .. ..... ..... 100 ..... 0001011 @th_memidx
111
+th_surd 01110 .. ..... ..... 101 ..... 0001011 @th_memidx
112
+th_surw 01010 .. ..... ..... 101 ..... 0001011 @th_memidx
113
+th_surh 00110 .. ..... ..... 101 ..... 0001011 @th_memidx
114
+th_surb 00010 .. ..... ..... 101 ..... 0001011 @th_memidx
115
+
116
# XTheadMemPair
117
th_ldd 11111 .. ..... ..... 100 ..... 0001011 @th_pair
118
th_lwd 11100 .. ..... ..... 100 ..... 0001011 @th_pair
119
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
120
index XXXXXXX..XXXXXXX 100644
168
index XXXXXXX..XXXXXXX 100644
121
--- a/target/riscv/cpu.c
169
--- a/target/riscv/cpu.c
122
+++ b/target/riscv/cpu.c
170
+++ b/target/riscv/cpu.c
123
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
171
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
124
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
172
ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
125
ISA_EXT_DATA_ENTRY(xtheadcondmov, true, PRIV_VERSION_1_11_0, ext_xtheadcondmov),
173
ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
126
ISA_EXT_DATA_ENTRY(xtheadmac, true, PRIV_VERSION_1_11_0, ext_xtheadmac),
174
ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
127
+ ISA_EXT_DATA_ENTRY(xtheadmemidx, true, PRIV_VERSION_1_11_0, ext_xtheadmemidx),
175
+ ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
128
ISA_EXT_DATA_ENTRY(xtheadmempair, true, PRIV_VERSION_1_11_0, ext_xtheadmempair),
176
ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
129
ISA_EXT_DATA_ENTRY(xtheadsync, true, PRIV_VERSION_1_11_0, ext_xtheadsync),
177
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
130
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
178
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
179
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
180
return;
181
}
182
183
+ /*
184
+ * In principle Zve*x would also suffice here, were they supported
185
+ * in qemu
186
+ */
187
+ if (cpu->cfg.ext_zvbb && !cpu->cfg.ext_zve32f) {
188
+ error_setg(errp,
189
+ "Vector crypto extensions require V or Zve* extensions");
190
+ return;
191
+ }
192
+
193
if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
194
error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
195
return;
131
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
196
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
132
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
197
DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
133
DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
198
134
DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false),
199
/* Vector cryptography extensions */
135
+ DEFINE_PROP_BOOL("xtheadmemidx", RISCVCPU, cfg.ext_xtheadmemidx, false),
200
+ DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
136
DEFINE_PROP_BOOL("xtheadmempair", RISCVCPU, cfg.ext_xtheadmempair, false),
201
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
137
DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
202
138
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
203
DEFINE_PROP_END_OF_LIST(),
139
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
204
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
140
index XXXXXXX..XXXXXXX 100644
205
index XXXXXXX..XXXXXXX 100644
141
--- a/target/riscv/translate.c
206
--- a/target/riscv/vcrypto_helper.c
142
+++ b/target/riscv/translate.c
207
+++ b/target/riscv/vcrypto_helper.c
143
@@ -XXX,XX +XXX,XX @@ static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
208
@@ -XXX,XX +XXX,XX @@
144
return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
209
#include "qemu/osdep.h"
145
ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
210
#include "qemu/host-utils.h"
146
ctx->cfg_ptr->ext_xtheadcondmov || ctx->cfg_ptr->ext_xtheadmac ||
211
#include "qemu/bitops.h"
147
- ctx->cfg_ptr->ext_xtheadmempair || ctx->cfg_ptr->ext_xtheadsync;
212
+#include "qemu/bswap.h"
148
+ ctx->cfg_ptr->ext_xtheadmemidx || ctx->cfg_ptr->ext_xtheadmempair ||
213
#include "cpu.h"
149
+ ctx->cfg_ptr->ext_xtheadsync;
214
#include "exec/memop.h"
150
}
215
#include "exec/exec-all.h"
151
216
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64)
152
#define MATERIALISE_EXT_PREDICATE(ext) \
217
GEN_VEXT_VV(vclmulh_vv, 8)
153
@@ -XXX,XX +XXX,XX @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm)
218
RVVCALL(OPIVX2, vclmulh_vx, OP_UUU_D, H8, H8, clmulh64)
154
return addr;
219
GEN_VEXT_VX(vclmulh_vx, 8)
155
}
220
+
156
221
+RVVCALL(OPIVV2, vror_vv_b, OP_UUU_B, H1, H1, H1, ror8)
157
+/* Compute a canonical address from a register plus reg offset. */
222
+RVVCALL(OPIVV2, vror_vv_h, OP_UUU_H, H2, H2, H2, ror16)
158
+static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs)
223
+RVVCALL(OPIVV2, vror_vv_w, OP_UUU_W, H4, H4, H4, ror32)
224
+RVVCALL(OPIVV2, vror_vv_d, OP_UUU_D, H8, H8, H8, ror64)
225
+GEN_VEXT_VV(vror_vv_b, 1)
226
+GEN_VEXT_VV(vror_vv_h, 2)
227
+GEN_VEXT_VV(vror_vv_w, 4)
228
+GEN_VEXT_VV(vror_vv_d, 8)
229
+
230
+RVVCALL(OPIVX2, vror_vx_b, OP_UUU_B, H1, H1, ror8)
231
+RVVCALL(OPIVX2, vror_vx_h, OP_UUU_H, H2, H2, ror16)
232
+RVVCALL(OPIVX2, vror_vx_w, OP_UUU_W, H4, H4, ror32)
233
+RVVCALL(OPIVX2, vror_vx_d, OP_UUU_D, H8, H8, ror64)
234
+GEN_VEXT_VX(vror_vx_b, 1)
235
+GEN_VEXT_VX(vror_vx_h, 2)
236
+GEN_VEXT_VX(vror_vx_w, 4)
237
+GEN_VEXT_VX(vror_vx_d, 8)
238
+
239
+RVVCALL(OPIVV2, vrol_vv_b, OP_UUU_B, H1, H1, H1, rol8)
240
+RVVCALL(OPIVV2, vrol_vv_h, OP_UUU_H, H2, H2, H2, rol16)
241
+RVVCALL(OPIVV2, vrol_vv_w, OP_UUU_W, H4, H4, H4, rol32)
242
+RVVCALL(OPIVV2, vrol_vv_d, OP_UUU_D, H8, H8, H8, rol64)
243
+GEN_VEXT_VV(vrol_vv_b, 1)
244
+GEN_VEXT_VV(vrol_vv_h, 2)
245
+GEN_VEXT_VV(vrol_vv_w, 4)
246
+GEN_VEXT_VV(vrol_vv_d, 8)
247
+
248
+RVVCALL(OPIVX2, vrol_vx_b, OP_UUU_B, H1, H1, rol8)
249
+RVVCALL(OPIVX2, vrol_vx_h, OP_UUU_H, H2, H2, rol16)
250
+RVVCALL(OPIVX2, vrol_vx_w, OP_UUU_W, H4, H4, rol32)
251
+RVVCALL(OPIVX2, vrol_vx_d, OP_UUU_D, H8, H8, rol64)
252
+GEN_VEXT_VX(vrol_vx_b, 1)
253
+GEN_VEXT_VX(vrol_vx_h, 2)
254
+GEN_VEXT_VX(vrol_vx_w, 4)
255
+GEN_VEXT_VX(vrol_vx_d, 8)
256
+
257
+static uint64_t brev8(uint64_t val)
159
+{
258
+{
160
+ TCGv addr = temp_new(ctx);
259
+ val = ((val & 0x5555555555555555ull) << 1) |
161
+ TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
260
+ ((val & 0xAAAAAAAAAAAAAAAAull) >> 1);
162
+
261
+ val = ((val & 0x3333333333333333ull) << 2) |
163
+ tcg_gen_add_tl(addr, src1, offs);
262
+ ((val & 0xCCCCCCCCCCCCCCCCull) >> 2);
164
+ if (ctx->pm_mask_enabled) {
263
+ val = ((val & 0x0F0F0F0F0F0F0F0Full) << 4) |
165
+ tcg_gen_andc_tl(addr, addr, pm_mask);
264
+ ((val & 0xF0F0F0F0F0F0F0F0ull) >> 4);
166
+ } else if (get_xl(ctx) == MXL_RV32) {
265
+
167
+ tcg_gen_ext32u_tl(addr, addr);
266
+ return val;
168
+ }
169
+ if (ctx->pm_base_enabled) {
170
+ tcg_gen_or_tl(addr, addr, pm_base);
171
+ }
172
+ return addr;
173
+}
267
+}
174
+
268
+
175
#ifndef CONFIG_USER_ONLY
269
+RVVCALL(OPIVV1, vbrev8_v_b, OP_UU_B, H1, H1, brev8)
176
/* The states of mstatus_fs are:
270
+RVVCALL(OPIVV1, vbrev8_v_h, OP_UU_H, H2, H2, brev8)
177
* 0 = disabled, 1 = initial, 2 = clean, 3 = dirty
271
+RVVCALL(OPIVV1, vbrev8_v_w, OP_UU_W, H4, H4, brev8)
178
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
272
+RVVCALL(OPIVV1, vbrev8_v_d, OP_UU_D, H8, H8, brev8)
273
+GEN_VEXT_V(vbrev8_v_b, 1)
274
+GEN_VEXT_V(vbrev8_v_h, 2)
275
+GEN_VEXT_V(vbrev8_v_w, 4)
276
+GEN_VEXT_V(vbrev8_v_d, 8)
277
+
278
+#define DO_IDENTITY(a) (a)
279
+RVVCALL(OPIVV1, vrev8_v_b, OP_UU_B, H1, H1, DO_IDENTITY)
280
+RVVCALL(OPIVV1, vrev8_v_h, OP_UU_H, H2, H2, bswap16)
281
+RVVCALL(OPIVV1, vrev8_v_w, OP_UU_W, H4, H4, bswap32)
282
+RVVCALL(OPIVV1, vrev8_v_d, OP_UU_D, H8, H8, bswap64)
283
+GEN_VEXT_V(vrev8_v_b, 1)
284
+GEN_VEXT_V(vrev8_v_h, 2)
285
+GEN_VEXT_V(vrev8_v_w, 4)
286
+GEN_VEXT_V(vrev8_v_d, 8)
287
+
288
+#define DO_ANDN(a, b) ((a) & ~(b))
289
+RVVCALL(OPIVV2, vandn_vv_b, OP_UUU_B, H1, H1, H1, DO_ANDN)
290
+RVVCALL(OPIVV2, vandn_vv_h, OP_UUU_H, H2, H2, H2, DO_ANDN)
291
+RVVCALL(OPIVV2, vandn_vv_w, OP_UUU_W, H4, H4, H4, DO_ANDN)
292
+RVVCALL(OPIVV2, vandn_vv_d, OP_UUU_D, H8, H8, H8, DO_ANDN)
293
+GEN_VEXT_VV(vandn_vv_b, 1)
294
+GEN_VEXT_VV(vandn_vv_h, 2)
295
+GEN_VEXT_VV(vandn_vv_w, 4)
296
+GEN_VEXT_VV(vandn_vv_d, 8)
297
+
298
+RVVCALL(OPIVX2, vandn_vx_b, OP_UUU_B, H1, H1, DO_ANDN)
299
+RVVCALL(OPIVX2, vandn_vx_h, OP_UUU_H, H2, H2, DO_ANDN)
300
+RVVCALL(OPIVX2, vandn_vx_w, OP_UUU_W, H4, H4, DO_ANDN)
301
+RVVCALL(OPIVX2, vandn_vx_d, OP_UUU_D, H8, H8, DO_ANDN)
302
+GEN_VEXT_VX(vandn_vx_b, 1)
303
+GEN_VEXT_VX(vandn_vx_h, 2)
304
+GEN_VEXT_VX(vandn_vx_w, 4)
305
+GEN_VEXT_VX(vandn_vx_d, 8)
306
+
307
+RVVCALL(OPIVV1, vbrev_v_b, OP_UU_B, H1, H1, revbit8)
308
+RVVCALL(OPIVV1, vbrev_v_h, OP_UU_H, H2, H2, revbit16)
309
+RVVCALL(OPIVV1, vbrev_v_w, OP_UU_W, H4, H4, revbit32)
310
+RVVCALL(OPIVV1, vbrev_v_d, OP_UU_D, H8, H8, revbit64)
311
+GEN_VEXT_V(vbrev_v_b, 1)
312
+GEN_VEXT_V(vbrev_v_h, 2)
313
+GEN_VEXT_V(vbrev_v_w, 4)
314
+GEN_VEXT_V(vbrev_v_d, 8)
315
+
316
+RVVCALL(OPIVV1, vclz_v_b, OP_UU_B, H1, H1, clz8)
317
+RVVCALL(OPIVV1, vclz_v_h, OP_UU_H, H2, H2, clz16)
318
+RVVCALL(OPIVV1, vclz_v_w, OP_UU_W, H4, H4, clz32)
319
+RVVCALL(OPIVV1, vclz_v_d, OP_UU_D, H8, H8, clz64)
320
+GEN_VEXT_V(vclz_v_b, 1)
321
+GEN_VEXT_V(vclz_v_h, 2)
322
+GEN_VEXT_V(vclz_v_w, 4)
323
+GEN_VEXT_V(vclz_v_d, 8)
324
+
325
+RVVCALL(OPIVV1, vctz_v_b, OP_UU_B, H1, H1, ctz8)
326
+RVVCALL(OPIVV1, vctz_v_h, OP_UU_H, H2, H2, ctz16)
327
+RVVCALL(OPIVV1, vctz_v_w, OP_UU_W, H4, H4, ctz32)
328
+RVVCALL(OPIVV1, vctz_v_d, OP_UU_D, H8, H8, ctz64)
329
+GEN_VEXT_V(vctz_v_b, 1)
330
+GEN_VEXT_V(vctz_v_h, 2)
331
+GEN_VEXT_V(vctz_v_w, 4)
332
+GEN_VEXT_V(vctz_v_d, 8)
333
+
334
+RVVCALL(OPIVV1, vcpop_v_b, OP_UU_B, H1, H1, ctpop8)
335
+RVVCALL(OPIVV1, vcpop_v_h, OP_UU_H, H2, H2, ctpop16)
336
+RVVCALL(OPIVV1, vcpop_v_w, OP_UU_W, H4, H4, ctpop32)
337
+RVVCALL(OPIVV1, vcpop_v_d, OP_UU_D, H8, H8, ctpop64)
338
+GEN_VEXT_V(vcpop_v_b, 1)
339
+GEN_VEXT_V(vcpop_v_h, 2)
340
+GEN_VEXT_V(vcpop_v_w, 4)
341
+GEN_VEXT_V(vcpop_v_d, 8)
342
+
343
+#define DO_SLL(N, M) (N << (M & (sizeof(N) * 8 - 1)))
344
+RVVCALL(OPIVV2, vwsll_vv_b, WOP_UUU_B, H2, H1, H1, DO_SLL)
345
+RVVCALL(OPIVV2, vwsll_vv_h, WOP_UUU_H, H4, H2, H2, DO_SLL)
346
+RVVCALL(OPIVV2, vwsll_vv_w, WOP_UUU_W, H8, H4, H4, DO_SLL)
347
+GEN_VEXT_VV(vwsll_vv_b, 2)
348
+GEN_VEXT_VV(vwsll_vv_h, 4)
349
+GEN_VEXT_VV(vwsll_vv_w, 8)
350
+
351
+RVVCALL(OPIVX2, vwsll_vx_b, WOP_UUU_B, H2, H1, DO_SLL)
352
+RVVCALL(OPIVX2, vwsll_vx_h, WOP_UUU_H, H4, H2, DO_SLL)
353
+RVVCALL(OPIVX2, vwsll_vx_w, WOP_UUU_W, H8, H4, DO_SLL)
354
+GEN_VEXT_VX(vwsll_vx_b, 2)
355
+GEN_VEXT_VX(vwsll_vx_h, 4)
356
+GEN_VEXT_VX(vwsll_vx_w, 8)
357
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
179
index XXXXXXX..XXXXXXX 100644
358
index XXXXXXX..XXXXXXX 100644
180
--- a/target/riscv/insn_trans/trans_xthead.c.inc
359
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
181
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
360
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
182
@@ -XXX,XX +XXX,XX @@
361
@@ -XXX,XX +XXX,XX @@ static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a)
183
} \
362
184
} while (0)
363
GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check)
185
364
GEN_VX_MASKED_TRANS(vclmulh_vx, vclmul_vx_check)
186
+#define REQUIRE_XTHEADMEMIDX(ctx) do { \
365
+
187
+ if (!ctx->cfg_ptr->ext_xtheadmemidx) { \
188
+ return false; \
189
+ } \
190
+} while (0)
191
+
192
#define REQUIRE_XTHEADMEMPAIR(ctx) do { \
193
if (!ctx->cfg_ptr->ext_xtheadmempair) { \
194
return false; \
195
@@ -XXX,XX +XXX,XX @@
196
} \
197
} while (0)
198
199
+/*
366
+/*
200
+ * Calculate and return the address for indexed mem operations:
367
+ * Zvbb
201
+ * If !zext_offs, then the address is rs1 + (rs2 << imm2).
202
+ * If zext_offs, then the address is rs1 + (zext(rs2[31:0]) << imm2).
203
+ */
368
+ */
204
+static TCGv get_th_address_indexed(DisasContext *ctx, int rs1, int rs2,
369
+
205
+ int imm2, bool zext_offs)
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)
206
+{
418
+{
207
+ TCGv src2 = get_gpr(ctx, rs2, EXT_NONE);
419
+ return opivv_check(s, a) && s->cfg_ptr->ext_zvbb == true;
208
+ TCGv offs = tcg_temp_new();
209
+
210
+ if (zext_offs) {
211
+ tcg_gen_extract_tl(offs, src2, 0, 32);
212
+ tcg_gen_shli_tl(offs, offs, imm2);
213
+ } else {
214
+ tcg_gen_shli_tl(offs, src2, imm2);
215
+ }
216
+
217
+ TCGv addr = get_address_indexed(ctx, rs1, offs);
218
+
219
+ tcg_temp_free(offs);
220
+ return addr;
221
+}
420
+}
222
+
421
+
223
/* XTheadBa */
422
+static bool zvbb_vx_check(DisasContext *s, arg_rmrr *a)
224
225
/*
226
@@ -XXX,XX +XXX,XX @@ static bool trans_th_mulsw(DisasContext *ctx, arg_th_mulsw *a)
227
return gen_th_mac(ctx, a, tcg_gen_sub_tl, NULL);
228
}
229
230
+/* XTheadMemIdx */
231
+
232
+/*
233
+ * Load with memop from indexed address and add (imm5 << imm2) to rs1.
234
+ * If !preinc, then the load address is rs1.
235
+ * If preinc, then the load address is rs1 + (imm5) << imm2).
236
+ */
237
+static bool gen_load_inc(DisasContext *ctx, arg_th_meminc *a, MemOp memop,
238
+ bool preinc)
239
+{
423
+{
240
+ if (a->rs1 == a->rd) {
424
+ return opivx_check(s, a) && s->cfg_ptr->ext_zvbb == true;
241
+ return false;
242
+ }
243
+
244
+ int imm = a->imm5 << a->imm2;
245
+ TCGv addr = get_address(ctx, a->rs1, preinc ? imm : 0);
246
+ TCGv rd = dest_gpr(ctx, a->rd);
247
+ TCGv rs1 = get_gpr(ctx, a->rs1, EXT_NONE);
248
+
249
+ tcg_gen_qemu_ld_tl(rd, addr, ctx->mem_idx, memop);
250
+ tcg_gen_addi_tl(rs1, rs1, imm);
251
+ gen_set_gpr(ctx, a->rd, rd);
252
+ gen_set_gpr(ctx, a->rs1, rs1);
253
+
254
+ tcg_temp_free(addr);
255
+ return true;
256
+}
425
+}
257
+
426
+
258
+/*
427
+/* vrol.v[vx] */
259
+ * Store with memop to indexed address and add (imm5 << imm2) to rs1.
428
+GEN_OPIVV_GVEC_TRANS_CHECK(vrol_vv, rotlv, zvbb_vv_check)
260
+ * If !preinc, then the store address is rs1.
429
+GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vrol_vx, rotls, zvbb_vx_check)
261
+ * If preinc, then the store address is rs1 + (imm5) << imm2).
430
+
262
+ */
431
+/* vror.v[vxi] */
263
+static bool gen_store_inc(DisasContext *ctx, arg_th_meminc *a, MemOp memop,
432
+GEN_OPIVV_GVEC_TRANS_CHECK(vror_vv, rotrv, zvbb_vv_check)
264
+ bool preinc)
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)
265
+{
486
+{
266
+ int imm = a->imm5 << a->imm2;
487
+ return s->cfg_ptr->ext_zvbb == true &&
267
+ TCGv addr = get_address(ctx, a->rs1, preinc ? imm : 0);
488
+ require_rvv(s) &&
268
+ TCGv data = get_gpr(ctx, a->rd, EXT_NONE);
489
+ vext_check_isa_ill(s) &&
269
+ TCGv rs1 = get_gpr(ctx, a->rs1, EXT_NONE);
490
+ vext_check_ss(s, a->rd, a->rs2, a->vm);
270
+
271
+ tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
272
+ tcg_gen_addi_tl(rs1, rs1, imm);
273
+ gen_set_gpr(ctx, a->rs1, rs1);
274
+
275
+ tcg_temp_free(addr);
276
+ return true;
277
+}
491
+}
278
+
492
+
279
+static bool trans_th_ldia(DisasContext *ctx, arg_th_meminc *a)
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)
280
+{
501
+{
281
+ REQUIRE_XTHEADMEMIDX(ctx);
502
+ return s->cfg_ptr->ext_zvbb && opivv_widen_check(s, a);
282
+ REQUIRE_64BIT(ctx);
283
+ return gen_load_inc(ctx, a, MO_TESQ, false);
284
+}
503
+}
285
+
504
+
286
+static bool trans_th_ldib(DisasContext *ctx, arg_th_meminc *a)
505
+static bool vwsll_vx_check(DisasContext *s, arg_rmrr *a)
287
+{
506
+{
288
+ REQUIRE_XTHEADMEMIDX(ctx);
507
+ return s->cfg_ptr->ext_zvbb && opivx_widen_check(s, a);
289
+ REQUIRE_64BIT(ctx);
290
+ return gen_load_inc(ctx, a, MO_TESQ, true);
291
+}
508
+}
292
+
509
+
293
+static bool trans_th_lwia(DisasContext *ctx, arg_th_meminc *a)
510
+/* OPIVI without GVEC IR */
294
+{
511
+#define GEN_OPIVI_WIDEN_TRANS(NAME, IMM_MODE, OPIVX, CHECK) \
295
+ REQUIRE_XTHEADMEMIDX(ctx);
512
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
296
+ return gen_load_inc(ctx, a, MO_TESL, false);
513
+ { \
297
+}
514
+ if (CHECK(s, a)) { \
298
+
515
+ static gen_helper_opivx *const fns[3] = { \
299
+static bool trans_th_lwib(DisasContext *ctx, arg_th_meminc *a)
516
+ gen_helper_##OPIVX##_b, \
300
+{
517
+ gen_helper_##OPIVX##_h, \
301
+ REQUIRE_XTHEADMEMIDX(ctx);
518
+ gen_helper_##OPIVX##_w, \
302
+ return gen_load_inc(ctx, a, MO_TESL, true);
519
+ }; \
303
+}
520
+ return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s, \
304
+
521
+ IMM_MODE); \
305
+static bool trans_th_lwuia(DisasContext *ctx, arg_th_meminc *a)
522
+ } \
306
+{
523
+ return false; \
307
+ REQUIRE_XTHEADMEMIDX(ctx);
524
+ }
308
+ REQUIRE_64BIT(ctx);
525
+
309
+ return gen_load_inc(ctx, a, MO_TEUL, false);
526
+GEN_OPIVV_WIDEN_TRANS(vwsll_vv, vwsll_vv_check)
310
+}
527
+GEN_OPIVX_WIDEN_TRANS(vwsll_vx, vwsll_vx_check)
311
+
528
+GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
312
+static bool trans_th_lwuib(DisasContext *ctx, arg_th_meminc *a)
313
+{
314
+ REQUIRE_XTHEADMEMIDX(ctx);
315
+ REQUIRE_64BIT(ctx);
316
+ return gen_load_inc(ctx, a, MO_TEUL, true);
317
+}
318
+
319
+static bool trans_th_lhia(DisasContext *ctx, arg_th_meminc *a)
320
+{
321
+ REQUIRE_XTHEADMEMIDX(ctx);
322
+ return gen_load_inc(ctx, a, MO_TESW, false);
323
+}
324
+
325
+static bool trans_th_lhib(DisasContext *ctx, arg_th_meminc *a)
326
+{
327
+ REQUIRE_XTHEADMEMIDX(ctx);
328
+ return gen_load_inc(ctx, a, MO_TESW, true);
329
+}
330
+
331
+static bool trans_th_lhuia(DisasContext *ctx, arg_th_meminc *a)
332
+{
333
+ REQUIRE_XTHEADMEMIDX(ctx);
334
+ return gen_load_inc(ctx, a, MO_TEUW, false);
335
+}
336
+
337
+static bool trans_th_lhuib(DisasContext *ctx, arg_th_meminc *a)
338
+{
339
+ REQUIRE_XTHEADMEMIDX(ctx);
340
+ return gen_load_inc(ctx, a, MO_TEUW, true);
341
+}
342
+
343
+static bool trans_th_lbia(DisasContext *ctx, arg_th_meminc *a)
344
+{
345
+ REQUIRE_XTHEADMEMIDX(ctx);
346
+ return gen_load_inc(ctx, a, MO_SB, false);
347
+}
348
+
349
+static bool trans_th_lbib(DisasContext *ctx, arg_th_meminc *a)
350
+{
351
+ REQUIRE_XTHEADMEMIDX(ctx);
352
+ return gen_load_inc(ctx, a, MO_SB, true);
353
+}
354
+
355
+static bool trans_th_lbuia(DisasContext *ctx, arg_th_meminc *a)
356
+{
357
+ REQUIRE_XTHEADMEMIDX(ctx);
358
+ return gen_load_inc(ctx, a, MO_UB, false);
359
+}
360
+
361
+static bool trans_th_lbuib(DisasContext *ctx, arg_th_meminc *a)
362
+{
363
+ REQUIRE_XTHEADMEMIDX(ctx);
364
+ return gen_load_inc(ctx, a, MO_UB, true);
365
+}
366
+
367
+static bool trans_th_sdia(DisasContext *ctx, arg_th_meminc *a)
368
+{
369
+ REQUIRE_XTHEADMEMIDX(ctx);
370
+ REQUIRE_64BIT(ctx);
371
+ return gen_store_inc(ctx, a, MO_TESQ, false);
372
+}
373
+
374
+static bool trans_th_sdib(DisasContext *ctx, arg_th_meminc *a)
375
+{
376
+ REQUIRE_XTHEADMEMIDX(ctx);
377
+ REQUIRE_64BIT(ctx);
378
+ return gen_store_inc(ctx, a, MO_TESQ, true);
379
+}
380
+
381
+static bool trans_th_swia(DisasContext *ctx, arg_th_meminc *a)
382
+{
383
+ REQUIRE_XTHEADMEMIDX(ctx);
384
+ return gen_store_inc(ctx, a, MO_TESL, false);
385
+}
386
+
387
+static bool trans_th_swib(DisasContext *ctx, arg_th_meminc *a)
388
+{
389
+ REQUIRE_XTHEADMEMIDX(ctx);
390
+ return gen_store_inc(ctx, a, MO_TESL, true);
391
+}
392
+
393
+static bool trans_th_shia(DisasContext *ctx, arg_th_meminc *a)
394
+{
395
+ REQUIRE_XTHEADMEMIDX(ctx);
396
+ return gen_store_inc(ctx, a, MO_TESW, false);
397
+}
398
+
399
+static bool trans_th_shib(DisasContext *ctx, arg_th_meminc *a)
400
+{
401
+ REQUIRE_XTHEADMEMIDX(ctx);
402
+ return gen_store_inc(ctx, a, MO_TESW, true);
403
+}
404
+
405
+static bool trans_th_sbia(DisasContext *ctx, arg_th_meminc *a)
406
+{
407
+ REQUIRE_XTHEADMEMIDX(ctx);
408
+ return gen_store_inc(ctx, a, MO_SB, false);
409
+}
410
+
411
+static bool trans_th_sbib(DisasContext *ctx, arg_th_meminc *a)
412
+{
413
+ REQUIRE_XTHEADMEMIDX(ctx);
414
+ return gen_store_inc(ctx, a, MO_SB, true);
415
+}
416
+
417
+/*
418
+ * Load with memop from indexed address.
419
+ * If !zext_offs, then address is rs1 + (rs2 << imm2).
420
+ * If zext_offs, then address is rs1 + (zext(rs2[31:0]) << imm2).
421
+ */
422
+static bool gen_load_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop,
423
+ bool zext_offs)
424
+{
425
+ TCGv rd = dest_gpr(ctx, a->rd);
426
+ TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs);
427
+
428
+ tcg_gen_qemu_ld_tl(rd, addr, ctx->mem_idx, memop);
429
+ gen_set_gpr(ctx, a->rd, rd);
430
+
431
+ return true;
432
+}
433
+
434
+/*
435
+ * Store with memop to indexed address.
436
+ * If !zext_offs, then address is rs1 + (rs2 << imm2).
437
+ * If zext_offs, then address is rs1 + (zext(rs2[31:0]) << imm2).
438
+ */
439
+static bool gen_store_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop,
440
+ bool zext_offs)
441
+{
442
+ TCGv data = get_gpr(ctx, a->rd, EXT_NONE);
443
+ TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs);
444
+
445
+ tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
446
+
447
+ return true;
448
+}
449
+
450
+static bool trans_th_lrd(DisasContext *ctx, arg_th_memidx *a)
451
+{
452
+ REQUIRE_XTHEADMEMIDX(ctx);
453
+ REQUIRE_64BIT(ctx);
454
+ return gen_load_idx(ctx, a, MO_TESQ, false);
455
+}
456
+
457
+static bool trans_th_lrw(DisasContext *ctx, arg_th_memidx *a)
458
+{
459
+ REQUIRE_XTHEADMEMIDX(ctx);
460
+ return gen_load_idx(ctx, a, MO_TESL, false);
461
+}
462
+
463
+static bool trans_th_lrwu(DisasContext *ctx, arg_th_memidx *a)
464
+{
465
+ REQUIRE_XTHEADMEMIDX(ctx);
466
+ REQUIRE_64BIT(ctx);
467
+ return gen_load_idx(ctx, a, MO_TEUL, false);
468
+}
469
+
470
+static bool trans_th_lrh(DisasContext *ctx, arg_th_memidx *a)
471
+{
472
+ REQUIRE_XTHEADMEMIDX(ctx);
473
+ return gen_load_idx(ctx, a, MO_TESW, false);
474
+}
475
+
476
+static bool trans_th_lrhu(DisasContext *ctx, arg_th_memidx *a)
477
+{
478
+ REQUIRE_XTHEADMEMIDX(ctx);
479
+ return gen_load_idx(ctx, a, MO_TEUW, false);
480
+}
481
+
482
+static bool trans_th_lrb(DisasContext *ctx, arg_th_memidx *a)
483
+{
484
+ REQUIRE_XTHEADMEMIDX(ctx);
485
+ return gen_load_idx(ctx, a, MO_SB, false);
486
+}
487
+
488
+static bool trans_th_lrbu(DisasContext *ctx, arg_th_memidx *a)
489
+{
490
+ REQUIRE_XTHEADMEMIDX(ctx);
491
+ return gen_load_idx(ctx, a, MO_UB, false);
492
+}
493
+
494
+static bool trans_th_srd(DisasContext *ctx, arg_th_memidx *a)
495
+{
496
+ REQUIRE_XTHEADMEMIDX(ctx);
497
+ REQUIRE_64BIT(ctx);
498
+ return gen_store_idx(ctx, a, MO_TESQ, false);
499
+}
500
+
501
+static bool trans_th_srw(DisasContext *ctx, arg_th_memidx *a)
502
+{
503
+ REQUIRE_XTHEADMEMIDX(ctx);
504
+ return gen_store_idx(ctx, a, MO_TESL, false);
505
+}
506
+
507
+static bool trans_th_srh(DisasContext *ctx, arg_th_memidx *a)
508
+{
509
+ REQUIRE_XTHEADMEMIDX(ctx);
510
+ return gen_store_idx(ctx, a, MO_TESW, false);
511
+}
512
+
513
+static bool trans_th_srb(DisasContext *ctx, arg_th_memidx *a)
514
+{
515
+ REQUIRE_XTHEADMEMIDX(ctx);
516
+ return gen_store_idx(ctx, a, MO_SB, false);
517
+}
518
+static bool trans_th_lurd(DisasContext *ctx, arg_th_memidx *a)
519
+{
520
+ REQUIRE_XTHEADMEMIDX(ctx);
521
+ REQUIRE_64BIT(ctx);
522
+ return gen_load_idx(ctx, a, MO_TESQ, true);
523
+}
524
+
525
+static bool trans_th_lurw(DisasContext *ctx, arg_th_memidx *a)
526
+{
527
+ REQUIRE_XTHEADMEMIDX(ctx);
528
+ return gen_load_idx(ctx, a, MO_TESL, true);
529
+}
530
+
531
+static bool trans_th_lurwu(DisasContext *ctx, arg_th_memidx *a)
532
+{
533
+ REQUIRE_XTHEADMEMIDX(ctx);
534
+ REQUIRE_64BIT(ctx);
535
+ return gen_load_idx(ctx, a, MO_TEUL, true);
536
+}
537
+
538
+static bool trans_th_lurh(DisasContext *ctx, arg_th_memidx *a)
539
+{
540
+ REQUIRE_XTHEADMEMIDX(ctx);
541
+ return gen_load_idx(ctx, a, MO_TESW, true);
542
+}
543
+
544
+static bool trans_th_lurhu(DisasContext *ctx, arg_th_memidx *a)
545
+{
546
+ REQUIRE_XTHEADMEMIDX(ctx);
547
+ return gen_load_idx(ctx, a, MO_TEUW, true);
548
+}
549
+
550
+static bool trans_th_lurb(DisasContext *ctx, arg_th_memidx *a)
551
+{
552
+ REQUIRE_XTHEADMEMIDX(ctx);
553
+ return gen_load_idx(ctx, a, MO_SB, true);
554
+}
555
+
556
+static bool trans_th_lurbu(DisasContext *ctx, arg_th_memidx *a)
557
+{
558
+ REQUIRE_XTHEADMEMIDX(ctx);
559
+ return gen_load_idx(ctx, a, MO_UB, true);
560
+}
561
+
562
+static bool trans_th_surd(DisasContext *ctx, arg_th_memidx *a)
563
+{
564
+ REQUIRE_XTHEADMEMIDX(ctx);
565
+ REQUIRE_64BIT(ctx);
566
+ return gen_store_idx(ctx, a, MO_TESQ, true);
567
+}
568
+
569
+static bool trans_th_surw(DisasContext *ctx, arg_th_memidx *a)
570
+{
571
+ REQUIRE_XTHEADMEMIDX(ctx);
572
+ return gen_store_idx(ctx, a, MO_TESL, true);
573
+}
574
+
575
+static bool trans_th_surh(DisasContext *ctx, arg_th_memidx *a)
576
+{
577
+ REQUIRE_XTHEADMEMIDX(ctx);
578
+ return gen_store_idx(ctx, a, MO_TESW, true);
579
+}
580
+
581
+static bool trans_th_surb(DisasContext *ctx, arg_th_memidx *a)
582
+{
583
+ REQUIRE_XTHEADMEMIDX(ctx);
584
+ return gen_store_idx(ctx, a, MO_SB, true);
585
+}
586
+
587
/* XTheadMemPair */
588
589
static bool gen_loadpair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop,
590
--
529
--
591
2.39.1
530
2.41.0
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
This patch adds support for the XTheadCondMov ISA extension.
3
This commit adds support for the Zvkned vector-crypto extension, which
4
The patch uses the T-Head specific decoder and translation.
4
consists of the following instructions:
5
5
6
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
6
* vaesef.[vv,vs]
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
* vaesdf.[vv,vs]
8
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
8
* vaesdm.[vv,vs]
9
Message-Id: <20230131202013.2541053-7-christoph.muellner@vrull.eu>
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>
25
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
26
[max.chou@sifive.com: Imported aes-round.h and exposed x-zvkned
27
property]
28
[max.chou@sifive.com: Fixed endian issues and replaced the vstart & vl
29
egs checking by helper function]
30
[max.chou@sifive.com: Replaced bswap32 calls in aes key expanding]
31
Message-ID: <20230711165917.2629866-10-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
32
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
33
---
12
target/riscv/cpu.h | 1 +
34
target/riscv/cpu_cfg.h | 1 +
13
target/riscv/xthead.decode | 4 +++
35
target/riscv/helper.h | 14 ++
14
target/riscv/cpu.c | 2 ++
36
target/riscv/insn32.decode | 14 ++
15
target/riscv/translate.c | 2 +-
37
target/riscv/cpu.c | 4 +-
16
target/riscv/insn_trans/trans_xthead.c.inc | 35 ++++++++++++++++++++++
38
target/riscv/vcrypto_helper.c | 202 +++++++++++++++++++++++
17
5 files changed, 43 insertions(+), 1 deletion(-)
39
target/riscv/insn_trans/trans_rvvk.c.inc | 147 +++++++++++++++++
40
6 files changed, 381 insertions(+), 1 deletion(-)
18
41
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
42
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
20
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.h
44
--- a/target/riscv/cpu_cfg.h
22
+++ b/target/riscv/cpu.h
45
+++ b/target/riscv/cpu_cfg.h
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
46
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
24
bool ext_xtheadbb;
47
bool ext_zve64d;
25
bool ext_xtheadbs;
48
bool ext_zvbb;
26
bool ext_xtheadcmo;
49
bool ext_zvbc;
27
+ bool ext_xtheadcondmov;
50
+ bool ext_zvkned;
28
bool ext_xtheadsync;
51
bool ext_zmmul;
29
bool ext_XVentanaCondOps;
52
bool ext_zvfbfmin;
30
53
bool ext_zvfbfwma;
31
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
54
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
32
index XXXXXXX..XXXXXXX 100644
55
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/xthead.decode
56
--- a/target/riscv/helper.h
34
+++ b/target/riscv/xthead.decode
57
+++ b/target/riscv/helper.h
35
@@ -XXX,XX +XXX,XX @@ th_l2cache_call 0000000 10101 00000 000 00000 0001011
58
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vandn_vx_b, void, ptr, ptr, tl, ptr, env, i32)
36
th_l2cache_ciall 0000000 10111 00000 000 00000 0001011
59
DEF_HELPER_6(vandn_vx_h, void, ptr, ptr, tl, ptr, env, i32)
37
th_l2cache_iall 0000000 10110 00000 000 00000 0001011
60
DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, i32)
38
61
DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32)
39
+# XTheadCondMov
62
+
40
+th_mveqz 0100000 ..... ..... 001 ..... 0001011 @r
63
+DEF_HELPER_2(egs_check, void, i32, env)
41
+th_mvnez 0100001 ..... ..... 001 ..... 0001011 @r
64
+
42
+
65
+DEF_HELPER_4(vaesef_vv, void, ptr, ptr, env, i32)
43
# XTheadSync
66
+DEF_HELPER_4(vaesef_vs, void, ptr, ptr, env, i32)
44
th_sfence_vmas 0000010 ..... ..... 000 00000 0001011 @rs2_s
67
+DEF_HELPER_4(vaesdf_vv, void, ptr, ptr, env, i32)
45
th_sync 0000000 11000 00000 000 00000 0001011
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
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/riscv/insn32.decode
79
+++ b/target/riscv/insn32.decode
80
@@ -XXX,XX +XXX,XX @@
81
@r_rm ....... ..... ..... ... ..... ....... %rs2 %rs1 %rm %rd
82
@r2_rm ....... ..... ..... ... ..... ....... %rs1 %rm %rd
83
@r2 ....... ..... ..... ... ..... ....... &r2 %rs1 %rd
84
+@r2_vm_1 ...... . ..... ..... ... ..... ....... &rmr vm=1 %rs2 %rd
85
@r2_nfvm ... ... vm:1 ..... ..... ... ..... ....... &r2nfvm %nf %rs1 %rd
86
@r2_vm ...... vm:1 ..... ..... ... ..... ....... &rmr %rs2 %rd
87
@r1_vm ...... vm:1 ..... ..... ... ..... ....... %rd
88
@@ -XXX,XX +XXX,XX @@ vcpop_v 010010 . ..... 01110 010 ..... 1010111 @r2_vm
89
vwsll_vv 110101 . ..... ..... 000 ..... 1010111 @r_vm
90
vwsll_vx 110101 . ..... ..... 100 ..... 1010111 @r_vm
91
vwsll_vi 110101 . ..... ..... 011 ..... 1010111 @r_vm
92
+
93
+# *** Zvkned vector crypto extension ***
94
+vaesef_vv 101000 1 ..... 00011 010 ..... 1110111 @r2_vm_1
95
+vaesef_vs 101001 1 ..... 00011 010 ..... 1110111 @r2_vm_1
96
+vaesdf_vv 101000 1 ..... 00001 010 ..... 1110111 @r2_vm_1
97
+vaesdf_vs 101001 1 ..... 00001 010 ..... 1110111 @r2_vm_1
98
+vaesem_vv 101000 1 ..... 00010 010 ..... 1110111 @r2_vm_1
99
+vaesem_vs 101001 1 ..... 00010 010 ..... 1110111 @r2_vm_1
100
+vaesdm_vv 101000 1 ..... 00000 010 ..... 1110111 @r2_vm_1
101
+vaesdm_vs 101001 1 ..... 00000 010 ..... 1110111 @r2_vm_1
102
+vaesz_vs 101001 1 ..... 00111 010 ..... 1110111 @r2_vm_1
103
+vaeskf1_vi 100010 1 ..... ..... 010 ..... 1110111 @r_vm_1
104
+vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1
46
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
105
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
47
index XXXXXXX..XXXXXXX 100644
106
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/cpu.c
107
--- a/target/riscv/cpu.c
49
+++ b/target/riscv/cpu.c
108
+++ b/target/riscv/cpu.c
50
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
109
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
51
ISA_EXT_DATA_ENTRY(xtheadbb, true, PRIV_VERSION_1_11_0, ext_xtheadbb),
110
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
52
ISA_EXT_DATA_ENTRY(xtheadbs, true, PRIV_VERSION_1_11_0, ext_xtheadbs),
111
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
53
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
112
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
54
+ ISA_EXT_DATA_ENTRY(xtheadcondmov, true, PRIV_VERSION_1_11_0, ext_xtheadcondmov),
113
+ ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
55
ISA_EXT_DATA_ENTRY(xtheadsync, true, PRIV_VERSION_1_11_0, ext_xtheadsync),
114
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
56
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
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(),
57
};
133
};
58
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
134
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
59
DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false),
60
DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
61
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
62
+ DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
63
DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
64
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
65
66
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
67
index XXXXXXX..XXXXXXX 100644
135
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/translate.c
136
--- a/target/riscv/vcrypto_helper.c
69
+++ b/target/riscv/translate.c
137
+++ b/target/riscv/vcrypto_helper.c
70
@@ -XXX,XX +XXX,XX @@ static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
138
@@ -XXX,XX +XXX,XX @@
71
{
139
#include "qemu/bitops.h"
72
return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
140
#include "qemu/bswap.h"
73
ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
141
#include "cpu.h"
74
- ctx->cfg_ptr->ext_xtheadsync;
142
+#include "crypto/aes.h"
75
+ ctx->cfg_ptr->ext_xtheadcondmov || ctx->cfg_ptr->ext_xtheadsync;
143
+#include "crypto/aes-round.h"
76
}
144
#include "exec/memop.h"
77
145
#include "exec/exec-all.h"
78
#define MATERIALISE_EXT_PREDICATE(ext) \
146
#include "exec/helper-proto.h"
79
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
147
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vwsll_vx_w, WOP_UUU_W, H8, H4, DO_SLL)
148
GEN_VEXT_VX(vwsll_vx_b, 2)
149
GEN_VEXT_VX(vwsll_vx_h, 4)
150
GEN_VEXT_VX(vwsll_vx_w, 8)
151
+
152
+void HELPER(egs_check)(uint32_t egs, CPURISCVState *env)
153
+{
154
+ uint32_t vl = env->vl;
155
+ uint32_t vstart = env->vstart;
156
+
157
+ if (vl % egs != 0 || vstart % egs != 0) {
158
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
159
+ }
160
+}
161
+
162
+static inline void xor_round_key(AESState *round_state, AESState *round_key)
163
+{
164
+ round_state->v = round_state->v ^ round_key->v;
165
+}
166
+
167
+#define GEN_ZVKNED_HELPER_VV(NAME, ...) \
168
+ void HELPER(NAME)(void *vd, void *vs2, CPURISCVState *env, \
169
+ uint32_t desc) \
170
+ { \
171
+ uint32_t vl = env->vl; \
172
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4); \
173
+ uint32_t vta = vext_vta(desc); \
174
+ \
175
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \
176
+ AESState round_key; \
177
+ round_key.d[0] = *((uint64_t *)vs2 + H8(i * 2 + 0)); \
178
+ round_key.d[1] = *((uint64_t *)vs2 + H8(i * 2 + 1)); \
179
+ AESState round_state; \
180
+ round_state.d[0] = *((uint64_t *)vd + H8(i * 2 + 0)); \
181
+ round_state.d[1] = *((uint64_t *)vd + H8(i * 2 + 1)); \
182
+ __VA_ARGS__; \
183
+ *((uint64_t *)vd + H8(i * 2 + 0)) = round_state.d[0]; \
184
+ *((uint64_t *)vd + H8(i * 2 + 1)) = round_state.d[1]; \
185
+ } \
186
+ env->vstart = 0; \
187
+ /* set tail elements to 1s */ \
188
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4); \
189
+ }
190
+
191
+#define GEN_ZVKNED_HELPER_VS(NAME, ...) \
192
+ void HELPER(NAME)(void *vd, void *vs2, CPURISCVState *env, \
193
+ uint32_t desc) \
194
+ { \
195
+ uint32_t vl = env->vl; \
196
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4); \
197
+ uint32_t vta = vext_vta(desc); \
198
+ \
199
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \
200
+ AESState round_key; \
201
+ round_key.d[0] = *((uint64_t *)vs2 + H8(0)); \
202
+ round_key.d[1] = *((uint64_t *)vs2 + H8(1)); \
203
+ AESState round_state; \
204
+ round_state.d[0] = *((uint64_t *)vd + H8(i * 2 + 0)); \
205
+ round_state.d[1] = *((uint64_t *)vd + H8(i * 2 + 1)); \
206
+ __VA_ARGS__; \
207
+ *((uint64_t *)vd + H8(i * 2 + 0)) = round_state.d[0]; \
208
+ *((uint64_t *)vd + H8(i * 2 + 1)) = round_state.d[1]; \
209
+ } \
210
+ env->vstart = 0; \
211
+ /* set tail elements to 1s */ \
212
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4); \
213
+ }
214
+
215
+GEN_ZVKNED_HELPER_VV(vaesef_vv, aesenc_SB_SR_AK(&round_state,
216
+ &round_state,
217
+ &round_key,
218
+ false);)
219
+GEN_ZVKNED_HELPER_VS(vaesef_vs, aesenc_SB_SR_AK(&round_state,
220
+ &round_state,
221
+ &round_key,
222
+ false);)
223
+GEN_ZVKNED_HELPER_VV(vaesdf_vv, aesdec_ISB_ISR_AK(&round_state,
224
+ &round_state,
225
+ &round_key,
226
+ false);)
227
+GEN_ZVKNED_HELPER_VS(vaesdf_vs, aesdec_ISB_ISR_AK(&round_state,
228
+ &round_state,
229
+ &round_key,
230
+ false);)
231
+GEN_ZVKNED_HELPER_VV(vaesem_vv, aesenc_SB_SR_MC_AK(&round_state,
232
+ &round_state,
233
+ &round_key,
234
+ false);)
235
+GEN_ZVKNED_HELPER_VS(vaesem_vs, aesenc_SB_SR_MC_AK(&round_state,
236
+ &round_state,
237
+ &round_key,
238
+ false);)
239
+GEN_ZVKNED_HELPER_VV(vaesdm_vv, aesdec_ISB_ISR_AK_IMC(&round_state,
240
+ &round_state,
241
+ &round_key,
242
+ false);)
243
+GEN_ZVKNED_HELPER_VS(vaesdm_vs, aesdec_ISB_ISR_AK_IMC(&round_state,
244
+ &round_state,
245
+ &round_key,
246
+ false);)
247
+GEN_ZVKNED_HELPER_VS(vaesz_vs, xor_round_key(&round_state, &round_key);)
248
+
249
+void HELPER(vaeskf1_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
250
+ CPURISCVState *env, uint32_t desc)
251
+{
252
+ uint32_t *vd = vd_vptr;
253
+ uint32_t *vs2 = vs2_vptr;
254
+ uint32_t vl = env->vl;
255
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
256
+ uint32_t vta = vext_vta(desc);
257
+
258
+ uimm &= 0b1111;
259
+ if (uimm > 10 || uimm == 0) {
260
+ uimm ^= 0b1000;
261
+ }
262
+
263
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
264
+ uint32_t rk[8], tmp;
265
+ static const uint32_t rcon[] = {
266
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
267
+ 0x00000020, 0x00000040, 0x00000080, 0x0000001B, 0x00000036,
268
+ };
269
+
270
+ rk[0] = vs2[i * 4 + H4(0)];
271
+ rk[1] = vs2[i * 4 + H4(1)];
272
+ rk[2] = vs2[i * 4 + H4(2)];
273
+ rk[3] = vs2[i * 4 + H4(3)];
274
+ tmp = ror32(rk[3], 8);
275
+
276
+ rk[4] = rk[0] ^ (((uint32_t)AES_sbox[(tmp >> 24) & 0xff] << 24) |
277
+ ((uint32_t)AES_sbox[(tmp >> 16) & 0xff] << 16) |
278
+ ((uint32_t)AES_sbox[(tmp >> 8) & 0xff] << 8) |
279
+ ((uint32_t)AES_sbox[(tmp >> 0) & 0xff] << 0))
280
+ ^ rcon[uimm - 1];
281
+ rk[5] = rk[1] ^ rk[4];
282
+ rk[6] = rk[2] ^ rk[5];
283
+ rk[7] = rk[3] ^ rk[6];
284
+
285
+ vd[i * 4 + H4(0)] = rk[4];
286
+ vd[i * 4 + H4(1)] = rk[5];
287
+ vd[i * 4 + H4(2)] = rk[6];
288
+ vd[i * 4 + H4(3)] = rk[7];
289
+ }
290
+ env->vstart = 0;
291
+ /* set tail elements to 1s */
292
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
293
+}
294
+
295
+void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
296
+ CPURISCVState *env, uint32_t desc)
297
+{
298
+ uint32_t *vd = vd_vptr;
299
+ uint32_t *vs2 = vs2_vptr;
300
+ uint32_t vl = env->vl;
301
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
302
+ uint32_t vta = vext_vta(desc);
303
+
304
+ uimm &= 0b1111;
305
+ if (uimm > 14 || uimm < 2) {
306
+ uimm ^= 0b1000;
307
+ }
308
+
309
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
310
+ uint32_t rk[12], tmp;
311
+ static const uint32_t rcon[] = {
312
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
313
+ 0x00000020, 0x00000040, 0x00000080, 0x0000001B, 0x00000036,
314
+ };
315
+
316
+ rk[0] = vd[i * 4 + H4(0)];
317
+ rk[1] = vd[i * 4 + H4(1)];
318
+ rk[2] = vd[i * 4 + H4(2)];
319
+ rk[3] = vd[i * 4 + H4(3)];
320
+ rk[4] = vs2[i * 4 + H4(0)];
321
+ rk[5] = vs2[i * 4 + H4(1)];
322
+ rk[6] = vs2[i * 4 + H4(2)];
323
+ rk[7] = vs2[i * 4 + H4(3)];
324
+
325
+ if (uimm % 2 == 0) {
326
+ tmp = ror32(rk[7], 8);
327
+ rk[8] = rk[0] ^ (((uint32_t)AES_sbox[(tmp >> 24) & 0xff] << 24) |
328
+ ((uint32_t)AES_sbox[(tmp >> 16) & 0xff] << 16) |
329
+ ((uint32_t)AES_sbox[(tmp >> 8) & 0xff] << 8) |
330
+ ((uint32_t)AES_sbox[(tmp >> 0) & 0xff] << 0))
331
+ ^ rcon[(uimm - 1) / 2];
332
+ } else {
333
+ rk[8] = rk[0] ^ (((uint32_t)AES_sbox[(rk[7] >> 24) & 0xff] << 24) |
334
+ ((uint32_t)AES_sbox[(rk[7] >> 16) & 0xff] << 16) |
335
+ ((uint32_t)AES_sbox[(rk[7] >> 8) & 0xff] << 8) |
336
+ ((uint32_t)AES_sbox[(rk[7] >> 0) & 0xff] << 0));
337
+ }
338
+ rk[9] = rk[1] ^ rk[8];
339
+ rk[10] = rk[2] ^ rk[9];
340
+ rk[11] = rk[3] ^ rk[10];
341
+
342
+ vd[i * 4 + H4(0)] = rk[8];
343
+ vd[i * 4 + H4(1)] = rk[9];
344
+ vd[i * 4 + H4(2)] = rk[10];
345
+ vd[i * 4 + H4(3)] = rk[11];
346
+ }
347
+ env->vstart = 0;
348
+ /* set tail elements to 1s */
349
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
350
+}
351
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
80
index XXXXXXX..XXXXXXX 100644
352
index XXXXXXX..XXXXXXX 100644
81
--- a/target/riscv/insn_trans/trans_xthead.c.inc
353
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
82
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
354
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
83
@@ -XXX,XX +XXX,XX @@
355
@@ -XXX,XX +XXX,XX @@ static bool vwsll_vx_check(DisasContext *s, arg_rmrr *a)
84
} \
356
GEN_OPIVV_WIDEN_TRANS(vwsll_vv, vwsll_vv_check)
85
} while (0)
357
GEN_OPIVX_WIDEN_TRANS(vwsll_vx, vwsll_vx_check)
86
358
GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
87
+#define REQUIRE_XTHEADCONDMOV(ctx) do { \
359
+
88
+ if (!ctx->cfg_ptr->ext_xtheadcondmov) { \
360
+/*
89
+ return false; \
361
+ * Zvkned
90
+ } \
362
+ */
91
+} while (0)
363
+
92
+
364
+#define ZVKNED_EGS 4
93
#define REQUIRE_XTHEADSYNC(ctx) do { \
365
+
94
if (!ctx->cfg_ptr->ext_xtheadsync) { \
366
+#define GEN_V_UNMASKED_TRANS(NAME, CHECK, EGS) \
95
return false; \
367
+ static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
96
@@ -XXX,XX +XXX,XX @@ NOP_PRIVCHECK(th_l2cache_call, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
368
+ { \
97
NOP_PRIVCHECK(th_l2cache_ciall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
369
+ if (CHECK(s, a)) { \
98
NOP_PRIVCHECK(th_l2cache_iall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
370
+ TCGv_ptr rd_v, rs2_v; \
99
371
+ TCGv_i32 desc, egs; \
100
+/* XTheadCondMov */
372
+ uint32_t data = 0; \
101
+
373
+ TCGLabel *over = gen_new_label(); \
102
+static bool gen_th_condmove(DisasContext *ctx, arg_r *a, TCGCond cond)
374
+ \
103
+{
375
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
104
+ TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
376
+ /* save opcode for unwinding in case we throw an exception */ \
105
+ TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
377
+ decode_save_opc(s); \
106
+ TCGv old = get_gpr(ctx, a->rd, EXT_NONE);
378
+ egs = tcg_constant_i32(EGS); \
107
+ TCGv dest = dest_gpr(ctx, a->rd);
379
+ gen_helper_egs_check(egs, cpu_env); \
108
+
380
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
109
+ tcg_gen_movcond_tl(cond, dest, src2, ctx->zero, src1, old);
381
+ } \
110
+
382
+ \
111
+ gen_set_gpr(ctx, a->rd, dest);
383
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
112
+ return true;
384
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
113
+}
385
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
114
+
386
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
115
+/* th.mveqz: "if (rs2 == 0) rd = rs1;" */
387
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
116
+static bool trans_th_mveqz(DisasContext *ctx, arg_th_mveqz *a)
388
+ rd_v = tcg_temp_new_ptr(); \
117
+{
389
+ rs2_v = tcg_temp_new_ptr(); \
118
+ REQUIRE_XTHEADCONDMOV(ctx);
390
+ desc = tcg_constant_i32( \
119
+ return gen_th_condmove(ctx, a, TCG_COND_EQ);
391
+ simd_desc(s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, data)); \
120
+}
392
+ tcg_gen_addi_ptr(rd_v, cpu_env, vreg_ofs(s, a->rd)); \
121
+
393
+ tcg_gen_addi_ptr(rs2_v, cpu_env, vreg_ofs(s, a->rs2)); \
122
+/* th.mvnez: "if (rs2 != 0) rd = rs1;" */
394
+ gen_helper_##NAME(rd_v, rs2_v, cpu_env, desc); \
123
+static bool trans_th_mvnez(DisasContext *ctx, arg_th_mveqz *a)
395
+ mark_vs_dirty(s); \
124
+{
396
+ gen_set_label(over); \
125
+ REQUIRE_XTHEADCONDMOV(ctx);
397
+ return true; \
126
+ return gen_th_condmove(ctx, a, TCG_COND_NE);
398
+ } \
127
+}
399
+ return false; \
128
+
400
+ }
129
/* XTheadSync */
401
+
130
402
+static bool vaes_check_vv(DisasContext *s, arg_rmr *a)
131
static bool trans_th_sfence_vmas(DisasContext *ctx, arg_th_sfence_vmas *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)
132
--
506
--
133
2.39.1
507
2.41.0
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
This patch adds support for the XTheadSync ISA extension.
3
This commit adds support for the Zvknh vector-crypto extension, which
4
The patch uses the T-Head specific decoder and translation.
4
consists of the following instructions:
5
5
6
The implementation introduces a helper to execute synchronization tasks:
6
* vsha2ms.vv
7
helper_tlb_flush_all() performs a synchronized TLB flush on all CPUs.
7
* vsha2c[hl].vv
8
8
9
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Translation functions are defined in
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
11
`target/riscv/vcrypto_helper.c`.
12
Message-Id: <20230131202013.2541053-3-christoph.muellner@vrull.eu>
12
13
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
14
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
15
[max.chou@sifive.com: Replaced vstart checking by TCG op]
16
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
17
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
18
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
19
Signed-off-by: Max Chou <max.chou@sifive.com>
20
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
21
[max.chou@sifive.com: Exposed x-zvknha & x-zvknhb properties]
22
[max.chou@sifive.com: Replaced SEW selection to happened during
23
translation]
24
Message-ID: <20230711165917.2629866-11-max.chou@sifive.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
26
---
15
target/riscv/cpu.h | 1 +
27
target/riscv/cpu_cfg.h | 2 +
16
target/riscv/helper.h | 1 +
28
target/riscv/helper.h | 6 +
17
target/riscv/xthead.decode | 9 +++
29
target/riscv/insn32.decode | 5 +
18
target/riscv/cpu.c | 2 +
30
target/riscv/cpu.c | 13 +-
19
target/riscv/op_helper.c | 6 ++
31
target/riscv/vcrypto_helper.c | 238 +++++++++++++++++++++++
20
target/riscv/translate.c | 2 +-
32
target/riscv/insn_trans/trans_rvvk.c.inc | 129 ++++++++++++
21
target/riscv/insn_trans/trans_xthead.c.inc | 85 ++++++++++++++++++++++
33
6 files changed, 390 insertions(+), 3 deletions(-)
22
7 files changed, 105 insertions(+), 1 deletion(-)
23
34
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
35
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
25
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
37
--- a/target/riscv/cpu_cfg.h
27
+++ b/target/riscv/cpu.h
38
+++ b/target/riscv/cpu_cfg.h
28
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
39
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
29
40
bool ext_zvbb;
30
/* Vendor-specific custom extensions */
41
bool ext_zvbc;
31
bool ext_xtheadcmo;
42
bool ext_zvkned;
32
+ bool ext_xtheadsync;
43
+ bool ext_zvknha;
33
bool ext_XVentanaCondOps;
44
+ bool ext_zvknhb;
34
45
bool ext_zmmul;
35
uint8_t pmu_num;
46
bool ext_zvfbfmin;
47
bool ext_zvfbfwma;
36
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
48
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
37
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/helper.h
50
--- a/target/riscv/helper.h
39
+++ b/target/riscv/helper.h
51
+++ b/target/riscv/helper.h
40
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(sret, tl, env)
52
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
41
DEF_HELPER_1(mret, tl, env)
53
DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
42
DEF_HELPER_1(wfi, void, env)
54
DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
43
DEF_HELPER_1(tlb_flush, void, env)
55
DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
44
+DEF_HELPER_1(tlb_flush_all, void, env)
56
+
45
/* Native Debug */
57
+DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32)
46
DEF_HELPER_1(itrigger_match, void, env)
58
+DEF_HELPER_5(vsha2ch32_vv, void, ptr, ptr, ptr, env, i32)
47
#endif
59
+DEF_HELPER_5(vsha2ch64_vv, void, ptr, ptr, ptr, env, i32)
48
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
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
49
index XXXXXXX..XXXXXXX 100644
63
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/xthead.decode
64
--- a/target/riscv/insn32.decode
51
+++ b/target/riscv/xthead.decode
65
+++ b/target/riscv/insn32.decode
52
@@ -XXX,XX +XXX,XX @@
66
@@ -XXX,XX +XXX,XX @@ vaesdm_vs 101001 1 ..... 00000 010 ..... 1110111 @r2_vm_1
53
67
vaesz_vs 101001 1 ..... 00111 010 ..... 1110111 @r2_vm_1
54
# Fields:
68
vaeskf1_vi 100010 1 ..... ..... 010 ..... 1110111 @r_vm_1
55
%rs1 15:5
69
vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1
56
+%rs2 20:5
70
+
57
71
+# *** Zvknh vector crypto extension ***
58
# Formats
72
+vsha2ms_vv 101101 1 ..... ..... 010 ..... 1110111 @r_vm_1
59
@sfence_vm ....... ..... ..... ... ..... ....... %rs1
73
+vsha2ch_vv 101110 1 ..... ..... 010 ..... 1110111 @r_vm_1
60
+@rs2_s ....... ..... ..... ... ..... ....... %rs2 %rs1
74
+vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
61
62
# XTheadCmo
63
th_dcache_call 0000000 00001 00000 000 00000 0001011
64
@@ -XXX,XX +XXX,XX @@ th_icache_iva 0000001 10000 ..... 000 00000 0001011 @sfence_vm
65
th_l2cache_call 0000000 10101 00000 000 00000 0001011
66
th_l2cache_ciall 0000000 10111 00000 000 00000 0001011
67
th_l2cache_iall 0000000 10110 00000 000 00000 0001011
68
+
69
+# XTheadSync
70
+th_sfence_vmas 0000010 ..... ..... 000 00000 0001011 @rs2_s
71
+th_sync 0000000 11000 00000 000 00000 0001011
72
+th_sync_i 0000000 11010 00000 000 00000 0001011
73
+th_sync_is 0000000 11011 00000 000 00000 0001011
74
+th_sync_s 0000000 11001 00000 000 00000 0001011
75
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
76
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/riscv/cpu.c
77
--- a/target/riscv/cpu.c
78
+++ b/target/riscv/cpu.c
78
+++ b/target/riscv/cpu.c
79
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
79
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
80
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
80
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
81
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
81
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
82
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
82
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
83
+ ISA_EXT_DATA_ENTRY(xtheadsync, true, PRIV_VERSION_1_11_0, ext_xtheadsync),
83
+ ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
84
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
84
+ ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
85
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
86
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
87
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
88
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
89
* In principle Zve*x would also suffice here, were they supported
90
* in qemu
91
*/
92
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) && !cpu->cfg.ext_zve32f) {
93
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
94
+ !cpu->cfg.ext_zve32f) {
95
error_setg(errp,
96
"Vector crypto extensions require V or Zve* extensions");
97
return;
98
}
99
100
- if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
101
- error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
102
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
103
+ error_setg(
104
+ errp,
105
+ "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
106
return;
107
}
108
109
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
110
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
111
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
112
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
113
+ DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
114
+ DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
115
116
DEFINE_PROP_END_OF_LIST(),
85
};
117
};
86
118
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
87
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
88
89
/* Vendor-specific custom extensions */
90
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
91
+ DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
92
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
93
94
/* These are experimental so mark with 'x-' */
95
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
96
index XXXXXXX..XXXXXXX 100644
119
index XXXXXXX..XXXXXXX 100644
97
--- a/target/riscv/op_helper.c
120
--- a/target/riscv/vcrypto_helper.c
98
+++ b/target/riscv/op_helper.c
121
+++ b/target/riscv/vcrypto_helper.c
99
@@ -XXX,XX +XXX,XX @@ void helper_tlb_flush(CPURISCVState *env)
122
@@ -XXX,XX +XXX,XX @@ void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
100
}
123
/* set tail elements to 1s */
124
vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
101
}
125
}
102
126
+
103
+void helper_tlb_flush_all(CPURISCVState *env)
127
+static inline uint32_t sig0_sha256(uint32_t x)
104
+{
128
+{
105
+ CPUState *cs = env_cpu(env);
129
+ return ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3);
106
+ tlb_flush_all_cpus_synced(cs);
130
+}
107
+}
131
+
108
+
132
+static inline uint32_t sig1_sha256(uint32_t x)
109
void helper_hyp_tlb_flush(CPURISCVState *env)
133
+{
110
{
134
+ return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
111
CPUState *cs = env_cpu(env);
135
+}
112
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
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
113
index XXXXXXX..XXXXXXX 100644
365
index XXXXXXX..XXXXXXX 100644
114
--- a/target/riscv/translate.c
366
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
115
+++ b/target/riscv/translate.c
367
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
116
@@ -XXX,XX +XXX,XX @@ static bool always_true_p(DisasContext *ctx __attribute__((__unused__)))
368
@@ -XXX,XX +XXX,XX @@ static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi *a)
117
369
118
static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
370
GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, ZVKNED_EGS)
119
{
371
GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
120
- return ctx->cfg_ptr->ext_xtheadcmo;
372
+
121
+ return ctx->cfg_ptr->ext_xtheadcmo || ctx->cfg_ptr->ext_xtheadsync;
373
+/*
122
}
374
+ * Zvknh
123
375
+ */
124
#define MATERIALISE_EXT_PREDICATE(ext) \
376
+
125
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
377
+#define ZVKNH_EGS 4
126
index XXXXXXX..XXXXXXX 100644
378
+
127
--- a/target/riscv/insn_trans/trans_xthead.c.inc
379
+#define GEN_VV_UNMASKED_TRANS(NAME, CHECK, EGS) \
128
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
380
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
129
@@ -XXX,XX +XXX,XX @@
381
+ { \
130
} \
382
+ if (CHECK(s, a)) { \
131
} while (0)
383
+ uint32_t data = 0; \
132
384
+ TCGLabel *over = gen_new_label(); \
133
+#define REQUIRE_XTHEADSYNC(ctx) do { \
385
+ TCGv_i32 egs; \
134
+ if (!ctx->cfg_ptr->ext_xtheadsync) { \
386
+ \
135
+ return false; \
387
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
136
+ } \
388
+ /* save opcode for unwinding in case we throw an exception */ \
137
+} while (0)
389
+ decode_save_opc(s); \
138
+
390
+ egs = tcg_constant_i32(EGS); \
139
/* XTheadCmo */
391
+ gen_helper_egs_check(egs, cpu_env); \
140
392
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
141
static inline int priv_level(DisasContext *ctx)
393
+ } \
142
@@ -XXX,XX +XXX,XX @@ NOP_PRIVCHECK(th_icache_iva, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU)
394
+ \
143
NOP_PRIVCHECK(th_l2cache_call, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
395
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
144
NOP_PRIVCHECK(th_l2cache_ciall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
396
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
145
NOP_PRIVCHECK(th_l2cache_iall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS)
397
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
146
+
398
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
147
+/* XTheadSync */
399
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
148
+
400
+ \
149
+static bool trans_th_sfence_vmas(DisasContext *ctx, arg_th_sfence_vmas *a)
401
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1), \
150
+{
402
+ vreg_ofs(s, a->rs2), cpu_env, \
151
+ (void) a;
403
+ s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, \
152
+ REQUIRE_XTHEADSYNC(ctx);
404
+ data, gen_helper_##NAME); \
153
+
405
+ \
154
+#ifndef CONFIG_USER_ONLY
406
+ mark_vs_dirty(s); \
155
+ REQUIRE_PRIV_MS(ctx);
407
+ gen_set_label(over); \
156
+ gen_helper_tlb_flush_all(cpu_env);
408
+ return true; \
157
+ return true;
409
+ } \
158
+#else
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
+ }
159
+ return false;
465
+ return false;
160
+#endif
466
+}
161
+}
467
+
162
+
468
+static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
163
+#ifndef CONFIG_USER_ONLY
469
+{
164
+static void gen_th_sync_local(DisasContext *ctx)
470
+ if (vsha_check(s, a)) {
165
+{
471
+ uint32_t data = 0;
166
+ /*
472
+ TCGLabel *over = gen_new_label();
167
+ * Emulate out-of-order barriers with pipeline flush
473
+ TCGv_i32 egs;
168
+ * by exiting the translation block.
474
+
169
+ */
475
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
170
+ gen_set_pc_imm(ctx, ctx->pc_succ_insn);
476
+ /* save opcode for unwinding in case we throw an exception */
171
+ tcg_gen_exit_tb(NULL, 0);
477
+ decode_save_opc(s);
172
+ ctx->base.is_jmp = DISAS_NORETURN;
478
+ egs = tcg_constant_i32(ZVKNH_EGS);
173
+}
479
+ gen_helper_egs_check(egs, cpu_env);
174
+#endif
480
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
175
+
481
+ }
176
+static bool trans_th_sync(DisasContext *ctx, arg_th_sync *a)
482
+
177
+{
483
+ data = FIELD_DP32(data, VDATA, VM, a->vm);
178
+ (void) a;
484
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
179
+ REQUIRE_XTHEADSYNC(ctx);
485
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
180
+
486
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
181
+#ifndef CONFIG_USER_ONLY
487
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
182
+ REQUIRE_PRIV_MSU(ctx);
488
+
183
+
489
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
184
+ /*
490
+ vreg_ofs(s, a->rs2), cpu_env, s->cfg_ptr->vlen / 8,
185
+ * th.sync is an out-of-order barrier.
491
+ s->cfg_ptr->vlen / 8, data,
186
+ */
492
+ s->sew == MO_32 ?
187
+ gen_th_sync_local(ctx);
493
+ gen_helper_vsha2ch32_vv : gen_helper_vsha2ch64_vv);
188
+
494
+
189
+ return true;
495
+ mark_vs_dirty(s);
190
+#else
496
+ gen_set_label(over);
497
+ return true;
498
+ }
191
+ return false;
499
+ return false;
192
+#endif
193
+}
194
+
195
+static bool trans_th_sync_i(DisasContext *ctx, arg_th_sync_i *a)
196
+{
197
+ (void) a;
198
+ REQUIRE_XTHEADSYNC(ctx);
199
+
200
+#ifndef CONFIG_USER_ONLY
201
+ REQUIRE_PRIV_MSU(ctx);
202
+
203
+ /*
204
+ * th.sync.i is th.sync plus pipeline flush.
205
+ */
206
+ gen_th_sync_local(ctx);
207
+
208
+ return true;
209
+#else
210
+ return false;
211
+#endif
212
+}
213
+
214
+static bool trans_th_sync_is(DisasContext *ctx, arg_th_sync_is *a)
215
+{
216
+ /* This instruction has the same behaviour like th.sync.i. */
217
+ return trans_th_sync_i(ctx, a);
218
+}
219
+
220
+static bool trans_th_sync_s(DisasContext *ctx, arg_th_sync_s *a)
221
+{
222
+ /* This instruction has the same behaviour like th.sync. */
223
+ return trans_th_sync(ctx, a);
224
+}
500
+}
225
--
501
--
226
2.39.1
502
2.41.0
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
This patch adds support for the XTheadBs ISA extension.
3
This commit adds support for the Zvksh vector-crypto extension, which
4
The patch uses the T-Head specific decoder and translation.
4
consists of the following instructions:
5
5
6
Co-developed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
6
* vsm3me.vv
7
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
7
* vsm3c.vi
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
9
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
9
Translation functions are defined in
10
Message-Id: <20230131202013.2541053-6-christoph.muellner@vrull.eu>
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>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
22
---
13
target/riscv/cpu.h | 1 +
23
target/riscv/cpu_cfg.h | 1 +
14
target/riscv/xthead.decode | 3 +++
24
target/riscv/helper.h | 3 +
15
target/riscv/cpu.c | 2 ++
25
target/riscv/insn32.decode | 4 +
16
target/riscv/translate.c | 3 ++-
26
target/riscv/cpu.c | 6 +-
17
target/riscv/insn_trans/trans_xthead.c.inc | 15 +++++++++++++++
27
target/riscv/vcrypto_helper.c | 134 +++++++++++++++++++++++
18
5 files changed, 23 insertions(+), 1 deletion(-)
28
target/riscv/insn_trans/trans_rvvk.c.inc | 31 ++++++
19
29
6 files changed, 177 insertions(+), 2 deletions(-)
20
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
30
21
index XXXXXXX..XXXXXXX 100644
31
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
22
--- a/target/riscv/cpu.h
32
index XXXXXXX..XXXXXXX 100644
23
+++ b/target/riscv/cpu.h
33
--- a/target/riscv/cpu_cfg.h
34
+++ b/target/riscv/cpu_cfg.h
24
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
35
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
25
/* Vendor-specific custom extensions */
36
bool ext_zvkned;
26
bool ext_xtheadba;
37
bool ext_zvknha;
27
bool ext_xtheadbb;
38
bool ext_zvknhb;
28
+ bool ext_xtheadbs;
39
+ bool ext_zvksh;
29
bool ext_xtheadcmo;
40
bool ext_zmmul;
30
bool ext_xtheadsync;
41
bool ext_zvfbfmin;
31
bool ext_XVentanaCondOps;
42
bool ext_zvfbfwma;
32
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
43
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
33
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/xthead.decode
45
--- a/target/riscv/helper.h
35
+++ b/target/riscv/xthead.decode
46
+++ b/target/riscv/helper.h
36
@@ -XXX,XX +XXX,XX @@ th_rev 1000001 00000 ..... 001 ..... 0001011 @r2
47
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsha2ch32_vv, void, ptr, ptr, ptr, env, i32)
37
th_revw 1001000 00000 ..... 001 ..... 0001011 @r2
48
DEF_HELPER_5(vsha2ch64_vv, void, ptr, ptr, ptr, env, i32)
38
th_tstnbz 1000000 00000 ..... 001 ..... 0001011 @r2
49
DEF_HELPER_5(vsha2cl32_vv, void, ptr, ptr, ptr, env, i32)
39
50
DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
40
+# XTheadBs
51
+
41
+th_tst 100010 ...... ..... 001 ..... 0001011 @sh6
52
+DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
42
+
53
+DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
43
# XTheadCmo
54
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
44
th_dcache_call 0000000 00001 00000 000 00000 0001011
55
index XXXXXXX..XXXXXXX 100644
45
th_dcache_ciall 0000000 00011 00000 000 00000 0001011
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
46
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
66
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
47
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/cpu.c
68
--- a/target/riscv/cpu.c
49
+++ b/target/riscv/cpu.c
69
+++ b/target/riscv/cpu.c
50
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
70
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
51
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
71
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
52
ISA_EXT_DATA_ENTRY(xtheadba, true, PRIV_VERSION_1_11_0, ext_xtheadba),
72
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
53
ISA_EXT_DATA_ENTRY(xtheadbb, true, PRIV_VERSION_1_11_0, ext_xtheadbb),
73
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
54
+ ISA_EXT_DATA_ENTRY(xtheadbs, true, PRIV_VERSION_1_11_0, ext_xtheadbs),
74
+ ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh),
55
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
75
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
56
ISA_EXT_DATA_ENTRY(xtheadsync, true, PRIV_VERSION_1_11_0, ext_xtheadsync),
76
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
57
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
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;
58
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
89
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
59
/* Vendor-specific custom extensions */
90
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
60
DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
91
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
61
DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false),
92
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
62
+ DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
93
+ DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
63
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
94
64
DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
95
DEFINE_PROP_END_OF_LIST(),
65
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
96
};
66
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
97
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
67
index XXXXXXX..XXXXXXX 100644
98
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/translate.c
99
--- a/target/riscv/vcrypto_helper.c
69
+++ b/target/riscv/translate.c
100
+++ b/target/riscv/vcrypto_helper.c
70
@@ -XXX,XX +XXX,XX @@ static bool always_true_p(DisasContext *ctx __attribute__((__unused__)))
101
@@ -XXX,XX +XXX,XX @@ void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
71
static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
102
vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
72
{
103
env->vstart = 0;
73
return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
74
- ctx->cfg_ptr->ext_xtheadcmo || ctx->cfg_ptr->ext_xtheadsync;
75
+ ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
76
+ ctx->cfg_ptr->ext_xtheadsync;
77
}
104
}
78
105
+
79
#define MATERIALISE_EXT_PREDICATE(ext) \
106
+static inline uint32_t p1(uint32_t x)
80
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
107
+{
81
index XXXXXXX..XXXXXXX 100644
108
+ return x ^ rol32(x, 15) ^ rol32(x, 23);
82
--- a/target/riscv/insn_trans/trans_xthead.c.inc
109
+}
83
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
110
+
84
@@ -XXX,XX +XXX,XX @@
111
+static inline uint32_t zvksh_w(uint32_t m16, uint32_t m9, uint32_t m3,
85
} \
112
+ uint32_t m13, uint32_t m6)
86
} while (0)
113
+{
87
114
+ return p1(m16 ^ m9 ^ rol32(m3, 15)) ^ rol32(m13, 7) ^ m6;
88
+#define REQUIRE_XTHEADBS(ctx) do { \
115
+}
89
+ if (!ctx->cfg_ptr->ext_xtheadbs) { \
116
+
90
+ return false; \
117
+void HELPER(vsm3me_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
91
+ } \
118
+ CPURISCVState *env, uint32_t desc)
92
+} while (0)
119
+{
93
+
120
+ uint32_t esz = memop_size(FIELD_EX64(env->vtype, VTYPE, VSEW));
94
#define REQUIRE_XTHEADCMO(ctx) do { \
121
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
95
if (!ctx->cfg_ptr->ext_xtheadcmo) { \
122
+ uint32_t vta = vext_vta(desc);
96
return false; \
123
+ uint32_t *vd = vd_vptr;
97
@@ -XXX,XX +XXX,XX @@ static bool trans_th_tstnbz(DisasContext *ctx, arg_th_tstnbz *a)
124
+ uint32_t *vs1 = vs1_vptr;
98
return gen_unary(ctx, a, EXT_ZERO, gen_th_tstnbz);
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;
99
}
246
}
100
247
+
101
+/* XTheadBs */
248
+/*
102
+
249
+ * Zvksh
103
+/* th.tst is an alternate encoding for bexti (from Zbs) */
250
+ */
104
+static bool trans_th_tst(DisasContext *ctx, arg_th_tst *a)
251
+
105
+{
252
+#define ZVKSH_EGS 8
106
+ REQUIRE_XTHEADBS(ctx);
253
+
107
+ return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bext);
254
+static inline bool vsm3_check(DisasContext *s, arg_rmrr *a)
108
+}
255
+{
109
+
256
+ int egw_bytes = ZVKSH_EGS << s->sew;
110
/* XTheadCmo */
257
+ int mult = 1 << MAX(s->lmul, 0);
111
258
+ return s->cfg_ptr->ext_zvksh == true &&
112
static inline int priv_level(DisasContext *ctx)
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)
113
--
278
--
114
2.39.1
279
2.41.0
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
This patch adds support for the XTheadBa ISA extension.
3
This commit adds support for the Zvkg vector-crypto extension, which
4
The patch uses the T-Head specific decoder and translation.
4
consists of the following instructions:
5
5
6
Co-developed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
6
* vgmul.vv
7
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
7
* vghsh.vv
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
9
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
9
Translation functions are defined in
10
Message-Id: <20230131202013.2541053-4-christoph.muellner@vrull.eu>
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>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
23
---
13
target/riscv/cpu.h | 1 +
24
target/riscv/cpu_cfg.h | 1 +
14
target/riscv/xthead.decode | 22 ++++++++++++
25
target/riscv/helper.h | 3 +
15
target/riscv/cpu.c | 2 ++
26
target/riscv/insn32.decode | 4 ++
16
target/riscv/translate.c | 3 +-
27
target/riscv/cpu.c | 6 +-
17
target/riscv/insn_trans/trans_xthead.c.inc | 39 ++++++++++++++++++++++
28
target/riscv/vcrypto_helper.c | 72 ++++++++++++++++++++++++
18
5 files changed, 66 insertions(+), 1 deletion(-)
29
target/riscv/insn_trans/trans_rvvk.c.inc | 30 ++++++++++
19
30
6 files changed, 114 insertions(+), 2 deletions(-)
20
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
31
21
index XXXXXXX..XXXXXXX 100644
32
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
22
--- a/target/riscv/cpu.h
33
index XXXXXXX..XXXXXXX 100644
23
+++ b/target/riscv/cpu.h
34
--- a/target/riscv/cpu_cfg.h
35
+++ b/target/riscv/cpu_cfg.h
24
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
36
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
25
uint64_t mimpid;
37
bool ext_zve64d;
26
38
bool ext_zvbb;
27
/* Vendor-specific custom extensions */
39
bool ext_zvbc;
28
+ bool ext_xtheadba;
40
+ bool ext_zvkg;
29
bool ext_xtheadcmo;
41
bool ext_zvkned;
30
bool ext_xtheadsync;
42
bool ext_zvknha;
31
bool ext_XVentanaCondOps;
43
bool ext_zvknhb;
32
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
44
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
33
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/xthead.decode
46
--- a/target/riscv/helper.h
35
+++ b/target/riscv/xthead.decode
47
+++ b/target/riscv/helper.h
36
@@ -XXX,XX +XXX,XX @@
48
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
37
# Translation routines for the instructions of the XThead* ISA extensions
49
38
#
50
DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
39
# Copyright (c) 2022 Christoph Muellner, christoph.muellner@vrull.eu
51
DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
40
+# Dr. Philipp Tomsich, philipp.tomsich@vrull.eu
52
+
41
#
53
+DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
42
# SPDX-License-Identifier: LGPL-2.1-or-later
54
+DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
43
#
55
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
44
@@ -XXX,XX +XXX,XX @@
56
index XXXXXXX..XXXXXXX 100644
45
# https://github.com/T-head-Semi/thead-extension-spec/releases/latest
57
--- a/target/riscv/insn32.decode
46
58
+++ b/target/riscv/insn32.decode
47
# Fields:
59
@@ -XXX,XX +XXX,XX @@ vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
48
+%rd 7:5
60
# *** Zvksh vector crypto extension ***
49
%rs1 15:5
61
vsm3me_vv 100000 1 ..... ..... 010 ..... 1110111 @r_vm_1
50
%rs2 20:5
62
vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
51
63
+
52
+# Argument sets
64
+# *** Zvkg vector crypto extension ***
53
+&r rd rs1 rs2 !extern
65
+vghsh_vv 101100 1 ..... ..... 010 ..... 1110111 @r_vm_1
54
+
66
+vgmul_vv 101000 1 ..... 10001 010 ..... 1110111 @r2_vm_1
55
# Formats
56
@sfence_vm ....... ..... ..... ... ..... ....... %rs1
57
@rs2_s ....... ..... ..... ... ..... ....... %rs2 %rs1
58
+@r ....... ..... ..... ... ..... ....... &r %rs2 %rs1 %rd
59
+
60
+# XTheadBa
61
+# Instead of defining a new encoding, we simply use the decoder to
62
+# extract the imm[0:1] field and dispatch to separate translation
63
+# functions (mirroring the `sh[123]add` instructions from Zba and
64
+# the regular RVI `add` instruction.
65
+#
66
+# The only difference between sh[123]add and addsl is that the shift
67
+# is applied to rs1 (for addsl) instead of rs2 (for sh[123]add).
68
+#
69
+# Note that shift-by-0 is a valid operation according to the manual.
70
+# This will be equivalent to a regular add.
71
+add 0000000 ..... ..... 001 ..... 0001011 @r
72
+th_addsl1 0000001 ..... ..... 001 ..... 0001011 @r
73
+th_addsl2 0000010 ..... ..... 001 ..... 0001011 @r
74
+th_addsl3 0000011 ..... ..... 001 ..... 0001011 @r
75
76
# XTheadCmo
77
th_dcache_call 0000000 00001 00000 000 00000 0001011
78
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
67
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
79
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
80
--- a/target/riscv/cpu.c
69
--- a/target/riscv/cpu.c
81
+++ b/target/riscv/cpu.c
70
+++ b/target/riscv/cpu.c
82
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
71
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
83
ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
72
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
84
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
73
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
85
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
74
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
86
+ ISA_EXT_DATA_ENTRY(xtheadba, true, PRIV_VERSION_1_11_0, ext_xtheadba),
75
+ ISA_EXT_DATA_ENTRY(zvkg, PRIV_VERSION_1_12_0, ext_zvkg),
87
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
76
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
88
ISA_EXT_DATA_ENTRY(xtheadsync, true, PRIV_VERSION_1_11_0, ext_xtheadsync),
77
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
89
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
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[] = {
90
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
91
DEFINE_PROP_BOOL("zmmul", RISCVCPU, cfg.ext_zmmul, false),
91
/* Vector cryptography extensions */
92
92
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
93
/* Vendor-specific custom extensions */
93
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
94
+ DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
94
+ DEFINE_PROP_BOOL("x-zvkg", RISCVCPU, cfg.ext_zvkg, false),
95
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
95
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
96
DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
96
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
97
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
97
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
98
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
98
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
99
index XXXXXXX..XXXXXXX 100644
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/riscv/translate.c
100
--- a/target/riscv/vcrypto_helper.c
101
+++ b/target/riscv/translate.c
101
+++ b/target/riscv/vcrypto_helper.c
102
@@ -XXX,XX +XXX,XX @@ static bool always_true_p(DisasContext *ctx __attribute__((__unused__)))
102
@@ -XXX,XX +XXX,XX @@ void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
103
103
vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
104
static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
104
env->vstart = 0;
105
{
106
- return ctx->cfg_ptr->ext_xtheadcmo || ctx->cfg_ptr->ext_xtheadsync;
107
+ return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadcmo ||
108
+ ctx->cfg_ptr->ext_xtheadsync;
109
}
105
}
110
106
+
111
#define MATERIALISE_EXT_PREDICATE(ext) \
107
+void HELPER(vghsh_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
112
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
108
+ CPURISCVState *env, uint32_t desc)
113
index XXXXXXX..XXXXXXX 100644
109
+{
114
--- a/target/riscv/insn_trans/trans_xthead.c.inc
110
+ uint64_t *vd = vd_vptr;
115
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
111
+ uint64_t *vs1 = vs1_vptr;
116
@@ -XXX,XX +XXX,XX @@
112
+ uint64_t *vs2 = vs2_vptr;
117
* this program. If not, see <http://www.gnu.org/licenses/>.
113
+ uint32_t vta = vext_vta(desc);
118
*/
114
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
119
115
+
120
+#define REQUIRE_XTHEADBA(ctx) do { \
116
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
121
+ if (!ctx->cfg_ptr->ext_xtheadba) { \
117
+ uint64_t Y[2] = {vd[i * 2 + 0], vd[i * 2 + 1]};
122
+ return false; \
118
+ uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
123
+ } \
119
+ uint64_t X[2] = {vs1[i * 2 + 0], vs1[i * 2 + 1]};
124
+} while (0)
120
+ uint64_t Z[2] = {0, 0};
125
+
121
+
126
#define REQUIRE_XTHEADCMO(ctx) do { \
122
+ uint64_t S[2] = {brev8(Y[0] ^ X[0]), brev8(Y[1] ^ X[1])};
127
if (!ctx->cfg_ptr->ext_xtheadcmo) { \
123
+
128
return false; \
124
+ for (int j = 0; j < 128; j++) {
129
@@ -XXX,XX +XXX,XX @@
125
+ if ((S[j / 64] >> (j % 64)) & 1) {
130
} \
126
+ Z[0] ^= H[0];
131
} while (0)
127
+ Z[1] ^= H[1];
132
128
+ }
133
+/* XTheadBa */
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)
134
+
186
+
135
+/*
187
+/*
136
+ * th.addsl is similar to sh[123]add (from Zba), but not an
188
+ * Zvkg
137
+ * alternative encoding: while sh[123] applies the shift to rs1,
138
+ * th.addsl shifts rs2.
139
+ */
189
+ */
140
+
190
+
141
+#define GEN_TH_ADDSL(SHAMT) \
191
+#define ZVKG_EGS 4
142
+static void gen_th_addsl##SHAMT(TCGv ret, TCGv arg1, TCGv arg2) \
192
+
143
+{ \
193
+static bool vgmul_check(DisasContext *s, arg_rmr *a)
144
+ TCGv t = tcg_temp_new(); \
194
+{
145
+ tcg_gen_shli_tl(t, arg2, SHAMT); \
195
+ int egw_bytes = ZVKG_EGS << s->sew;
146
+ tcg_gen_add_tl(ret, t, arg1); \
196
+ return s->cfg_ptr->ext_zvkg == true &&
147
+ tcg_temp_free(t); \
197
+ vext_check_isa_ill(s) &&
148
+}
198
+ require_rvv(s) &&
149
+
199
+ MAXSZ(s) >= egw_bytes &&
150
+GEN_TH_ADDSL(1)
200
+ vext_check_ss(s, a->rd, a->rs2, a->vm) &&
151
+GEN_TH_ADDSL(2)
201
+ s->sew == MO_32;
152
+GEN_TH_ADDSL(3)
202
+}
153
+
203
+
154
+#define GEN_TRANS_TH_ADDSL(SHAMT) \
204
+GEN_V_UNMASKED_TRANS(vgmul_vv, vgmul_check, ZVKG_EGS)
155
+static bool trans_th_addsl##SHAMT(DisasContext *ctx, \
205
+
156
+ arg_th_addsl##SHAMT * a) \
206
+static bool vghsh_check(DisasContext *s, arg_rmrr *a)
157
+{ \
207
+{
158
+ REQUIRE_XTHEADBA(ctx); \
208
+ int egw_bytes = ZVKG_EGS << s->sew;
159
+ return gen_arith(ctx, a, EXT_NONE, gen_th_addsl##SHAMT, NULL); \
209
+ return s->cfg_ptr->ext_zvkg == true &&
160
+}
210
+ opivv_check(s, a) &&
161
+
211
+ MAXSZ(s) >= egw_bytes &&
162
+GEN_TRANS_TH_ADDSL(1)
212
+ s->sew == MO_32;
163
+GEN_TRANS_TH_ADDSL(2)
213
+}
164
+GEN_TRANS_TH_ADDSL(3)
214
+
165
+
215
+GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
166
/* XTheadCmo */
167
168
static inline int priv_level(DisasContext *ctx)
169
--
216
--
170
2.39.1
217
2.41.0
diff view generated by jsdifflib
1
From: Anup Patel <apatel@ventanamicro.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
We should call decode_save_opc() for all relevant instructions which
3
Allows sharing of sm4_subword between different targets.
4
can potentially generate a virtual instruction fault or a guest page
5
fault because generating transformed instruction upon guest page fault
6
expects opcode to be available. Without this, hypervisor will see
7
transformed instruction as zero in htinst CSR for guest MMIO emulation
8
which makes MMIO emulation in hypervisor slow and also breaks nested
9
virtualization.
10
4
11
Fixes: a9814e3e08d2 ("target/riscv: Minimize the calls to decode_save_opc")
5
Signed-off-by: Max Chou <max.chou@sifive.com>
12
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
6
Reviewed-by: Frank Chang <frank.chang@sifive.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-Id: <20230120125950.2246378-5-apatel@ventanamicro.com>
8
Signed-off-by: Max Chou <max.chou@sifive.com>
9
Message-ID: <20230711165917.2629866-14-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_rva.c.inc | 10 +++++++---
12
include/crypto/sm4.h | 8 ++++++++
18
target/riscv/insn_trans/trans_rvd.c.inc | 2 ++
13
target/arm/tcg/crypto_helper.c | 10 ++--------
19
target/riscv/insn_trans/trans_rvf.c.inc | 2 ++
14
2 files changed, 10 insertions(+), 8 deletions(-)
20
target/riscv/insn_trans/trans_rvh.c.inc | 3 +++
21
target/riscv/insn_trans/trans_rvi.c.inc | 2 ++
22
target/riscv/insn_trans/trans_rvzfh.c.inc | 2 ++
23
target/riscv/insn_trans/trans_svinval.c.inc | 3 +++
24
7 files changed, 21 insertions(+), 3 deletions(-)
25
15
26
diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
16
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
27
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/insn_trans/trans_rva.c.inc
18
--- a/include/crypto/sm4.h
29
+++ b/target/riscv/insn_trans/trans_rva.c.inc
19
+++ b/include/crypto/sm4.h
30
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
31
21
32
static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
22
extern const uint8_t sm4_sbox[256];
33
{
23
34
- TCGv src1 = get_address(ctx, a->rs1, 0);
24
+static inline uint32_t sm4_subword(uint32_t word)
35
+ TCGv src1;
25
+{
36
26
+ return sm4_sbox[word & 0xff] |
37
+ decode_save_opc(ctx);
27
+ sm4_sbox[(word >> 8) & 0xff] << 8 |
38
+ src1 = get_address(ctx, a->rs1, 0);
28
+ sm4_sbox[(word >> 16) & 0xff] << 16 |
39
if (a->rl) {
29
+ sm4_sbox[(word >> 24) & 0xff] << 24;
40
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
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);
41
}
60
}
42
@@ -XXX,XX +XXX,XX @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
43
TCGLabel *l1 = gen_new_label();
44
TCGLabel *l2 = gen_new_label();
45
46
+ decode_save_opc(ctx);
47
src1 = get_address(ctx, a->rs1, 0);
48
tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
49
50
@@ -XXX,XX +XXX,XX @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
51
MemOp mop)
52
{
53
TCGv dest = dest_gpr(ctx, a->rd);
54
- TCGv src1 = get_address(ctx, a->rs1, 0);
55
- TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
56
+ TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE);
57
58
+ decode_save_opc(ctx);
59
+ src1 = get_address(ctx, a->rs1, 0);
60
func(dest, src1, src2, ctx->mem_idx, mop);
61
62
gen_set_gpr(ctx, a->rd, dest);
63
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/riscv/insn_trans/trans_rvd.c.inc
66
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
67
@@ -XXX,XX +XXX,XX @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
68
REQUIRE_FPU;
69
REQUIRE_EXT(ctx, RVD);
70
71
+ decode_save_opc(ctx);
72
addr = get_address(ctx, a->rs1, a->imm);
73
tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEUQ);
74
75
@@ -XXX,XX +XXX,XX @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
76
REQUIRE_FPU;
77
REQUIRE_EXT(ctx, RVD);
78
79
+ decode_save_opc(ctx);
80
addr = get_address(ctx, a->rs1, a->imm);
81
tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUQ);
82
return true;
83
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
84
index XXXXXXX..XXXXXXX 100644
85
--- a/target/riscv/insn_trans/trans_rvf.c.inc
86
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
87
@@ -XXX,XX +XXX,XX @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
88
REQUIRE_FPU;
89
REQUIRE_EXT(ctx, RVF);
90
91
+ decode_save_opc(ctx);
92
addr = get_address(ctx, a->rs1, a->imm);
93
dest = cpu_fpr[a->rd];
94
tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL);
95
@@ -XXX,XX +XXX,XX @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
96
REQUIRE_FPU;
97
REQUIRE_EXT(ctx, RVF);
98
99
+ decode_save_opc(ctx);
100
addr = get_address(ctx, a->rs1, a->imm);
101
tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
102
return true;
103
diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc
104
index XXXXXXX..XXXXXXX 100644
105
--- a/target/riscv/insn_trans/trans_rvh.c.inc
106
+++ b/target/riscv/insn_trans/trans_rvh.c.inc
107
@@ -XXX,XX +XXX,XX @@ static bool do_hlv(DisasContext *ctx, arg_r2 *a, MemOp mop)
108
#ifdef CONFIG_USER_ONLY
109
return false;
110
#else
111
+ decode_save_opc(ctx);
112
if (check_access(ctx)) {
113
TCGv dest = dest_gpr(ctx, a->rd);
114
TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
115
@@ -XXX,XX +XXX,XX @@ static bool do_hsv(DisasContext *ctx, arg_r2_s *a, MemOp mop)
116
#ifdef CONFIG_USER_ONLY
117
return false;
118
#else
119
+ decode_save_opc(ctx);
120
if (check_access(ctx)) {
121
TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
122
TCGv data = get_gpr(ctx, a->rs2, EXT_NONE);
123
@@ -XXX,XX +XXX,XX @@ static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a)
124
static bool do_hlvx(DisasContext *ctx, arg_r2 *a,
125
void (*func)(TCGv, TCGv_env, TCGv))
126
{
127
+ decode_save_opc(ctx);
128
if (check_access(ctx)) {
129
TCGv dest = dest_gpr(ctx, a->rd);
130
TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
131
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/riscv/insn_trans/trans_rvi.c.inc
134
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
135
@@ -XXX,XX +XXX,XX @@ static bool gen_load_i128(DisasContext *ctx, arg_lb *a, MemOp memop)
136
137
static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
138
{
139
+ decode_save_opc(ctx);
140
if (get_xl(ctx) == MXL_RV128) {
141
return gen_load_i128(ctx, a, memop);
142
} else {
143
@@ -XXX,XX +XXX,XX @@ static bool gen_store_i128(DisasContext *ctx, arg_sb *a, MemOp memop)
144
145
static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop)
146
{
147
+ decode_save_opc(ctx);
148
if (get_xl(ctx) == MXL_RV128) {
149
return gen_store_i128(ctx, a, memop);
150
} else {
151
diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc
152
index XXXXXXX..XXXXXXX 100644
153
--- a/target/riscv/insn_trans/trans_rvzfh.c.inc
154
+++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
155
@@ -XXX,XX +XXX,XX @@ static bool trans_flh(DisasContext *ctx, arg_flh *a)
156
REQUIRE_FPU;
157
REQUIRE_ZFH_OR_ZFHMIN(ctx);
158
159
+ decode_save_opc(ctx);
160
t0 = get_gpr(ctx, a->rs1, EXT_NONE);
161
if (a->imm) {
162
TCGv temp = temp_new(ctx);
163
@@ -XXX,XX +XXX,XX @@ static bool trans_fsh(DisasContext *ctx, arg_fsh *a)
164
REQUIRE_FPU;
165
REQUIRE_ZFH_OR_ZFHMIN(ctx);
166
167
+ decode_save_opc(ctx);
168
t0 = get_gpr(ctx, a->rs1, EXT_NONE);
169
if (a->imm) {
170
TCGv temp = tcg_temp_new();
171
diff --git a/target/riscv/insn_trans/trans_svinval.c.inc b/target/riscv/insn_trans/trans_svinval.c.inc
172
index XXXXXXX..XXXXXXX 100644
173
--- a/target/riscv/insn_trans/trans_svinval.c.inc
174
+++ b/target/riscv/insn_trans/trans_svinval.c.inc
175
@@ -XXX,XX +XXX,XX @@ static bool trans_sinval_vma(DisasContext *ctx, arg_sinval_vma *a)
176
/* Do the same as sfence.vma currently */
177
REQUIRE_EXT(ctx, RVS);
178
#ifndef CONFIG_USER_ONLY
179
+ decode_save_opc(ctx);
180
gen_helper_tlb_flush(cpu_env);
181
return true;
182
#endif
183
@@ -XXX,XX +XXX,XX @@ static bool trans_hinval_vvma(DisasContext *ctx, arg_hinval_vvma *a)
184
/* Do the same as hfence.vvma currently */
185
REQUIRE_EXT(ctx, RVH);
186
#ifndef CONFIG_USER_ONLY
187
+ decode_save_opc(ctx);
188
gen_helper_hyp_tlb_flush(cpu_env);
189
return true;
190
#endif
191
@@ -XXX,XX +XXX,XX @@ static bool trans_hinval_gvma(DisasContext *ctx, arg_hinval_gvma *a)
192
/* Do the same as hfence.gvma currently */
193
REQUIRE_EXT(ctx, RVH);
194
#ifndef CONFIG_USER_ONLY
195
+ decode_save_opc(ctx);
196
gen_helper_hyp_gvma_tlb_flush(cpu_env);
197
return true;
198
#endif
199
--
61
--
200
2.39.1
62
2.41.0
diff view generated by jsdifflib
New patch
1
From: Max Chou <max.chou@sifive.com>
1
2
3
Adds sm4_ck constant for use in sm4 cryptography across different targets.
4
5
Signed-off-by: Max Chou <max.chou@sifive.com>
6
Reviewed-by: Frank Chang <frank.chang@sifive.com>
7
Signed-off-by: Max Chou <max.chou@sifive.com>
8
Message-ID: <20230711165917.2629866-15-max.chou@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
include/crypto/sm4.h | 1 +
12
crypto/sm4.c | 10 ++++++++++
13
2 files changed, 11 insertions(+)
14
15
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/crypto/sm4.h
18
+++ b/include/crypto/sm4.h
19
@@ -XXX,XX +XXX,XX @@
20
#define QEMU_SM4_H
21
22
extern const uint8_t sm4_sbox[256];
23
+extern const uint32_t sm4_ck[32];
24
25
static inline uint32_t sm4_subword(uint32_t word)
26
{
27
diff --git a/crypto/sm4.c b/crypto/sm4.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/crypto/sm4.c
30
+++ b/crypto/sm4.c
31
@@ -XXX,XX +XXX,XX @@ uint8_t const sm4_sbox[] = {
32
0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
33
};
34
35
+uint32_t const sm4_ck[] = {
36
+ 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
37
+ 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
38
+ 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
39
+ 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
40
+ 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
41
+ 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
42
+ 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
43
+ 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
44
+};
45
--
46
2.41.0
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
This patch adds support for the T-Head FMemIdx instructions.
3
This commit adds support for the Zvksed vector-crypto extension, which
4
The patch uses the T-Head specific decoder and translation.
4
consists of the following instructions:
5
5
6
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
6
* vsm4k.vi
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
* vsm4r.[vv,vs]
8
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
8
9
Message-Id: <20230131202013.2541053-11-christoph.muellner@vrull.eu>
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Signed-off-by: Max Chou <max.chou@sifive.com>
14
Reviewed-by: Frank Chang <frank.chang@sifive.com>
15
[lawrence.hunter@codethink.co.uk: Moved SM4 functions from
16
crypto_helper.c to vcrypto_helper.c]
17
[nazar.kazakov@codethink.co.uk: Added alignment checks, refactored code to
18
use macros, and minor style changes]
19
Signed-off-by: Max Chou <max.chou@sifive.com>
20
Message-ID: <20230711165917.2629866-16-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
22
---
12
target/riscv/cpu.h | 1 +
23
target/riscv/cpu_cfg.h | 1 +
13
target/riscv/xthead.decode | 10 ++
24
target/riscv/helper.h | 4 +
14
target/riscv/cpu.c | 2 +
25
target/riscv/insn32.decode | 5 +
15
target/riscv/translate.c | 3 +-
26
target/riscv/cpu.c | 5 +-
16
target/riscv/insn_trans/trans_xthead.c.inc | 108 +++++++++++++++++++++
27
target/riscv/vcrypto_helper.c | 127 +++++++++++++++++++++++
17
5 files changed, 123 insertions(+), 1 deletion(-)
28
target/riscv/insn_trans/trans_rvvk.c.inc | 43 ++++++++
18
29
6 files changed, 184 insertions(+), 1 deletion(-)
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
30
20
index XXXXXXX..XXXXXXX 100644
31
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
21
--- a/target/riscv/cpu.h
32
index XXXXXXX..XXXXXXX 100644
22
+++ b/target/riscv/cpu.h
33
--- a/target/riscv/cpu_cfg.h
34
+++ b/target/riscv/cpu_cfg.h
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
35
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
24
bool ext_xtheadbs;
36
bool ext_zvkned;
25
bool ext_xtheadcmo;
37
bool ext_zvknha;
26
bool ext_xtheadcondmov;
38
bool ext_zvknhb;
27
+ bool ext_xtheadfmemidx;
39
+ bool ext_zvksed;
28
bool ext_xtheadmac;
40
bool ext_zvksh;
29
bool ext_xtheadmemidx;
41
bool ext_zmmul;
30
bool ext_xtheadmempair;
42
bool ext_zvfbfmin;
31
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
43
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
32
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/xthead.decode
45
--- a/target/riscv/helper.h
34
+++ b/target/riscv/xthead.decode
46
+++ b/target/riscv/helper.h
35
@@ -XXX,XX +XXX,XX @@ th_l2cache_iall 0000000 10110 00000 000 00000 0001011
47
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
36
th_mveqz 0100000 ..... ..... 001 ..... 0001011 @r
48
37
th_mvnez 0100001 ..... ..... 001 ..... 0001011 @r
49
DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
38
50
DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
39
+# XTheadFMemIdx
51
+
40
+th_flrd 01100 .. ..... ..... 110 ..... 0001011 @th_memidx
52
+DEF_HELPER_5(vsm4k_vi, void, ptr, ptr, i32, env, i32)
41
+th_flrw 01000 .. ..... ..... 110 ..... 0001011 @th_memidx
53
+DEF_HELPER_4(vsm4r_vv, void, ptr, ptr, env, i32)
42
+th_flurd 01110 .. ..... ..... 110 ..... 0001011 @th_memidx
54
+DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32)
43
+th_flurw 01010 .. ..... ..... 110 ..... 0001011 @th_memidx
55
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
44
+th_fsrd 01100 .. ..... ..... 111 ..... 0001011 @th_memidx
56
index XXXXXXX..XXXXXXX 100644
45
+th_fsrw 01000 .. ..... ..... 111 ..... 0001011 @th_memidx
57
--- a/target/riscv/insn32.decode
46
+th_fsurd 01110 .. ..... ..... 111 ..... 0001011 @th_memidx
58
+++ b/target/riscv/insn32.decode
47
+th_fsurw 01010 .. ..... ..... 111 ..... 0001011 @th_memidx
59
@@ -XXX,XX +XXX,XX @@ vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
48
+
60
# *** Zvkg vector crypto extension ***
49
# XTheadMac
61
vghsh_vv 101100 1 ..... ..... 010 ..... 1110111 @r_vm_1
50
th_mula 00100 00 ..... ..... 001 ..... 0001011 @r
62
vgmul_vv 101000 1 ..... 10001 010 ..... 1110111 @r2_vm_1
51
th_mulah 00101 00 ..... ..... 001 ..... 0001011 @r
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
52
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
68
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
53
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
54
--- a/target/riscv/cpu.c
70
--- a/target/riscv/cpu.c
55
+++ b/target/riscv/cpu.c
71
+++ b/target/riscv/cpu.c
56
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
72
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
57
ISA_EXT_DATA_ENTRY(xtheadbs, true, PRIV_VERSION_1_11_0, ext_xtheadbs),
73
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
58
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
74
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
59
ISA_EXT_DATA_ENTRY(xtheadcondmov, true, PRIV_VERSION_1_11_0, ext_xtheadcondmov),
75
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
60
+ ISA_EXT_DATA_ENTRY(xtheadfmemidx, true, PRIV_VERSION_1_11_0, ext_xtheadfmemidx),
76
+ ISA_EXT_DATA_ENTRY(zvksed, PRIV_VERSION_1_12_0, ext_zvksed),
61
ISA_EXT_DATA_ENTRY(xtheadmac, true, PRIV_VERSION_1_11_0, ext_xtheadmac),
77
ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh),
62
ISA_EXT_DATA_ENTRY(xtheadmemidx, true, PRIV_VERSION_1_11_0, ext_xtheadmemidx),
78
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
63
ISA_EXT_DATA_ENTRY(xtheadmempair, true, PRIV_VERSION_1_11_0, ext_xtheadmempair),
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;
64
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
90
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
65
DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
91
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
66
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
92
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
67
DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
93
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
68
+ DEFINE_PROP_BOOL("xtheadfmemidx", RISCVCPU, cfg.ext_xtheadfmemidx, false),
94
+ DEFINE_PROP_BOOL("x-zvksed", RISCVCPU, cfg.ext_zvksed, false),
69
DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false),
95
DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
70
DEFINE_PROP_BOOL("xtheadmemidx", RISCVCPU, cfg.ext_xtheadmemidx, false),
96
71
DEFINE_PROP_BOOL("xtheadmempair", RISCVCPU, cfg.ext_xtheadmempair, false),
97
DEFINE_PROP_END_OF_LIST(),
72
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
98
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
73
index XXXXXXX..XXXXXXX 100644
99
index XXXXXXX..XXXXXXX 100644
74
--- a/target/riscv/translate.c
100
--- a/target/riscv/vcrypto_helper.c
75
+++ b/target/riscv/translate.c
101
+++ b/target/riscv/vcrypto_helper.c
76
@@ -XXX,XX +XXX,XX @@ static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
102
@@ -XXX,XX +XXX,XX @@
77
{
103
#include "cpu.h"
78
return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
104
#include "crypto/aes.h"
79
ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
105
#include "crypto/aes-round.h"
80
- ctx->cfg_ptr->ext_xtheadcondmov || ctx->cfg_ptr->ext_xtheadmac ||
106
+#include "crypto/sm4.h"
81
+ ctx->cfg_ptr->ext_xtheadcondmov ||
107
#include "exec/memop.h"
82
+ ctx->cfg_ptr->ext_xtheadfmemidx || ctx->cfg_ptr->ext_xtheadmac ||
108
#include "exec/exec-all.h"
83
ctx->cfg_ptr->ext_xtheadmemidx || ctx->cfg_ptr->ext_xtheadmempair ||
109
#include "exec/helper-proto.h"
84
ctx->cfg_ptr->ext_xtheadsync;
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;
85
}
113
}
86
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
114
+
87
index XXXXXXX..XXXXXXX 100644
115
+void HELPER(vsm4k_vi)(void *vd, void *vs2, uint32_t uimm5, CPURISCVState *env,
88
--- a/target/riscv/insn_trans/trans_xthead.c.inc
116
+ uint32_t desc)
89
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
117
+{
90
@@ -XXX,XX +XXX,XX @@
118
+ const uint32_t egs = 4;
91
} \
119
+ uint32_t rnd = uimm5 & 0x7;
92
} while (0)
120
+ uint32_t group_start = env->vstart / egs;
93
121
+ uint32_t group_end = env->vl / egs;
94
+#define REQUIRE_XTHEADFMEMIDX(ctx) do { \
122
+ uint32_t esz = sizeof(uint32_t);
95
+ if (!ctx->cfg_ptr->ext_xtheadfmemidx) { \
123
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
96
+ return false; \
124
+
97
+ } \
125
+ for (uint32_t i = group_start; i < group_end; ++i) {
98
+} while (0)
126
+ uint32_t vstart = i * egs;
99
+
127
+ uint32_t vend = (i + 1) * egs;
100
#define REQUIRE_XTHEADMAC(ctx) do { \
128
+ uint32_t rk[4] = {0};
101
if (!ctx->cfg_ptr->ext_xtheadmac) { \
129
+ uint32_t tmp[8] = {0};
102
return false; \
130
+
103
@@ -XXX,XX +XXX,XX @@ static bool trans_th_mvnez(DisasContext *ctx, arg_th_mveqz *a)
131
+ for (uint32_t j = vstart; j < vend; ++j) {
104
return gen_th_condmove(ctx, a, TCG_COND_NE);
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)
105
}
245
}
106
246
107
+/* XTheadFMem */
247
GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
108
+
248
+
109
+/*
249
+/*
110
+ * Load 64-bit float from indexed address.
250
+ * Zvksed
111
+ * If !zext_offs, then address is rs1 + (rs2 << imm2).
112
+ * If zext_offs, then address is rs1 + (zext(rs2[31:0]) << imm2).
113
+ */
251
+ */
114
+static bool gen_fload_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop,
252
+
115
+ bool zext_offs)
253
+#define ZVKSED_EGS 4
116
+{
254
+
117
+ TCGv_i64 rd = cpu_fpr[a->rd];
255
+static bool zvksed_check(DisasContext *s)
118
+ TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs);
256
+{
119
+
257
+ int egw_bytes = ZVKSED_EGS << s->sew;
120
+ tcg_gen_qemu_ld_i64(rd, addr, ctx->mem_idx, memop);
258
+ return s->cfg_ptr->ext_zvksed == true &&
121
+ if ((memop & MO_SIZE) == MO_32) {
259
+ require_rvv(s) &&
122
+ gen_nanbox_s(rd, rd);
260
+ vext_check_isa_ill(s) &&
123
+ }
261
+ MAXSZ(s) >= egw_bytes &&
124
+
262
+ s->sew == MO_32;
125
+ mark_fs_dirty(ctx);
263
+}
126
+ return true;
264
+
127
+}
265
+static bool vsm4k_vi_check(DisasContext *s, arg_rmrr *a)
128
+
266
+{
129
+/*
267
+ return zvksed_check(s) &&
130
+ * Store 64-bit float to indexed address.
268
+ require_align(a->rd, s->lmul) &&
131
+ * If !zext_offs, then address is rs1 + (rs2 << imm2).
269
+ require_align(a->rs2, s->lmul);
132
+ * If zext_offs, then address is rs1 + (zext(rs2[31:0]) << imm2).
270
+}
133
+ */
271
+
134
+static bool gen_fstore_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop,
272
+GEN_VI_UNMASKED_TRANS(vsm4k_vi, vsm4k_vi_check, ZVKSED_EGS)
135
+ bool zext_offs)
273
+
136
+{
274
+static bool vsm4r_vv_check(DisasContext *s, arg_rmr *a)
137
+ TCGv_i64 rd = cpu_fpr[a->rd];
275
+{
138
+ TCGv addr = get_th_address_indexed(ctx, a->rs1, a->rs2, a->imm2, zext_offs);
276
+ return zvksed_check(s) &&
139
+
277
+ require_align(a->rd, s->lmul) &&
140
+ tcg_gen_qemu_st_i64(rd, addr, ctx->mem_idx, memop);
278
+ require_align(a->rs2, s->lmul);
141
+
279
+}
142
+ return true;
280
+
143
+}
281
+GEN_V_UNMASKED_TRANS(vsm4r_vv, vsm4r_vv_check, ZVKSED_EGS)
144
+
282
+
145
+static bool trans_th_flrd(DisasContext *ctx, arg_th_memidx *a)
283
+static bool vsm4r_vs_check(DisasContext *s, arg_rmr *a)
146
+{
284
+{
147
+ REQUIRE_XTHEADFMEMIDX(ctx);
285
+ return zvksed_check(s) &&
148
+ REQUIRE_FPU;
286
+ !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) &&
149
+ REQUIRE_EXT(ctx, RVD);
287
+ require_align(a->rd, s->lmul);
150
+ return gen_fload_idx(ctx, a, MO_TEUQ, false);
288
+}
151
+}
289
+
152
+
290
+GEN_V_UNMASKED_TRANS(vsm4r_vs, vsm4r_vs_check, ZVKSED_EGS)
153
+static bool trans_th_flrw(DisasContext *ctx, arg_th_memidx *a)
154
+{
155
+ REQUIRE_XTHEADFMEMIDX(ctx);
156
+ REQUIRE_FPU;
157
+ REQUIRE_EXT(ctx, RVF);
158
+ return gen_fload_idx(ctx, a, MO_TEUL, false);
159
+}
160
+
161
+static bool trans_th_flurd(DisasContext *ctx, arg_th_memidx *a)
162
+{
163
+ REQUIRE_XTHEADFMEMIDX(ctx);
164
+ REQUIRE_FPU;
165
+ REQUIRE_EXT(ctx, RVD);
166
+ return gen_fload_idx(ctx, a, MO_TEUQ, true);
167
+}
168
+
169
+static bool trans_th_flurw(DisasContext *ctx, arg_th_memidx *a)
170
+{
171
+ REQUIRE_XTHEADFMEMIDX(ctx);
172
+ REQUIRE_FPU;
173
+ REQUIRE_EXT(ctx, RVF);
174
+ return gen_fload_idx(ctx, a, MO_TEUL, true);
175
+}
176
+
177
+static bool trans_th_fsrd(DisasContext *ctx, arg_th_memidx *a)
178
+{
179
+ REQUIRE_XTHEADFMEMIDX(ctx);
180
+ REQUIRE_FPU;
181
+ REQUIRE_EXT(ctx, RVD);
182
+ return gen_fstore_idx(ctx, a, MO_TEUQ, false);
183
+}
184
+
185
+static bool trans_th_fsrw(DisasContext *ctx, arg_th_memidx *a)
186
+{
187
+ REQUIRE_XTHEADFMEMIDX(ctx);
188
+ REQUIRE_FPU;
189
+ REQUIRE_EXT(ctx, RVF);
190
+ return gen_fstore_idx(ctx, a, MO_TEUL, false);
191
+}
192
+
193
+static bool trans_th_fsurd(DisasContext *ctx, arg_th_memidx *a)
194
+{
195
+ REQUIRE_XTHEADFMEMIDX(ctx);
196
+ REQUIRE_FPU;
197
+ REQUIRE_EXT(ctx, RVD);
198
+ return gen_fstore_idx(ctx, a, MO_TEUQ, true);
199
+}
200
+
201
+static bool trans_th_fsurw(DisasContext *ctx, arg_th_memidx *a)
202
+{
203
+ REQUIRE_XTHEADFMEMIDX(ctx);
204
+ REQUIRE_FPU;
205
+ REQUIRE_EXT(ctx, RVF);
206
+ return gen_fstore_idx(ctx, a, MO_TEUL, true);
207
+}
208
+
209
/* XTheadMac */
210
211
static bool gen_th_mac(DisasContext *ctx, arg_r *a,
212
--
291
--
213
2.39.1
292
2.41.0
diff view generated by jsdifflib
1
From: Anup Patel <apatel@ventanamicro.com>
1
From: Rob Bradford <rbradford@rivosinc.com>
2
2
3
The htimedelta[h] CSR has impact on the VS timer comparison so we
3
These are WARL fields - zero out the bits for unavailable counters and
4
should call riscv_timer_write_timecmp() whenever htimedelta changes.
4
special case the TM bit in mcountinhibit which is hardwired to zero.
5
This patch achieves this by modifying the value written so that any use
6
of the field will see the correctly masked bits.
5
7
6
Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp suppor")
8
Tested by modifying OpenSBI to write max value to these CSRs and upon
7
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
9
subsequent read the appropriate number of bits for number of PMUs is
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
enabled and the TM bit is zero in mcountinhibit.
9
Message-Id: <20230120125950.2246378-2-apatel@ventanamicro.com>
11
12
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Atish Patra <atishp@rivosinc.com>
15
Message-ID: <20230802124906.24197-1-rbradford@rivosinc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
17
---
12
target/riscv/csr.c | 16 ++++++++++++++++
18
target/riscv/csr.c | 11 +++++++++--
13
1 file changed, 16 insertions(+)
19
1 file changed, 9 insertions(+), 2 deletions(-)
14
20
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
21
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/csr.c
23
--- a/target/riscv/csr.c
18
+++ b/target/riscv/csr.c
24
+++ b/target/riscv/csr.c
19
@@ -XXX,XX +XXX,XX @@ static RISCVException read_htimedelta(CPURISCVState *env, int csrno,
25
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
20
static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
26
{
27
int cidx;
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,
21
target_ulong val)
40
target_ulong val)
22
{
41
{
42
- env->mcounteren = val;
23
+ RISCVCPU *cpu = env_archcpu(env);
43
+ RISCVCPU *cpu = env_archcpu(env);
24
+
44
+
25
if (!env->rdtime_fn) {
45
+ /* WARL register - disable unavailable counters */
26
return RISCV_EXCP_ILLEGAL_INST;
46
+ env->mcounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
27
}
47
+ COUNTEREN_IR);
28
@@ -XXX,XX +XXX,XX @@ static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
29
} else {
30
env->htimedelta = val;
31
}
32
+
33
+ if (cpu->cfg.ext_sstc && env->rdtime_fn) {
34
+ riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
35
+ env->htimedelta, MIP_VSTIP);
36
+ }
37
+
38
return RISCV_EXCP_NONE;
48
return RISCV_EXCP_NONE;
39
}
49
}
40
50
41
@@ -XXX,XX +XXX,XX @@ static RISCVException read_htimedeltah(CPURISCVState *env, int csrno,
42
static RISCVException write_htimedeltah(CPURISCVState *env, int csrno,
43
target_ulong val)
44
{
45
+ RISCVCPU *cpu = env_archcpu(env);
46
+
47
if (!env->rdtime_fn) {
48
return RISCV_EXCP_ILLEGAL_INST;
49
}
50
51
env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
52
+
53
+ if (cpu->cfg.ext_sstc && env->rdtime_fn) {
54
+ riscv_timer_write_timecmp(cpu, env->vstimer, env->vstimecmp,
55
+ env->htimedelta, MIP_VSTIP);
56
+ }
57
+
58
return RISCV_EXCP_NONE;
59
}
60
61
--
51
--
62
2.39.1
52
2.41.0
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
This patch adds support for the XTheadBb ISA extension.
3
RVA23 Profiles states:
4
The patch uses the T-Head specific decoder and translation.
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.
5
9
6
Co-developed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
10
The chapter 4 of the unprivileged spec introduces the Zihintntl extension
7
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
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>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
27
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
28
Signed-off-by: Jason Chien <jason.chien@sifive.com>
10
Message-Id: <20230131202013.2541053-5-christoph.muellner@vrull.eu>
29
Message-ID: <20230726074049.19505-2-jason.chien@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
31
---
13
target/riscv/cpu.h | 1 +
32
target/riscv/cpu_cfg.h | 1 +
14
target/riscv/xthead.decode | 20 ++++
33
target/riscv/cpu.c | 2 ++
15
target/riscv/cpu.c | 2 +
34
2 files changed, 3 insertions(+)
16
target/riscv/translate.c | 4 +-
17
target/riscv/insn_trans/trans_xthead.c.inc | 124 +++++++++++++++++++++
18
5 files changed, 149 insertions(+), 2 deletions(-)
19
35
20
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
36
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
21
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/cpu.h
38
--- a/target/riscv/cpu_cfg.h
23
+++ b/target/riscv/cpu.h
39
+++ b/target/riscv/cpu_cfg.h
24
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
40
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
25
41
bool ext_icbom;
26
/* Vendor-specific custom extensions */
42
bool ext_icboz;
27
bool ext_xtheadba;
43
bool ext_zicond;
28
+ bool ext_xtheadbb;
44
+ bool ext_zihintntl;
29
bool ext_xtheadcmo;
45
bool ext_zihintpause;
30
bool ext_xtheadsync;
46
bool ext_smstateen;
31
bool ext_XVentanaCondOps;
47
bool ext_sstc;
32
diff --git a/target/riscv/xthead.decode b/target/riscv/xthead.decode
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/xthead.decode
35
+++ b/target/riscv/xthead.decode
36
@@ -XXX,XX +XXX,XX @@
37
%rd 7:5
38
%rs1 15:5
39
%rs2 20:5
40
+%sh5 20:5
41
+%sh6 20:6
42
43
# Argument sets
44
&r rd rs1 rs2 !extern
45
+&r2 rd rs1 !extern
46
+&shift shamt rs1 rd !extern
47
+&th_bfext msb lsb rs1 rd
48
49
# Formats
50
@sfence_vm ....... ..... ..... ... ..... ....... %rs1
51
@rs2_s ....... ..... ..... ... ..... ....... %rs2 %rs1
52
@r ....... ..... ..... ... ..... ....... &r %rs2 %rs1 %rd
53
+@r2 ....... ..... ..... ... ..... ....... &r2 %rs1 %rd
54
+@th_bfext msb:6 lsb:6 ..... ... ..... ....... &th_bfext %rs1 %rd
55
+@sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd
56
+@sh6 ...... ...... ..... ... ..... ....... &shift shamt=%sh6 %rs1 %rd
57
58
# XTheadBa
59
# Instead of defining a new encoding, we simply use the decoder to
60
@@ -XXX,XX +XXX,XX @@ th_addsl1 0000001 ..... ..... 001 ..... 0001011 @r
61
th_addsl2 0000010 ..... ..... 001 ..... 0001011 @r
62
th_addsl3 0000011 ..... ..... 001 ..... 0001011 @r
63
64
+# XTheadBb
65
+th_ext ...... ...... ..... 010 ..... 0001011 @th_bfext
66
+th_extu ...... ...... ..... 011 ..... 0001011 @th_bfext
67
+th_ff0 1000010 00000 ..... 001 ..... 0001011 @r2
68
+th_ff1 1000011 00000 ..... 001 ..... 0001011 @r2
69
+th_srri 000100 ...... ..... 001 ..... 0001011 @sh6
70
+th_srriw 0001010 ..... ..... 001 ..... 0001011 @sh5
71
+th_rev 1000001 00000 ..... 001 ..... 0001011 @r2
72
+th_revw 1001000 00000 ..... 001 ..... 0001011 @r2
73
+th_tstnbz 1000000 00000 ..... 001 ..... 0001011 @r2
74
+
75
# XTheadCmo
76
th_dcache_call 0000000 00001 00000 000 00000 0001011
77
th_dcache_ciall 0000000 00011 00000 000 00000 0001011
78
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
48
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
79
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
80
--- a/target/riscv/cpu.c
50
--- a/target/riscv/cpu.c
81
+++ b/target/riscv/cpu.c
51
+++ b/target/riscv/cpu.c
82
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
52
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
83
ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
53
ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
84
ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
54
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
85
ISA_EXT_DATA_ENTRY(xtheadba, true, PRIV_VERSION_1_11_0, ext_xtheadba),
55
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
86
+ ISA_EXT_DATA_ENTRY(xtheadbb, true, PRIV_VERSION_1_11_0, ext_xtheadbb),
56
+ ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl),
87
ISA_EXT_DATA_ENTRY(xtheadcmo, true, PRIV_VERSION_1_11_0, ext_xtheadcmo),
57
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
88
ISA_EXT_DATA_ENTRY(xtheadsync, true, PRIV_VERSION_1_11_0, ext_xtheadsync),
58
ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
89
ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
59
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
90
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
60
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
91
61
DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
92
/* Vendor-specific custom extensions */
62
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
93
DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
63
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
94
+ DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false),
64
+ DEFINE_PROP_BOOL("Zihintntl", RISCVCPU, cfg.ext_zihintntl, true),
95
DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
65
DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
96
DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
66
DEFINE_PROP_BOOL("Zawrs", RISCVCPU, cfg.ext_zawrs, true),
97
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
67
DEFINE_PROP_BOOL("Zfa", RISCVCPU, cfg.ext_zfa, true),
98
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/riscv/translate.c
101
+++ b/target/riscv/translate.c
102
@@ -XXX,XX +XXX,XX @@ static bool always_true_p(DisasContext *ctx __attribute__((__unused__)))
103
104
static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
105
{
106
- return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadcmo ||
107
- ctx->cfg_ptr->ext_xtheadsync;
108
+ return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
109
+ ctx->cfg_ptr->ext_xtheadcmo || ctx->cfg_ptr->ext_xtheadsync;
110
}
111
112
#define MATERIALISE_EXT_PREDICATE(ext) \
113
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/riscv/insn_trans/trans_xthead.c.inc
116
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
117
@@ -XXX,XX +XXX,XX @@
118
} \
119
} while (0)
120
121
+#define REQUIRE_XTHEADBB(ctx) do { \
122
+ if (!ctx->cfg_ptr->ext_xtheadbb) { \
123
+ return false; \
124
+ } \
125
+} while (0)
126
+
127
#define REQUIRE_XTHEADCMO(ctx) do { \
128
if (!ctx->cfg_ptr->ext_xtheadcmo) { \
129
return false; \
130
@@ -XXX,XX +XXX,XX @@ GEN_TRANS_TH_ADDSL(1)
131
GEN_TRANS_TH_ADDSL(2)
132
GEN_TRANS_TH_ADDSL(3)
133
134
+/* XTheadBb */
135
+
136
+/* th.srri is an alternate encoding for rori (from Zbb) */
137
+static bool trans_th_srri(DisasContext *ctx, arg_th_srri * a)
138
+{
139
+ REQUIRE_XTHEADBB(ctx);
140
+ return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE,
141
+ tcg_gen_rotri_tl, gen_roriw, NULL);
142
+}
143
+
144
+/* th.srriw is an alternate encoding for roriw (from Zbb) */
145
+static bool trans_th_srriw(DisasContext *ctx, arg_th_srriw *a)
146
+{
147
+ REQUIRE_XTHEADBB(ctx);
148
+ REQUIRE_64BIT(ctx);
149
+ ctx->ol = MXL_RV32;
150
+ return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_roriw, NULL);
151
+}
152
+
153
+/* th.ext and th.extu perform signed/unsigned bitfield extraction */
154
+static bool gen_th_bfextract(DisasContext *ctx, arg_th_bfext *a,
155
+ void (*f)(TCGv, TCGv, unsigned int, unsigned int))
156
+{
157
+ TCGv dest = dest_gpr(ctx, a->rd);
158
+ TCGv source = get_gpr(ctx, a->rs1, EXT_ZERO);
159
+
160
+ if (a->lsb <= a->msb) {
161
+ f(dest, source, a->lsb, a->msb - a->lsb + 1);
162
+ gen_set_gpr(ctx, a->rd, dest);
163
+ }
164
+ return true;
165
+}
166
+
167
+static bool trans_th_ext(DisasContext *ctx, arg_th_ext *a)
168
+{
169
+ REQUIRE_XTHEADBB(ctx);
170
+ return gen_th_bfextract(ctx, a, tcg_gen_sextract_tl);
171
+}
172
+
173
+static bool trans_th_extu(DisasContext *ctx, arg_th_extu *a)
174
+{
175
+ REQUIRE_XTHEADBB(ctx);
176
+ return gen_th_bfextract(ctx, a, tcg_gen_extract_tl);
177
+}
178
+
179
+/* th.ff0: find first zero (clz on an inverted input) */
180
+static bool gen_th_ff0(DisasContext *ctx, arg_th_ff0 *a, DisasExtend ext)
181
+{
182
+ TCGv dest = dest_gpr(ctx, a->rd);
183
+ TCGv src1 = get_gpr(ctx, a->rs1, ext);
184
+
185
+ int olen = get_olen(ctx);
186
+ TCGv t = tcg_temp_new();
187
+
188
+ tcg_gen_not_tl(t, src1);
189
+ if (olen != TARGET_LONG_BITS) {
190
+ if (olen == 32) {
191
+ gen_clzw(dest, t);
192
+ } else {
193
+ g_assert_not_reached();
194
+ }
195
+ } else {
196
+ gen_clz(dest, t);
197
+ }
198
+
199
+ tcg_temp_free(t);
200
+ gen_set_gpr(ctx, a->rd, dest);
201
+
202
+ return true;
203
+}
204
+
205
+static bool trans_th_ff0(DisasContext *ctx, arg_th_ff0 *a)
206
+{
207
+ REQUIRE_XTHEADBB(ctx);
208
+ return gen_th_ff0(ctx, a, EXT_NONE);
209
+}
210
+
211
+/* th.ff1 is an alternate encoding for clz (from Zbb) */
212
+static bool trans_th_ff1(DisasContext *ctx, arg_th_ff1 *a)
213
+{
214
+ REQUIRE_XTHEADBB(ctx);
215
+ return gen_unary_per_ol(ctx, a, EXT_NONE, gen_clz, gen_clzw);
216
+}
217
+
218
+static void gen_th_revw(TCGv ret, TCGv arg1)
219
+{
220
+ tcg_gen_bswap32_tl(ret, arg1, TCG_BSWAP_OS);
221
+}
222
+
223
+/* th.rev is an alternate encoding for the RV64 rev8 (from Zbb) */
224
+static bool trans_th_rev(DisasContext *ctx, arg_th_rev *a)
225
+{
226
+ REQUIRE_XTHEADBB(ctx);
227
+
228
+ return gen_unary_per_ol(ctx, a, EXT_NONE, tcg_gen_bswap_tl, gen_th_revw);
229
+}
230
+
231
+/* th.revw is a sign-extended byte-swap of the lower word */
232
+static bool trans_th_revw(DisasContext *ctx, arg_th_revw *a)
233
+{
234
+ REQUIRE_XTHEADBB(ctx);
235
+ REQUIRE_64BIT(ctx);
236
+ return gen_unary(ctx, a, EXT_NONE, gen_th_revw);
237
+}
238
+
239
+/* th.tstnbz is equivalent to an orc.b (from Zbb) with inverted result */
240
+static void gen_th_tstnbz(TCGv ret, TCGv source1)
241
+{
242
+ gen_orc_b(ret, source1);
243
+ tcg_gen_not_tl(ret, ret);
244
+}
245
+
246
+static bool trans_th_tstnbz(DisasContext *ctx, arg_th_tstnbz *a)
247
+{
248
+ REQUIRE_XTHEADBB(ctx);
249
+ return gen_unary(ctx, a, EXT_ZERO, gen_th_tstnbz);
250
+}
251
+
252
/* XTheadCmo */
253
254
static inline int priv_level(DisasContext *ctx)
255
--
68
--
256
2.39.1
69
2.41.0
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
2
3
Commit a47842d ("riscv: Add support for the Zfa extension") implemented the zfa extension.
4
However, it has some typos for fleq.d and fltq.d. Both of them misused the fltq.s
5
helper function.
6
7
Fixes: a47842d ("riscv: Add support for the Zfa extension")
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
11
Message-ID: <20230728003906.768-1-zhiwei_liu@linux.alibaba.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/insn_trans/trans_rvzfa.c.inc | 4 ++--
15
1 file changed, 2 insertions(+), 2 deletions(-)
16
17
diff --git a/target/riscv/insn_trans/trans_rvzfa.c.inc b/target/riscv/insn_trans/trans_rvzfa.c.inc
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/insn_trans/trans_rvzfa.c.inc
20
+++ b/target/riscv/insn_trans/trans_rvzfa.c.inc
21
@@ -XXX,XX +XXX,XX @@ bool trans_fleq_d(DisasContext *ctx, arg_fleq_d *a)
22
TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
23
TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
24
25
- gen_helper_fltq_s(dest, cpu_env, src1, src2);
26
+ gen_helper_fleq_d(dest, cpu_env, src1, src2);
27
gen_set_gpr(ctx, a->rd, dest);
28
return true;
29
}
30
@@ -XXX,XX +XXX,XX @@ bool trans_fltq_d(DisasContext *ctx, arg_fltq_d *a)
31
TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
32
TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
33
34
- gen_helper_fltq_s(dest, cpu_env, src1, src2);
35
+ gen_helper_fltq_d(dest, cpu_env, src1, src2);
36
gen_set_gpr(ctx, a->rd, dest);
37
return true;
38
}
39
--
40
2.41.0
diff view generated by jsdifflib
New patch
1
From: Jason Chien <jason.chien@sifive.com>
1
2
3
When writing the upper mtime, we should keep the original lower mtime
4
whose value is given by cpu_riscv_read_rtc() instead of
5
cpu_riscv_read_rtc_raw(). The same logic applies to writes to lower mtime.
6
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20230728082502.26439-1-jason.chien@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
hw/intc/riscv_aclint.c | 5 +++--
13
1 file changed, 3 insertions(+), 2 deletions(-)
14
15
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/riscv_aclint.c
18
+++ b/hw/intc/riscv_aclint.c
19
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
20
return;
21
} else if (addr == mtimer->time_base || addr == mtimer->time_base + 4) {
22
uint64_t rtc_r = cpu_riscv_read_rtc_raw(mtimer->timebase_freq);
23
+ uint64_t rtc = cpu_riscv_read_rtc(mtimer);
24
25
if (addr == mtimer->time_base) {
26
if (size == 4) {
27
/* time_lo for RV32/RV64 */
28
- mtimer->time_delta = ((rtc_r & ~0xFFFFFFFFULL) | value) - rtc_r;
29
+ mtimer->time_delta = ((rtc & ~0xFFFFFFFFULL) | value) - rtc_r;
30
} else {
31
/* time for RV64 */
32
mtimer->time_delta = value - rtc_r;
33
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
34
} else {
35
if (size == 4) {
36
/* time_hi for RV32/RV64 */
37
- mtimer->time_delta = (value << 32 | (rtc_r & 0xFFFFFFFF)) - rtc_r;
38
+ mtimer->time_delta = (value << 32 | (rtc & 0xFFFFFFFF)) - rtc_r;
39
} else {
40
qemu_log_mask(LOG_GUEST_ERROR,
41
"aclint-mtimer: invalid time_hi write: %08x",
42
--
43
2.41.0
diff view generated by jsdifflib
1
From: Vladimir Isaev <vladimir.isaev@syntacore.com>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
According to spec, ctzw should work with 32-bit register, not 64.
3
The variables whose values are given by cpu_riscv_read_rtc() should be named
4
"rtc". The variables whose value are given by cpu_riscv_read_rtc_raw()
5
should be named "rtc_r".
4
6
5
For example, previous implementation returns 33 for (1<<33) input
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
6
when the new one returns 32.
7
8
Signed-off-by: Vladimir Isaev <vladimir.isaev@syntacore.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-ID: <20230728082502.26439-2-jason.chien@sifive.com>
11
Message-Id: <20230204082312.43557-1-vladimir.isaev@syntacore.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/insn_trans/trans_rvb.c.inc | 1 +
12
hw/intc/riscv_aclint.c | 6 +++---
15
1 file changed, 1 insertion(+)
13
1 file changed, 3 insertions(+), 3 deletions(-)
16
14
17
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
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/insn_trans/trans_rvb.c.inc
17
--- a/hw/intc/riscv_aclint.c
20
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
18
+++ b/hw/intc/riscv_aclint.c
21
@@ -XXX,XX +XXX,XX @@ static bool trans_ctzw(DisasContext *ctx, arg_ctzw *a)
19
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
22
{
20
uint64_t next;
23
REQUIRE_64BIT(ctx);
21
uint64_t diff;
24
REQUIRE_ZBB(ctx);
22
25
+ ctx->ol = MXL_RV32;
23
- uint64_t rtc_r = cpu_riscv_read_rtc(mtimer);
26
return gen_unary(ctx, a, EXT_ZERO, gen_ctzw);
24
+ uint64_t rtc = cpu_riscv_read_rtc(mtimer);
27
}
25
26
/* Compute the relative hartid w.r.t the socket */
27
hartid = hartid - mtimer->hartid_base;
28
29
mtimer->timecmp[hartid] = value;
30
- if (mtimer->timecmp[hartid] <= rtc_r) {
31
+ if (mtimer->timecmp[hartid] <= rtc) {
32
/*
33
* If we're setting an MTIMECMP value in the "past",
34
* immediately raise the timer interrupt
35
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
36
37
/* otherwise, set up the future timer interrupt */
38
qemu_irq_lower(mtimer->timer_irqs[hartid]);
39
- diff = mtimer->timecmp[hartid] - rtc_r;
40
+ diff = mtimer->timecmp[hartid] - rtc;
41
/* back to ns (note args switched in muldiv64) */
42
uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
28
43
29
--
44
--
30
2.39.1
45
2.41.0
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
2
3
The XThead* extensions are maintained by T-Head and VRULL.
3
We should not use types dependend on host arch for target_ucontext.
4
Adding a point of contact from both companies.
4
This bug is found when run rv32 applications.
5
5
6
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
6
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Message-Id: <20230131202013.2541053-15-christoph.muellner@vrull.eu>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-ID: <20230811055438.1945-1-zhiwei_liu@linux.alibaba.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
---
12
MAINTAINERS | 8 ++++++++
13
linux-user/riscv/signal.c | 4 ++--
13
1 file changed, 8 insertions(+)
14
1 file changed, 2 insertions(+), 2 deletions(-)
14
15
15
diff --git a/MAINTAINERS b/MAINTAINERS
16
diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/MAINTAINERS
18
--- a/linux-user/riscv/signal.c
18
+++ b/MAINTAINERS
19
+++ b/linux-user/riscv/signal.c
19
@@ -XXX,XX +XXX,XX @@ F: include/hw/riscv/
20
@@ -XXX,XX +XXX,XX @@ struct target_sigcontext {
20
F: linux-user/host/riscv32/
21
}; /* cf. riscv-linux:arch/riscv/include/uapi/asm/ptrace.h */
21
F: linux-user/host/riscv64/
22
22
23
struct target_ucontext {
23
+RISC-V XThead* extensions
24
- unsigned long uc_flags;
24
+M: Christoph Muellner <christoph.muellner@vrull.eu>
25
- struct target_ucontext *uc_link;
25
+M: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
26
+ abi_ulong uc_flags;
26
+L: qemu-riscv@nongnu.org
27
+ abi_ptr uc_link;
27
+S: Supported
28
target_stack_t uc_stack;
28
+F: target/riscv/insn_trans/trans_xthead.c.inc
29
target_sigset_t uc_sigmask;
29
+F: target/riscv/xthead*.decode
30
uint8_t __unused[1024 / 8 - sizeof(target_sigset_t)];
30
+
31
RISC-V XVentanaCondOps extension
32
M: Philipp Tomsich <philipp.tomsich@vrull.eu>
33
L: qemu-riscv@nongnu.org
34
--
31
--
35
2.39.1
32
2.41.0
33
34
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
There is no need to declare an intermediate "MachineState *ms".
3
In this patch, we create the APLIC and IMSIC FDT helper functions and
4
remove M mode AIA devices when using KVM acceleration.
4
5
5
Signed-off-by: Bin Meng <bmeng@tinylab.org>
6
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Jim Shu <jim.shu@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Message-Id: <20230206085007.3618715-1-bmeng@tinylab.org>
9
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
10
Message-ID: <20230727102439.22554-2-yongxuan.wang@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
12
---
11
hw/riscv/virt.c | 6 ++----
13
hw/riscv/virt.c | 290 +++++++++++++++++++++++-------------------------
12
1 file changed, 2 insertions(+), 4 deletions(-)
14
1 file changed, 137 insertions(+), 153 deletions(-)
13
15
14
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
16
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/virt.c
18
--- a/hw/riscv/virt.c
17
+++ b/hw/riscv/virt.c
19
+++ b/hw/riscv/virt.c
18
@@ -XXX,XX +XXX,XX @@ static void virt_set_aia(Object *obj, const char *val, Error **errp)
20
@@ -XXX,XX +XXX,XX @@ static uint32_t imsic_num_bits(uint32_t count)
19
21
return ret;
20
static bool virt_get_aclint(Object *obj, Error **errp)
22
}
23
24
-static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
25
- uint32_t *phandle, uint32_t *intc_phandles,
26
- uint32_t *msi_m_phandle, uint32_t *msi_s_phandle)
27
+static void create_fdt_one_imsic(RISCVVirtState *s, hwaddr base_addr,
28
+ uint32_t *intc_phandles, uint32_t msi_phandle,
29
+ bool m_mode, uint32_t imsic_guest_bits)
21
{
30
{
22
- MachineState *ms = MACHINE(obj);
31
int cpu, socket;
23
- RISCVVirtState *s = RISCV_VIRT_MACHINE(ms);
32
char *imsic_name;
24
+ RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
33
MachineState *ms = MACHINE(s);
25
34
int socket_count = riscv_socket_count(ms);
26
return s->have_aclint;
35
- uint32_t imsic_max_hart_per_socket, imsic_guest_bits;
36
+ uint32_t imsic_max_hart_per_socket;
37
uint32_t *imsic_cells, *imsic_regs, imsic_addr, imsic_size;
38
39
- *msi_m_phandle = (*phandle)++;
40
- *msi_s_phandle = (*phandle)++;
41
imsic_cells = g_new0(uint32_t, ms->smp.cpus * 2);
42
imsic_regs = g_new0(uint32_t, socket_count * 4);
43
44
- /* M-level IMSIC node */
45
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
46
imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
47
- imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
48
+ imsic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
49
}
50
- imsic_max_hart_per_socket = 0;
51
- for (socket = 0; socket < socket_count; socket++) {
52
- imsic_addr = memmap[VIRT_IMSIC_M].base +
53
- socket * VIRT_IMSIC_GROUP_MAX_SIZE;
54
- imsic_size = IMSIC_HART_SIZE(0) * s->soc[socket].num_harts;
55
- imsic_regs[socket * 4 + 0] = 0;
56
- imsic_regs[socket * 4 + 1] = cpu_to_be32(imsic_addr);
57
- imsic_regs[socket * 4 + 2] = 0;
58
- imsic_regs[socket * 4 + 3] = cpu_to_be32(imsic_size);
59
- if (imsic_max_hart_per_socket < s->soc[socket].num_harts) {
60
- imsic_max_hart_per_socket = s->soc[socket].num_harts;
61
- }
62
- }
63
- imsic_name = g_strdup_printf("/soc/imsics@%lx",
64
- (unsigned long)memmap[VIRT_IMSIC_M].base);
65
- qemu_fdt_add_subnode(ms->fdt, imsic_name);
66
- qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
67
- "riscv,imsics");
68
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
69
- FDT_IMSIC_INT_CELLS);
70
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
71
- NULL, 0);
72
- qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
73
- NULL, 0);
74
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
75
- imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
76
- qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
77
- socket_count * sizeof(uint32_t) * 4);
78
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
79
- VIRT_IRQCHIP_NUM_MSIS);
80
- if (socket_count > 1) {
81
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
82
- imsic_num_bits(imsic_max_hart_per_socket));
83
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
84
- imsic_num_bits(socket_count));
85
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
86
- IMSIC_MMIO_GROUP_MIN_SHIFT);
87
- }
88
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_m_phandle);
89
-
90
- g_free(imsic_name);
91
92
- /* S-level IMSIC node */
93
- for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
94
- imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
95
- imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
96
- }
97
- imsic_guest_bits = imsic_num_bits(s->aia_guests + 1);
98
imsic_max_hart_per_socket = 0;
99
for (socket = 0; socket < socket_count; socket++) {
100
- imsic_addr = memmap[VIRT_IMSIC_S].base +
101
- socket * VIRT_IMSIC_GROUP_MAX_SIZE;
102
+ imsic_addr = base_addr + socket * VIRT_IMSIC_GROUP_MAX_SIZE;
103
imsic_size = IMSIC_HART_SIZE(imsic_guest_bits) *
104
s->soc[socket].num_harts;
105
imsic_regs[socket * 4 + 0] = 0;
106
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
107
imsic_max_hart_per_socket = s->soc[socket].num_harts;
108
}
109
}
110
- imsic_name = g_strdup_printf("/soc/imsics@%lx",
111
- (unsigned long)memmap[VIRT_IMSIC_S].base);
112
+
113
+ imsic_name = g_strdup_printf("/soc/imsics@%lx", (unsigned long)base_addr);
114
qemu_fdt_add_subnode(ms->fdt, imsic_name);
115
- qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
116
- "riscv,imsics");
117
+ qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible", "riscv,imsics");
118
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
119
- FDT_IMSIC_INT_CELLS);
120
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
121
- NULL, 0);
122
- qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
123
- NULL, 0);
124
+ FDT_IMSIC_INT_CELLS);
125
+ qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller", NULL, 0);
126
+ qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller", NULL, 0);
127
qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
128
- imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
129
+ imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
130
qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
131
- socket_count * sizeof(uint32_t) * 4);
132
+ socket_count * sizeof(uint32_t) * 4);
133
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
134
- VIRT_IRQCHIP_NUM_MSIS);
135
+ VIRT_IRQCHIP_NUM_MSIS);
136
+
137
if (imsic_guest_bits) {
138
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,guest-index-bits",
139
- imsic_guest_bits);
140
+ imsic_guest_bits);
141
}
142
+
143
if (socket_count > 1) {
144
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
145
- imsic_num_bits(imsic_max_hart_per_socket));
146
+ imsic_num_bits(imsic_max_hart_per_socket));
147
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
148
- imsic_num_bits(socket_count));
149
+ imsic_num_bits(socket_count));
150
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
151
- IMSIC_MMIO_GROUP_MIN_SHIFT);
152
+ IMSIC_MMIO_GROUP_MIN_SHIFT);
153
}
154
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_s_phandle);
155
- g_free(imsic_name);
156
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", msi_phandle);
157
158
+ g_free(imsic_name);
159
g_free(imsic_regs);
160
g_free(imsic_cells);
27
}
161
}
28
162
29
static void virt_set_aclint(Object *obj, bool value, Error **errp)
163
-static void create_fdt_socket_aplic(RISCVVirtState *s,
164
- const MemMapEntry *memmap, int socket,
165
- uint32_t msi_m_phandle,
166
- uint32_t msi_s_phandle,
167
- uint32_t *phandle,
168
- uint32_t *intc_phandles,
169
- uint32_t *aplic_phandles)
170
+static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
171
+ uint32_t *phandle, uint32_t *intc_phandles,
172
+ uint32_t *msi_m_phandle, uint32_t *msi_s_phandle)
173
+{
174
+ *msi_m_phandle = (*phandle)++;
175
+ *msi_s_phandle = (*phandle)++;
176
+
177
+ if (!kvm_enabled()) {
178
+ /* M-level IMSIC node */
179
+ create_fdt_one_imsic(s, memmap[VIRT_IMSIC_M].base, intc_phandles,
180
+ *msi_m_phandle, true, 0);
181
+ }
182
+
183
+ /* S-level IMSIC node */
184
+ create_fdt_one_imsic(s, memmap[VIRT_IMSIC_S].base, intc_phandles,
185
+ *msi_s_phandle, false,
186
+ imsic_num_bits(s->aia_guests + 1));
187
+
188
+}
189
+
190
+static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
191
+ unsigned long aplic_addr, uint32_t aplic_size,
192
+ uint32_t msi_phandle,
193
+ uint32_t *intc_phandles,
194
+ uint32_t aplic_phandle,
195
+ uint32_t aplic_child_phandle,
196
+ bool m_mode)
30
{
197
{
31
- MachineState *ms = MACHINE(obj);
198
int cpu;
32
- RISCVVirtState *s = RISCV_VIRT_MACHINE(ms);
199
char *aplic_name;
33
+ RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
200
uint32_t *aplic_cells;
34
201
- unsigned long aplic_addr;
35
s->have_aclint = value;
202
MachineState *ms = MACHINE(s);
203
- uint32_t aplic_m_phandle, aplic_s_phandle;
204
205
- aplic_m_phandle = (*phandle)++;
206
- aplic_s_phandle = (*phandle)++;
207
aplic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
208
209
- /* M-level APLIC node */
210
for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
211
aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
212
- aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
213
+ aplic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
214
}
215
- aplic_addr = memmap[VIRT_APLIC_M].base +
216
- (memmap[VIRT_APLIC_M].size * socket);
217
+
218
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
219
qemu_fdt_add_subnode(ms->fdt, aplic_name);
220
qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
221
qemu_fdt_setprop_cell(ms->fdt, aplic_name,
222
- "#interrupt-cells", FDT_APLIC_INT_CELLS);
223
+ "#interrupt-cells", FDT_APLIC_INT_CELLS);
224
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
225
+
226
if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
227
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
228
- aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2);
229
+ aplic_cells,
230
+ s->soc[socket].num_harts * sizeof(uint32_t) * 2);
231
} else {
232
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent",
233
- msi_m_phandle);
234
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent", msi_phandle);
235
}
236
+
237
qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
238
- 0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_M].size);
239
+ 0x0, aplic_addr, 0x0, aplic_size);
240
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
241
- VIRT_IRQCHIP_NUM_SOURCES);
242
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,children",
243
- aplic_s_phandle);
244
- qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate",
245
- aplic_s_phandle, 0x1, VIRT_IRQCHIP_NUM_SOURCES);
246
+ VIRT_IRQCHIP_NUM_SOURCES);
247
+
248
+ if (aplic_child_phandle) {
249
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,children",
250
+ aplic_child_phandle);
251
+ qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate",
252
+ aplic_child_phandle, 0x1,
253
+ VIRT_IRQCHIP_NUM_SOURCES);
254
+ }
255
+
256
riscv_socket_fdt_write_id(ms, aplic_name, socket);
257
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_m_phandle);
258
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_phandle);
259
+
260
g_free(aplic_name);
261
+ g_free(aplic_cells);
262
+}
263
264
- /* S-level APLIC node */
265
- for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
266
- aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
267
- aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
268
+static void create_fdt_socket_aplic(RISCVVirtState *s,
269
+ const MemMapEntry *memmap, int socket,
270
+ uint32_t msi_m_phandle,
271
+ uint32_t msi_s_phandle,
272
+ uint32_t *phandle,
273
+ uint32_t *intc_phandles,
274
+ uint32_t *aplic_phandles)
275
+{
276
+ char *aplic_name;
277
+ unsigned long aplic_addr;
278
+ MachineState *ms = MACHINE(s);
279
+ uint32_t aplic_m_phandle, aplic_s_phandle;
280
+
281
+ aplic_m_phandle = (*phandle)++;
282
+ aplic_s_phandle = (*phandle)++;
283
+
284
+ if (!kvm_enabled()) {
285
+ /* M-level APLIC node */
286
+ aplic_addr = memmap[VIRT_APLIC_M].base +
287
+ (memmap[VIRT_APLIC_M].size * socket);
288
+ create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_M].size,
289
+ msi_m_phandle, intc_phandles,
290
+ aplic_m_phandle, aplic_s_phandle,
291
+ true);
292
}
293
+
294
+ /* S-level APLIC node */
295
aplic_addr = memmap[VIRT_APLIC_S].base +
296
(memmap[VIRT_APLIC_S].size * socket);
297
+ create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_S].size,
298
+ msi_s_phandle, intc_phandles,
299
+ aplic_s_phandle, 0,
300
+ false);
301
+
302
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
303
- qemu_fdt_add_subnode(ms->fdt, aplic_name);
304
- qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
305
- qemu_fdt_setprop_cell(ms->fdt, aplic_name,
306
- "#interrupt-cells", FDT_APLIC_INT_CELLS);
307
- qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
308
- if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
309
- qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
310
- aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2);
311
- } else {
312
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent",
313
- msi_s_phandle);
314
- }
315
- qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
316
- 0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_S].size);
317
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
318
- VIRT_IRQCHIP_NUM_SOURCES);
319
- riscv_socket_fdt_write_id(ms, aplic_name, socket);
320
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_s_phandle);
321
322
if (!socket) {
323
platform_bus_add_all_fdt_nodes(ms->fdt, aplic_name,
324
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
325
326
g_free(aplic_name);
327
328
- g_free(aplic_cells);
329
aplic_phandles[socket] = aplic_s_phandle;
36
}
330
}
331
332
@@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
333
int i;
334
hwaddr addr;
335
uint32_t guest_bits;
336
- DeviceState *aplic_m;
337
- bool msimode = (aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) ? true : false;
338
+ DeviceState *aplic_s = NULL;
339
+ DeviceState *aplic_m = NULL;
340
+ bool msimode = aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
341
342
if (msimode) {
343
- /* Per-socket M-level IMSICs */
344
- addr = memmap[VIRT_IMSIC_M].base + socket * VIRT_IMSIC_GROUP_MAX_SIZE;
345
- for (i = 0; i < hart_count; i++) {
346
- riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0),
347
- base_hartid + i, true, 1,
348
- VIRT_IRQCHIP_NUM_MSIS);
349
+ if (!kvm_enabled()) {
350
+ /* Per-socket M-level IMSICs */
351
+ addr = memmap[VIRT_IMSIC_M].base +
352
+ socket * VIRT_IMSIC_GROUP_MAX_SIZE;
353
+ for (i = 0; i < hart_count; i++) {
354
+ riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0),
355
+ base_hartid + i, true, 1,
356
+ VIRT_IRQCHIP_NUM_MSIS);
357
+ }
358
}
359
360
/* Per-socket S-level IMSICs */
361
@@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
362
}
363
}
364
365
- /* Per-socket M-level APLIC */
366
- aplic_m = riscv_aplic_create(
367
- memmap[VIRT_APLIC_M].base + socket * memmap[VIRT_APLIC_M].size,
368
- memmap[VIRT_APLIC_M].size,
369
- (msimode) ? 0 : base_hartid,
370
- (msimode) ? 0 : hart_count,
371
- VIRT_IRQCHIP_NUM_SOURCES,
372
- VIRT_IRQCHIP_NUM_PRIO_BITS,
373
- msimode, true, NULL);
374
-
375
- if (aplic_m) {
376
- /* Per-socket S-level APLIC */
377
- riscv_aplic_create(
378
- memmap[VIRT_APLIC_S].base + socket * memmap[VIRT_APLIC_S].size,
379
- memmap[VIRT_APLIC_S].size,
380
- (msimode) ? 0 : base_hartid,
381
- (msimode) ? 0 : hart_count,
382
- VIRT_IRQCHIP_NUM_SOURCES,
383
- VIRT_IRQCHIP_NUM_PRIO_BITS,
384
- msimode, false, aplic_m);
385
+ if (!kvm_enabled()) {
386
+ /* Per-socket M-level APLIC */
387
+ aplic_m = riscv_aplic_create(memmap[VIRT_APLIC_M].base +
388
+ socket * memmap[VIRT_APLIC_M].size,
389
+ memmap[VIRT_APLIC_M].size,
390
+ (msimode) ? 0 : base_hartid,
391
+ (msimode) ? 0 : hart_count,
392
+ VIRT_IRQCHIP_NUM_SOURCES,
393
+ VIRT_IRQCHIP_NUM_PRIO_BITS,
394
+ msimode, true, NULL);
395
}
396
397
- return aplic_m;
398
+ /* Per-socket S-level APLIC */
399
+ aplic_s = riscv_aplic_create(memmap[VIRT_APLIC_S].base +
400
+ socket * memmap[VIRT_APLIC_S].size,
401
+ memmap[VIRT_APLIC_S].size,
402
+ (msimode) ? 0 : base_hartid,
403
+ (msimode) ? 0 : hart_count,
404
+ VIRT_IRQCHIP_NUM_SOURCES,
405
+ VIRT_IRQCHIP_NUM_PRIO_BITS,
406
+ msimode, false, aplic_m);
407
+
408
+ return kvm_enabled() ? aplic_s : aplic_m;
409
}
410
411
static void create_platform_bus(RISCVVirtState *s, DeviceState *irqchip)
37
--
412
--
38
2.39.1
413
2.41.0
diff view generated by jsdifflib
1
From: Vladimir Isaev <vladimir.isaev@syntacore.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
Character must be returned via ret[0] field (copied to a0 by KVM).
3
We check the in-kernel irqchip support when using KVM acceleration.
4
4
5
Return value should be set to 0 to indicate successful processing.
5
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
6
6
Reviewed-by: Jim Shu <jim.shu@sifive.com>
7
Signed-off-by: Vladimir Isaev <vladimir.isaev@syntacore.com>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
9
Message-Id: <20230203135155.12449-1-vladimir.isaev@syntacore.com>
9
Message-ID: <20230727102439.22554-3-yongxuan.wang@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
11
---
12
target/riscv/kvm.c | 5 +++--
12
target/riscv/kvm.c | 10 +++++++++-
13
1 file changed, 3 insertions(+), 2 deletions(-)
13
1 file changed, 9 insertions(+), 1 deletion(-)
14
14
15
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
15
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/kvm.c
17
--- a/target/riscv/kvm.c
18
+++ b/target/riscv/kvm.c
18
+++ b/target/riscv/kvm.c
19
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
19
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
20
case SBI_EXT_0_1_CONSOLE_GETCHAR:
20
21
ret = qemu_chr_fe_read_all(serial_hd(0)->be, &ch, sizeof(ch));
21
int kvm_arch_irqchip_create(KVMState *s)
22
if (ret == sizeof(ch)) {
22
{
23
- run->riscv_sbi.args[0] = ch;
23
- return 0;
24
+ run->riscv_sbi.ret[0] = ch;
24
+ if (kvm_kernel_irqchip_split()) {
25
} else {
25
+ error_report("-machine kernel_irqchip=split is not supported on RISC-V.");
26
- run->riscv_sbi.args[0] = -1;
26
+ exit(1);
27
+ run->riscv_sbi.ret[0] = -1;
27
+ }
28
}
28
+
29
+ ret = 0;
29
+ /*
30
break;
30
+ * We can create the VAIA using the newer device control API.
31
default:
31
+ */
32
qemu_log_mask(LOG_UNIMP,
32
+ return kvm_check_extension(s, KVM_CAP_DEVICE_CTRL);
33
}
34
35
int kvm_arch_process_async_events(CPUState *cs)
33
--
36
--
34
2.39.1
37
2.41.0
diff view generated by jsdifflib
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
Updates the opentitan IRQs to match the latest supported commit of
3
We create a vAIA chip by using the KVM_DEV_TYPE_RISCV_AIA and then set up
4
Opentitan from TockOS.
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
OPENTITAN_SUPPORTED_SHA := 565e4af39760a123c59a184aa2f5812a961fde47
12
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
7
13
Reviewed-by: Jim Shu <jim.shu@sifive.com>
8
Memory layout as per [1]
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
15
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
10
[1] https://github.com/lowRISC/opentitan/blob/565e4af39760a123c59a184aa2f5812a961fde47/hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
16
Message-ID: <20230727102439.22554-4-yongxuan.wang@sifive.com>
11
12
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-Id: <20230123063619.222459-1-wilfred.mallawa@opensource.wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
18
---
17
include/hw/riscv/opentitan.h | 14 +++----
19
target/riscv/kvm_riscv.h | 4 +
18
hw/riscv/opentitan.c | 80 ++++++++++++++++++------------------
20
target/riscv/kvm.c | 186 +++++++++++++++++++++++++++++++++++++++
19
2 files changed, 47 insertions(+), 47 deletions(-)
21
2 files changed, 190 insertions(+)
20
22
21
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
23
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
22
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/riscv/opentitan.h
25
--- a/target/riscv/kvm_riscv.h
24
+++ b/include/hw/riscv/opentitan.h
26
+++ b/target/riscv/kvm_riscv.h
25
@@ -XXX,XX +XXX,XX @@ enum {
27
@@ -XXX,XX +XXX,XX @@
26
IBEX_DEV_EDNO,
28
void kvm_riscv_init_user_properties(Object *cpu_obj);
27
IBEX_DEV_EDN1,
29
void kvm_riscv_reset_vcpu(RISCVCPU *cpu);
28
IBEX_DEV_ALERT_HANDLER,
30
void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level);
29
- IBEX_DEV_NMI_GEN,
31
+void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
30
+ IBEX_DEV_SRAM_CTRL,
32
+ uint64_t aia_irq_num, uint64_t aia_msi_num,
31
IBEX_DEV_OTBN,
33
+ uint64_t aplic_base, uint64_t imsic_base,
32
- IBEX_DEV_PERI,
34
+ uint64_t guest_num);
33
+ IBEX_DEV_IBEX_CFG,
34
};
35
36
enum {
37
@@ -XXX,XX +XXX,XX @@ enum {
38
IBEX_UART0_RX_BREAK_ERR_IRQ = 6,
39
IBEX_UART0_RX_TIMEOUT_IRQ = 7,
40
IBEX_UART0_RX_PARITY_ERR_IRQ = 8,
41
- IBEX_TIMER_TIMEREXPIRED0_0 = 127,
42
- IBEX_SPI_HOST0_ERR_IRQ = 134,
43
- IBEX_SPI_HOST0_SPI_EVENT_IRQ = 135,
44
- IBEX_SPI_HOST1_ERR_IRQ = 136,
45
- IBEX_SPI_HOST1_SPI_EVENT_IRQ = 137,
46
+ IBEX_TIMER_TIMEREXPIRED0_0 = 124,
47
+ IBEX_SPI_HOST0_ERR_IRQ = 131,
48
+ IBEX_SPI_HOST0_SPI_EVENT_IRQ = 132,
49
+ IBEX_SPI_HOST1_ERR_IRQ = 133,
50
+ IBEX_SPI_HOST1_SPI_EVENT_IRQ = 134,
51
};
52
35
53
#endif
36
#endif
54
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
37
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
55
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/riscv/opentitan.c
39
--- a/target/riscv/kvm.c
57
+++ b/hw/riscv/opentitan.c
40
+++ b/target/riscv/kvm.c
58
@@ -XXX,XX +XXX,XX @@
41
@@ -XXX,XX +XXX,XX @@
59
/*
42
#include "exec/address-spaces.h"
60
* This version of the OpenTitan machine currently supports
43
#include "hw/boards.h"
61
* OpenTitan RTL version:
44
#include "hw/irq.h"
62
- * <lowRISC/opentitan@d072ac505f82152678d6e04be95c72b728a347b8>
45
+#include "hw/intc/riscv_imsic.h"
63
+ * <lowRISC/opentitan@565e4af39760a123c59a184aa2f5812a961fde47>
46
#include "qemu/log.h"
64
*
47
#include "hw/loader.h"
65
* MMIO mapping as per (specified commit):
48
#include "kvm_riscv.h"
66
* lowRISC/opentitan: hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
49
@@ -XXX,XX +XXX,XX @@
67
*/
50
#include "chardev/char-fe.h"
68
static const MemMapEntry ibex_memmap[] = {
51
#include "migration/migration.h"
69
- [IBEX_DEV_ROM] = { 0x00008000, 0x8000 },
52
#include "sysemu/runstate.h"
70
- [IBEX_DEV_RAM] = { 0x10000000, 0x20000 },
53
+#include "hw/riscv/numa.h"
71
- [IBEX_DEV_FLASH] = { 0x20000000, 0x100000 },
54
72
- [IBEX_DEV_UART] = { 0x40000000, 0x1000 },
55
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
73
- [IBEX_DEV_GPIO] = { 0x40040000, 0x1000 },
56
uint64_t idx)
74
- [IBEX_DEV_SPI_DEVICE] = { 0x40050000, 0x1000 },
57
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_cpu_check_are_resettable(void)
75
- [IBEX_DEV_I2C] = { 0x40080000, 0x1000 },
58
return true;
76
- [IBEX_DEV_PATTGEN] = { 0x400e0000, 0x1000 },
77
- [IBEX_DEV_TIMER] = { 0x40100000, 0x1000 },
78
- [IBEX_DEV_OTP_CTRL] = { 0x40130000, 0x4000 },
79
- [IBEX_DEV_LC_CTRL] = { 0x40140000, 0x1000 },
80
- [IBEX_DEV_ALERT_HANDLER] = { 0x40150000, 0x1000 },
81
- [IBEX_DEV_SPI_HOST0] = { 0x40300000, 0x1000 },
82
- [IBEX_DEV_SPI_HOST1] = { 0x40310000, 0x1000 },
83
- [IBEX_DEV_USBDEV] = { 0x40320000, 0x1000 },
84
- [IBEX_DEV_PWRMGR] = { 0x40400000, 0x1000 },
85
- [IBEX_DEV_RSTMGR] = { 0x40410000, 0x1000 },
86
- [IBEX_DEV_CLKMGR] = { 0x40420000, 0x1000 },
87
- [IBEX_DEV_PINMUX] = { 0x40460000, 0x1000 },
88
- [IBEX_DEV_AON_TIMER] = { 0x40470000, 0x1000 },
89
- [IBEX_DEV_SENSOR_CTRL] = { 0x40490000, 0x1000 },
90
- [IBEX_DEV_FLASH_CTRL] = { 0x41000000, 0x1000 },
91
- [IBEX_DEV_AES] = { 0x41100000, 0x1000 },
92
- [IBEX_DEV_HMAC] = { 0x41110000, 0x1000 },
93
- [IBEX_DEV_KMAC] = { 0x41120000, 0x1000 },
94
- [IBEX_DEV_OTBN] = { 0x41130000, 0x10000 },
95
- [IBEX_DEV_KEYMGR] = { 0x41140000, 0x1000 },
96
- [IBEX_DEV_CSRNG] = { 0x41150000, 0x1000 },
97
- [IBEX_DEV_ENTROPY] = { 0x41160000, 0x1000 },
98
- [IBEX_DEV_EDNO] = { 0x41170000, 0x1000 },
99
- [IBEX_DEV_EDN1] = { 0x41180000, 0x1000 },
100
- [IBEX_DEV_NMI_GEN] = { 0x411c0000, 0x1000 },
101
- [IBEX_DEV_PERI] = { 0x411f0000, 0x10000 },
102
- [IBEX_DEV_PLIC] = { 0x48000000, 0x4005000 },
103
- [IBEX_DEV_FLASH_VIRTUAL] = { 0x80000000, 0x80000 },
104
+ [IBEX_DEV_ROM] = { 0x00008000, 0x8000 },
105
+ [IBEX_DEV_RAM] = { 0x10000000, 0x20000 },
106
+ [IBEX_DEV_FLASH] = { 0x20000000, 0x100000 },
107
+ [IBEX_DEV_UART] = { 0x40000000, 0x40 },
108
+ [IBEX_DEV_GPIO] = { 0x40040000, 0x40 },
109
+ [IBEX_DEV_SPI_DEVICE] = { 0x40050000, 0x2000 },
110
+ [IBEX_DEV_I2C] = { 0x40080000, 0x80 },
111
+ [IBEX_DEV_PATTGEN] = { 0x400e0000, 0x40 },
112
+ [IBEX_DEV_TIMER] = { 0x40100000, 0x200 },
113
+ [IBEX_DEV_OTP_CTRL] = { 0x40130000, 0x2000 },
114
+ [IBEX_DEV_LC_CTRL] = { 0x40140000, 0x100 },
115
+ [IBEX_DEV_ALERT_HANDLER] = { 0x40150000, 0x800 },
116
+ [IBEX_DEV_SPI_HOST0] = { 0x40300000, 0x40 },
117
+ [IBEX_DEV_SPI_HOST1] = { 0x40310000, 0x40 },
118
+ [IBEX_DEV_USBDEV] = { 0x40320000, 0x1000 },
119
+ [IBEX_DEV_PWRMGR] = { 0x40400000, 0x80 },
120
+ [IBEX_DEV_RSTMGR] = { 0x40410000, 0x80 },
121
+ [IBEX_DEV_CLKMGR] = { 0x40420000, 0x80 },
122
+ [IBEX_DEV_PINMUX] = { 0x40460000, 0x1000 },
123
+ [IBEX_DEV_AON_TIMER] = { 0x40470000, 0x40 },
124
+ [IBEX_DEV_SENSOR_CTRL] = { 0x40490000, 0x40 },
125
+ [IBEX_DEV_FLASH_CTRL] = { 0x41000000, 0x200 },
126
+ [IBEX_DEV_AES] = { 0x41100000, 0x100 },
127
+ [IBEX_DEV_HMAC] = { 0x41110000, 0x1000 },
128
+ [IBEX_DEV_KMAC] = { 0x41120000, 0x1000 },
129
+ [IBEX_DEV_OTBN] = { 0x41130000, 0x10000 },
130
+ [IBEX_DEV_KEYMGR] = { 0x41140000, 0x100 },
131
+ [IBEX_DEV_CSRNG] = { 0x41150000, 0x80 },
132
+ [IBEX_DEV_ENTROPY] = { 0x41160000, 0x100 },
133
+ [IBEX_DEV_EDNO] = { 0x41170000, 0x80 },
134
+ [IBEX_DEV_EDN1] = { 0x41180000, 0x80 },
135
+ [IBEX_DEV_SRAM_CTRL] = { 0x411c0000, 0x20 },
136
+ [IBEX_DEV_IBEX_CFG] = { 0x411f0000, 0x100 },
137
+ [IBEX_DEV_PLIC] = { 0x48000000, 0x8000000 },
138
+ [IBEX_DEV_FLASH_VIRTUAL] = { 0x80000000, 0x80000 },
139
};
140
141
static void opentitan_board_init(MachineState *machine)
142
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
143
memmap[IBEX_DEV_EDN1].base, memmap[IBEX_DEV_EDN1].size);
144
create_unimplemented_device("riscv.lowrisc.ibex.alert_handler",
145
memmap[IBEX_DEV_ALERT_HANDLER].base, memmap[IBEX_DEV_ALERT_HANDLER].size);
146
- create_unimplemented_device("riscv.lowrisc.ibex.nmi_gen",
147
- memmap[IBEX_DEV_NMI_GEN].base, memmap[IBEX_DEV_NMI_GEN].size);
148
+ create_unimplemented_device("riscv.lowrisc.ibex.sram_ctrl",
149
+ memmap[IBEX_DEV_SRAM_CTRL].base, memmap[IBEX_DEV_SRAM_CTRL].size);
150
create_unimplemented_device("riscv.lowrisc.ibex.otbn",
151
memmap[IBEX_DEV_OTBN].base, memmap[IBEX_DEV_OTBN].size);
152
- create_unimplemented_device("riscv.lowrisc.ibex.peri",
153
- memmap[IBEX_DEV_PERI].base, memmap[IBEX_DEV_PERI].size);
154
+ create_unimplemented_device("riscv.lowrisc.ibex.ibex_cfg",
155
+ memmap[IBEX_DEV_IBEX_CFG].base, memmap[IBEX_DEV_IBEX_CFG].size);
156
}
59
}
157
60
158
static Property lowrisc_ibex_soc_props[] = {
61
+static int aia_mode;
62
+
63
+static const char *kvm_aia_mode_str(uint64_t mode)
64
+{
65
+ switch (mode) {
66
+ case KVM_DEV_RISCV_AIA_MODE_EMUL:
67
+ return "emul";
68
+ case KVM_DEV_RISCV_AIA_MODE_HWACCEL:
69
+ return "hwaccel";
70
+ case KVM_DEV_RISCV_AIA_MODE_AUTO:
71
+ default:
72
+ return "auto";
73
+ };
74
+}
75
+
76
+static char *riscv_get_kvm_aia(Object *obj, Error **errp)
77
+{
78
+ return g_strdup(kvm_aia_mode_str(aia_mode));
79
+}
80
+
81
+static void riscv_set_kvm_aia(Object *obj, const char *val, Error **errp)
82
+{
83
+ if (!strcmp(val, "emul")) {
84
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_EMUL;
85
+ } else if (!strcmp(val, "hwaccel")) {
86
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_HWACCEL;
87
+ } else if (!strcmp(val, "auto")) {
88
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_AUTO;
89
+ } else {
90
+ error_setg(errp, "Invalid KVM AIA mode");
91
+ error_append_hint(errp, "Valid values are emul, hwaccel, and auto.\n");
92
+ }
93
+}
94
+
95
void kvm_arch_accel_class_init(ObjectClass *oc)
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;
206
+ }
207
+
208
+ for (i = 0; i < hart_count; i++) {
209
+ imsic_addr = socket_imsic_base + i * IMSIC_HART_SIZE(guest_bits);
210
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_ADDR,
211
+ KVM_DEV_RISCV_AIA_ADDR_IMSIC(i + base_hart),
212
+ &imsic_addr, true, NULL);
213
+ if (ret < 0) {
214
+ error_report("KVM AIA: failed to set the IMSIC address for hart %d", i);
215
+ exit(1);
216
+ }
217
+ }
218
+ }
219
+
220
+ hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
221
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
222
+ KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
223
+ &hart_bits, true, NULL);
224
+ if (ret < 0) {
225
+ error_report("KVM AIA: failed to set hart_bits");
226
+ exit(1);
227
+ }
228
+
229
+ if (kvm_has_gsi_routing()) {
230
+ for (uint64_t idx = 0; idx < aia_irq_num + 1; ++idx) {
231
+ /* KVM AIA only has one APLIC instance */
232
+ kvm_irqchip_add_irq_route(kvm_state, idx, 0, idx);
233
+ }
234
+ kvm_gsi_routing_allowed = true;
235
+ kvm_irqchip_commit_routes(kvm_state);
236
+ }
237
+
238
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CTRL,
239
+ KVM_DEV_RISCV_AIA_CTRL_INIT,
240
+ NULL, true, NULL);
241
+ if (ret < 0) {
242
+ error_report("KVM AIA: initialized fail");
243
+ exit(1);
244
+ }
245
+
246
+ kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();
247
}
159
--
248
--
160
2.39.1
249
2.41.0
diff view generated by jsdifflib
1
From: Anup Patel <apatel@ventanamicro.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
The time CSR will wrap-around immediately after reaching UINT64_MAX
3
KVM AIA can't emulate APLIC only. When "aia=aplic" parameter is passed,
4
so we don't need to re-start QEMU timer when timecmp == UINT64_MAX
4
APLIC devices is emulated by QEMU. For "aia=aplic-imsic", remove the
5
in riscv_timer_write_timecmp().
5
mmio operations of APLIC when using KVM AIA and send wired interrupt
6
signal via KVM_IRQ_LINE API.
7
After KVM AIA enabled, MSI messages are delivered by KVM_SIGNAL_MSI API
8
when the IMSICs receive mmio write requests.
6
9
7
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
10
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Jim Shu <jim.shu@sifive.com>
9
Message-Id: <20230120125950.2246378-4-apatel@ventanamicro.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
14
Message-ID: <20230727102439.22554-5-yongxuan.wang@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
16
---
12
target/riscv/time_helper.c | 24 ++++++++++++++++++++++++
17
hw/intc/riscv_aplic.c | 56 ++++++++++++++++++++++++++++++-------------
13
1 file changed, 24 insertions(+)
18
hw/intc/riscv_imsic.c | 25 +++++++++++++++----
19
2 files changed, 61 insertions(+), 20 deletions(-)
14
20
15
diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
21
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/time_helper.c
23
--- a/hw/intc/riscv_aplic.c
18
+++ b/target/riscv/time_helper.c
24
+++ b/hw/intc/riscv_aplic.c
19
@@ -XXX,XX +XXX,XX @@ void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer,
25
@@ -XXX,XX +XXX,XX @@
20
riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
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
+ }
21
}
109
}
22
110
23
+ /*
111
/* Create output IRQ lines for non-MSI mode */
24
+ * Sstc specification says the following about timer interrupt:
112
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
25
+ * "A supervisor timer interrupt becomes pending - as reflected in
113
qdev_prop_set_bit(dev, "mmode", mmode);
26
+ * the STIP bit in the mip and sip registers - whenever time contains
114
27
+ * a value greater than or equal to stimecmp, treating the values
115
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
28
+ * as unsigned integers. Writes to stimecmp are guaranteed to be
116
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
29
+ * reflected in STIP eventually, but not necessarily immediately.
117
+
30
+ * The interrupt remains posted until stimecmp becomes greater
118
+ if (!is_kvm_aia(msimode)) {
31
+ * than time - typically as a result of writing stimecmp."
119
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
32
+ *
120
+ }
33
+ * When timecmp = UINT64_MAX, the time CSR will eventually reach
121
34
+ * timecmp value but on next timer tick the time CSR will wrap-around
122
if (parent) {
35
+ * and become zero which is less than UINT64_MAX. Now, the timer
123
riscv_aplic_add_child(parent, dev);
36
+ * interrupt behaves like a level triggered interrupt so it will
124
diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c
37
+ * become 1 when time = timecmp = UINT64_MAX and next timer tick
125
index XXXXXXX..XXXXXXX 100644
38
+ * it will become 0 again because time = 0 < timecmp = UINT64_MAX.
126
--- a/hw/intc/riscv_imsic.c
39
+ *
127
+++ b/hw/intc/riscv_imsic.c
40
+ * Based on above, we don't re-start the QEMU timer when timecmp
128
@@ -XXX,XX +XXX,XX @@
41
+ * equals UINT64_MAX.
129
#include "target/riscv/cpu.h"
42
+ */
130
#include "target/riscv/cpu_bits.h"
43
+ if (timecmp == UINT64_MAX) {
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;
143
+
144
+ msi.address_lo = extract64(imsic->mmio.addr + addr, 0, 32);
145
+ msi.address_hi = extract64(imsic->mmio.addr + addr, 32, 32);
146
+ msi.data = le32_to_cpu(value);
147
+
148
+ kvm_vm_ioctl(kvm_state, KVM_SIGNAL_MSI, &msi);
149
+
44
+ return;
150
+ return;
45
+ }
151
+ }
152
+#endif
46
+
153
+
47
/* otherwise, set up the future timer interrupt */
154
/* Writes only supported for MSI little-endian registers */
48
diff = timecmp - rtc_r;
155
page = addr >> IMSIC_MMIO_PAGE_SHIFT;
49
/* back to ns (note args switched in muldiv64) */
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,
50
--
174
--
51
2.39.1
175
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
We have a convention in other QEMU boards/archs to name MachineState
3
Select KVM AIA when the host kernel has in-kernel AIA chip support.
4
pointers as either 'machine' or 'ms'. MachineClass pointers are usually
4
Since KVM AIA only has one APLIC instance, we map the QEMU APLIC
5
called 'mc'.
5
devices to KVM APLIC.
6
6
7
The 'virt' RISC-V machine has a lot of instances where MachineState
7
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
8
pointers are named 'mc'. There is nothing wrong with that, but we gain
8
Reviewed-by: Jim Shu <jim.shu@sifive.com>
9
more compatibility with the rest of the QEMU code base, and easier
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
reviews, if we follow QEMU conventions.
10
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
11
11
Message-ID: <20230727102439.22554-6-yongxuan.wang@sifive.com>
12
Rename all 'mc' MachineState pointers to 'ms'. This is a very tedious
13
and mechanical patch that was produced by doing the following:
14
15
- find/replace all 'MachineState *mc' to 'MachineState *ms';
16
- find/replace all 'mc->fdt' to 'ms->fdt';
17
- find/replace all 'mc->smp.cpus' to 'ms->smp.cpus';
18
- replace any remaining occurrences of 'mc' that the compiler complained
19
about.
20
21
Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
22
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
24
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
25
Message-Id: <20230124212234.412630-3-dbarboza@ventanamicro.com>
26
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
---
13
---
28
hw/riscv/virt.c | 434 ++++++++++++++++++++++++------------------------
14
hw/riscv/virt.c | 94 +++++++++++++++++++++++++++++++++----------------
29
1 file changed, 217 insertions(+), 217 deletions(-)
15
1 file changed, 63 insertions(+), 31 deletions(-)
30
16
31
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
17
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
32
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/riscv/virt.c
19
--- a/hw/riscv/virt.c
34
+++ b/hw/riscv/virt.c
20
+++ b/hw/riscv/virt.c
35
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
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)
36
{
48
{
37
int cpu;
49
int cpu;
38
uint32_t cpu_phandle;
39
- MachineState *mc = MACHINE(s);
40
+ MachineState *ms = MACHINE(s);
41
char *name, *cpu_name, *core_name, *intc_name;
42
bool is_32_bit = riscv_is_32bit(&s->soc[0]);
43
44
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
45
46
cpu_name = g_strdup_printf("/cpus/cpu@%d",
47
s->soc[socket].hartid_base + cpu);
48
- qemu_fdt_add_subnode(mc->fdt, cpu_name);
49
+ qemu_fdt_add_subnode(ms->fdt, cpu_name);
50
if (riscv_feature(&s->soc[socket].harts[cpu].env,
51
RISCV_FEATURE_MMU)) {
52
- qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type",
53
+ qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type",
54
(is_32_bit) ? "riscv,sv32" : "riscv,sv48");
55
} else {
56
- qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type",
57
+ qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type",
58
"riscv,none");
59
}
60
name = riscv_isa_string(&s->soc[socket].harts[cpu]);
61
- qemu_fdt_setprop_string(mc->fdt, cpu_name, "riscv,isa", name);
62
+ qemu_fdt_setprop_string(ms->fdt, cpu_name, "riscv,isa", name);
63
g_free(name);
64
- qemu_fdt_setprop_string(mc->fdt, cpu_name, "compatible", "riscv");
65
- qemu_fdt_setprop_string(mc->fdt, cpu_name, "status", "okay");
66
- qemu_fdt_setprop_cell(mc->fdt, cpu_name, "reg",
67
+ qemu_fdt_setprop_string(ms->fdt, cpu_name, "compatible", "riscv");
68
+ qemu_fdt_setprop_string(ms->fdt, cpu_name, "status", "okay");
69
+ qemu_fdt_setprop_cell(ms->fdt, cpu_name, "reg",
70
s->soc[socket].hartid_base + cpu);
71
- qemu_fdt_setprop_string(mc->fdt, cpu_name, "device_type", "cpu");
72
- riscv_socket_fdt_write_id(mc, cpu_name, socket);
73
- qemu_fdt_setprop_cell(mc->fdt, cpu_name, "phandle", cpu_phandle);
74
+ qemu_fdt_setprop_string(ms->fdt, cpu_name, "device_type", "cpu");
75
+ riscv_socket_fdt_write_id(ms, cpu_name, socket);
76
+ qemu_fdt_setprop_cell(ms->fdt, cpu_name, "phandle", cpu_phandle);
77
78
intc_phandles[cpu] = (*phandle)++;
79
80
intc_name = g_strdup_printf("%s/interrupt-controller", cpu_name);
81
- qemu_fdt_add_subnode(mc->fdt, intc_name);
82
- qemu_fdt_setprop_cell(mc->fdt, intc_name, "phandle",
83
+ qemu_fdt_add_subnode(ms->fdt, intc_name);
84
+ qemu_fdt_setprop_cell(ms->fdt, intc_name, "phandle",
85
intc_phandles[cpu]);
86
- qemu_fdt_setprop_string(mc->fdt, intc_name, "compatible",
87
+ qemu_fdt_setprop_string(ms->fdt, intc_name, "compatible",
88
"riscv,cpu-intc");
89
- qemu_fdt_setprop(mc->fdt, intc_name, "interrupt-controller", NULL, 0);
90
- qemu_fdt_setprop_cell(mc->fdt, intc_name, "#interrupt-cells", 1);
91
+ qemu_fdt_setprop(ms->fdt, intc_name, "interrupt-controller", NULL, 0);
92
+ qemu_fdt_setprop_cell(ms->fdt, intc_name, "#interrupt-cells", 1);
93
94
core_name = g_strdup_printf("%s/core%d", clust_name, cpu);
95
- qemu_fdt_add_subnode(mc->fdt, core_name);
96
- qemu_fdt_setprop_cell(mc->fdt, core_name, "cpu", cpu_phandle);
97
+ qemu_fdt_add_subnode(ms->fdt, core_name);
98
+ qemu_fdt_setprop_cell(ms->fdt, core_name, "cpu", cpu_phandle);
99
100
g_free(core_name);
101
g_free(intc_name);
102
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_memory(RISCVVirtState *s,
103
{
104
char *mem_name;
105
uint64_t addr, size;
106
- MachineState *mc = MACHINE(s);
107
+ MachineState *ms = MACHINE(s);
108
109
- addr = memmap[VIRT_DRAM].base + riscv_socket_mem_offset(mc, socket);
110
- size = riscv_socket_mem_size(mc, socket);
111
+ addr = memmap[VIRT_DRAM].base + riscv_socket_mem_offset(ms, socket);
112
+ size = riscv_socket_mem_size(ms, socket);
113
mem_name = g_strdup_printf("/memory@%lx", (long)addr);
114
- qemu_fdt_add_subnode(mc->fdt, mem_name);
115
- qemu_fdt_setprop_cells(mc->fdt, mem_name, "reg",
116
+ qemu_fdt_add_subnode(ms->fdt, mem_name);
117
+ qemu_fdt_setprop_cells(ms->fdt, mem_name, "reg",
118
addr >> 32, addr, size >> 32, size);
119
- qemu_fdt_setprop_string(mc->fdt, mem_name, "device_type", "memory");
120
- riscv_socket_fdt_write_id(mc, mem_name, socket);
121
+ qemu_fdt_setprop_string(ms->fdt, mem_name, "device_type", "memory");
122
+ riscv_socket_fdt_write_id(ms, mem_name, socket);
123
g_free(mem_name);
124
}
125
126
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_clint(RISCVVirtState *s,
127
char *clint_name;
128
uint32_t *clint_cells;
129
unsigned long clint_addr;
130
- MachineState *mc = MACHINE(s);
131
+ MachineState *ms = MACHINE(s);
132
static const char * const clint_compat[2] = {
133
"sifive,clint0", "riscv,clint0"
134
};
135
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_clint(RISCVVirtState *s,
136
137
clint_addr = memmap[VIRT_CLINT].base + (memmap[VIRT_CLINT].size * socket);
138
clint_name = g_strdup_printf("/soc/clint@%lx", clint_addr);
139
- qemu_fdt_add_subnode(mc->fdt, clint_name);
140
- qemu_fdt_setprop_string_array(mc->fdt, clint_name, "compatible",
141
+ qemu_fdt_add_subnode(ms->fdt, clint_name);
142
+ qemu_fdt_setprop_string_array(ms->fdt, clint_name, "compatible",
143
(char **)&clint_compat,
144
ARRAY_SIZE(clint_compat));
145
- qemu_fdt_setprop_cells(mc->fdt, clint_name, "reg",
146
+ qemu_fdt_setprop_cells(ms->fdt, clint_name, "reg",
147
0x0, clint_addr, 0x0, memmap[VIRT_CLINT].size);
148
- qemu_fdt_setprop(mc->fdt, clint_name, "interrupts-extended",
149
+ qemu_fdt_setprop(ms->fdt, clint_name, "interrupts-extended",
150
clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
151
- riscv_socket_fdt_write_id(mc, clint_name, socket);
152
+ riscv_socket_fdt_write_id(ms, clint_name, socket);
153
g_free(clint_name);
154
155
g_free(clint_cells);
156
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aclint(RISCVVirtState *s,
157
uint32_t *aclint_mswi_cells;
158
uint32_t *aclint_sswi_cells;
159
uint32_t *aclint_mtimer_cells;
160
- MachineState *mc = MACHINE(s);
161
+ MachineState *ms = MACHINE(s);
162
163
aclint_mswi_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
164
aclint_mtimer_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
165
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aclint(RISCVVirtState *s,
166
if (s->aia_type != VIRT_AIA_TYPE_APLIC_IMSIC) {
167
addr = memmap[VIRT_CLINT].base + (memmap[VIRT_CLINT].size * socket);
168
name = g_strdup_printf("/soc/mswi@%lx", addr);
169
- qemu_fdt_add_subnode(mc->fdt, name);
170
- qemu_fdt_setprop_string(mc->fdt, name, "compatible",
171
+ qemu_fdt_add_subnode(ms->fdt, name);
172
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible",
173
"riscv,aclint-mswi");
174
- qemu_fdt_setprop_cells(mc->fdt, name, "reg",
175
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg",
176
0x0, addr, 0x0, RISCV_ACLINT_SWI_SIZE);
177
- qemu_fdt_setprop(mc->fdt, name, "interrupts-extended",
178
+ qemu_fdt_setprop(ms->fdt, name, "interrupts-extended",
179
aclint_mswi_cells, aclint_cells_size);
180
- qemu_fdt_setprop(mc->fdt, name, "interrupt-controller", NULL, 0);
181
- qemu_fdt_setprop_cell(mc->fdt, name, "#interrupt-cells", 0);
182
- riscv_socket_fdt_write_id(mc, name, socket);
183
+ qemu_fdt_setprop(ms->fdt, name, "interrupt-controller", NULL, 0);
184
+ qemu_fdt_setprop_cell(ms->fdt, name, "#interrupt-cells", 0);
185
+ riscv_socket_fdt_write_id(ms, name, socket);
186
g_free(name);
187
}
188
189
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aclint(RISCVVirtState *s,
190
size = memmap[VIRT_CLINT].size - RISCV_ACLINT_SWI_SIZE;
191
}
192
name = g_strdup_printf("/soc/mtimer@%lx", addr);
193
- qemu_fdt_add_subnode(mc->fdt, name);
194
- qemu_fdt_setprop_string(mc->fdt, name, "compatible",
195
+ qemu_fdt_add_subnode(ms->fdt, name);
196
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible",
197
"riscv,aclint-mtimer");
198
- qemu_fdt_setprop_cells(mc->fdt, name, "reg",
199
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg",
200
0x0, addr + RISCV_ACLINT_DEFAULT_MTIME,
201
0x0, size - RISCV_ACLINT_DEFAULT_MTIME,
202
0x0, addr + RISCV_ACLINT_DEFAULT_MTIMECMP,
203
0x0, RISCV_ACLINT_DEFAULT_MTIME);
204
- qemu_fdt_setprop(mc->fdt, name, "interrupts-extended",
205
+ qemu_fdt_setprop(ms->fdt, name, "interrupts-extended",
206
aclint_mtimer_cells, aclint_cells_size);
207
- riscv_socket_fdt_write_id(mc, name, socket);
208
+ riscv_socket_fdt_write_id(ms, name, socket);
209
g_free(name);
210
211
if (s->aia_type != VIRT_AIA_TYPE_APLIC_IMSIC) {
212
addr = memmap[VIRT_ACLINT_SSWI].base +
213
(memmap[VIRT_ACLINT_SSWI].size * socket);
214
name = g_strdup_printf("/soc/sswi@%lx", addr);
215
- qemu_fdt_add_subnode(mc->fdt, name);
216
- qemu_fdt_setprop_string(mc->fdt, name, "compatible",
217
+ qemu_fdt_add_subnode(ms->fdt, name);
218
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible",
219
"riscv,aclint-sswi");
220
- qemu_fdt_setprop_cells(mc->fdt, name, "reg",
221
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg",
222
0x0, addr, 0x0, memmap[VIRT_ACLINT_SSWI].size);
223
- qemu_fdt_setprop(mc->fdt, name, "interrupts-extended",
224
+ qemu_fdt_setprop(ms->fdt, name, "interrupts-extended",
225
aclint_sswi_cells, aclint_cells_size);
226
- qemu_fdt_setprop(mc->fdt, name, "interrupt-controller", NULL, 0);
227
- qemu_fdt_setprop_cell(mc->fdt, name, "#interrupt-cells", 0);
228
- riscv_socket_fdt_write_id(mc, name, socket);
229
+ qemu_fdt_setprop(ms->fdt, name, "interrupt-controller", NULL, 0);
230
+ qemu_fdt_setprop_cell(ms->fdt, name, "#interrupt-cells", 0);
231
+ riscv_socket_fdt_write_id(ms, name, socket);
232
g_free(name);
233
}
234
235
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_plic(RISCVVirtState *s,
236
char *plic_name;
237
uint32_t *plic_cells;
238
unsigned long plic_addr;
239
- MachineState *mc = MACHINE(s);
240
+ MachineState *ms = MACHINE(s);
241
static const char * const plic_compat[2] = {
242
"sifive,plic-1.0.0", "riscv,plic0"
243
};
244
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_plic(RISCVVirtState *s,
245
plic_phandles[socket] = (*phandle)++;
246
plic_addr = memmap[VIRT_PLIC].base + (memmap[VIRT_PLIC].size * socket);
247
plic_name = g_strdup_printf("/soc/plic@%lx", plic_addr);
248
- qemu_fdt_add_subnode(mc->fdt, plic_name);
249
- qemu_fdt_setprop_cell(mc->fdt, plic_name,
250
+ qemu_fdt_add_subnode(ms->fdt, plic_name);
251
+ qemu_fdt_setprop_cell(ms->fdt, plic_name,
252
"#interrupt-cells", FDT_PLIC_INT_CELLS);
253
- qemu_fdt_setprop_cell(mc->fdt, plic_name,
254
+ qemu_fdt_setprop_cell(ms->fdt, plic_name,
255
"#address-cells", FDT_PLIC_ADDR_CELLS);
256
- qemu_fdt_setprop_string_array(mc->fdt, plic_name, "compatible",
257
+ qemu_fdt_setprop_string_array(ms->fdt, plic_name, "compatible",
258
(char **)&plic_compat,
259
ARRAY_SIZE(plic_compat));
260
- qemu_fdt_setprop(mc->fdt, plic_name, "interrupt-controller", NULL, 0);
261
- qemu_fdt_setprop(mc->fdt, plic_name, "interrupts-extended",
262
+ qemu_fdt_setprop(ms->fdt, plic_name, "interrupt-controller", NULL, 0);
263
+ qemu_fdt_setprop(ms->fdt, plic_name, "interrupts-extended",
264
plic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
265
- qemu_fdt_setprop_cells(mc->fdt, plic_name, "reg",
266
+ qemu_fdt_setprop_cells(ms->fdt, plic_name, "reg",
267
0x0, plic_addr, 0x0, memmap[VIRT_PLIC].size);
268
- qemu_fdt_setprop_cell(mc->fdt, plic_name, "riscv,ndev",
269
+ qemu_fdt_setprop_cell(ms->fdt, plic_name, "riscv,ndev",
270
VIRT_IRQCHIP_NUM_SOURCES - 1);
271
- riscv_socket_fdt_write_id(mc, plic_name, socket);
272
- qemu_fdt_setprop_cell(mc->fdt, plic_name, "phandle",
273
+ riscv_socket_fdt_write_id(ms, plic_name, socket);
274
+ qemu_fdt_setprop_cell(ms->fdt, plic_name, "phandle",
275
plic_phandles[socket]);
276
277
if (!socket) {
278
- platform_bus_add_all_fdt_nodes(mc->fdt, plic_name,
279
+ platform_bus_add_all_fdt_nodes(ms->fdt, plic_name,
280
memmap[VIRT_PLATFORM_BUS].base,
281
memmap[VIRT_PLATFORM_BUS].size,
282
VIRT_PLATFORM_BUS_IRQ);
283
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
284
{
285
int cpu, socket;
286
char *imsic_name;
287
- MachineState *mc = MACHINE(s);
288
- int socket_count = riscv_socket_count(mc);
289
+ MachineState *ms = MACHINE(s);
290
+ int socket_count = riscv_socket_count(ms);
291
uint32_t imsic_max_hart_per_socket, imsic_guest_bits;
292
uint32_t *imsic_cells, *imsic_regs, imsic_addr, imsic_size;
293
294
*msi_m_phandle = (*phandle)++;
295
*msi_s_phandle = (*phandle)++;
296
- imsic_cells = g_new0(uint32_t, mc->smp.cpus * 2);
297
+ imsic_cells = g_new0(uint32_t, ms->smp.cpus * 2);
298
imsic_regs = g_new0(uint32_t, socket_count * 4);
299
300
/* M-level IMSIC node */
301
- for (cpu = 0; cpu < mc->smp.cpus; cpu++) {
302
+ for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
303
imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
304
imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
305
}
306
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
307
}
308
imsic_name = g_strdup_printf("/soc/imsics@%lx",
309
(unsigned long)memmap[VIRT_IMSIC_M].base);
310
- qemu_fdt_add_subnode(mc->fdt, imsic_name);
311
- qemu_fdt_setprop_string(mc->fdt, imsic_name, "compatible",
312
+ qemu_fdt_add_subnode(ms->fdt, imsic_name);
313
+ qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
314
"riscv,imsics");
315
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "#interrupt-cells",
316
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
317
FDT_IMSIC_INT_CELLS);
318
- qemu_fdt_setprop(mc->fdt, imsic_name, "interrupt-controller",
319
+ qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
320
NULL, 0);
321
- qemu_fdt_setprop(mc->fdt, imsic_name, "msi-controller",
322
+ qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
323
NULL, 0);
324
- qemu_fdt_setprop(mc->fdt, imsic_name, "interrupts-extended",
325
- imsic_cells, mc->smp.cpus * sizeof(uint32_t) * 2);
326
- qemu_fdt_setprop(mc->fdt, imsic_name, "reg", imsic_regs,
327
+ qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
328
+ imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
329
+ qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
330
socket_count * sizeof(uint32_t) * 4);
331
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
332
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
333
VIRT_IRQCHIP_NUM_MSIS);
334
if (socket_count > 1) {
335
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits",
336
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
337
imsic_num_bits(imsic_max_hart_per_socket));
338
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-bits",
339
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
340
imsic_num_bits(socket_count));
341
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-shift",
342
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
343
IMSIC_MMIO_GROUP_MIN_SHIFT);
344
}
345
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "phandle", *msi_m_phandle);
346
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_m_phandle);
347
348
g_free(imsic_name);
349
350
/* S-level IMSIC node */
351
- for (cpu = 0; cpu < mc->smp.cpus; cpu++) {
352
+ for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
353
imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
354
imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
355
}
356
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
357
}
358
imsic_name = g_strdup_printf("/soc/imsics@%lx",
359
(unsigned long)memmap[VIRT_IMSIC_S].base);
360
- qemu_fdt_add_subnode(mc->fdt, imsic_name);
361
- qemu_fdt_setprop_string(mc->fdt, imsic_name, "compatible",
362
+ qemu_fdt_add_subnode(ms->fdt, imsic_name);
363
+ qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
364
"riscv,imsics");
365
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "#interrupt-cells",
366
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
367
FDT_IMSIC_INT_CELLS);
368
- qemu_fdt_setprop(mc->fdt, imsic_name, "interrupt-controller",
369
+ qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
370
NULL, 0);
371
- qemu_fdt_setprop(mc->fdt, imsic_name, "msi-controller",
372
+ qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
373
NULL, 0);
374
- qemu_fdt_setprop(mc->fdt, imsic_name, "interrupts-extended",
375
- imsic_cells, mc->smp.cpus * sizeof(uint32_t) * 2);
376
- qemu_fdt_setprop(mc->fdt, imsic_name, "reg", imsic_regs,
377
+ qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
378
+ imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
379
+ qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
380
socket_count * sizeof(uint32_t) * 4);
381
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
382
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
383
VIRT_IRQCHIP_NUM_MSIS);
384
if (imsic_guest_bits) {
385
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,guest-index-bits",
386
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,guest-index-bits",
387
imsic_guest_bits);
388
}
389
if (socket_count > 1) {
390
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits",
391
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
392
imsic_num_bits(imsic_max_hart_per_socket));
393
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-bits",
394
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
395
imsic_num_bits(socket_count));
396
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-shift",
397
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
398
IMSIC_MMIO_GROUP_MIN_SHIFT);
399
}
400
- qemu_fdt_setprop_cell(mc->fdt, imsic_name, "phandle", *msi_s_phandle);
401
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_s_phandle);
402
g_free(imsic_name);
403
404
g_free(imsic_regs);
405
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
406
char *aplic_name;
50
char *aplic_name;
407
uint32_t *aplic_cells;
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;
408
unsigned long aplic_addr;
81
unsigned long aplic_addr;
409
- MachineState *mc = MACHINE(s);
410
+ MachineState *ms = MACHINE(s);
411
uint32_t aplic_m_phandle, aplic_s_phandle;
412
413
aplic_m_phandle = (*phandle)++;
414
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
82
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
415
aplic_addr = memmap[VIRT_APLIC_M].base +
83
create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_M].size,
416
(memmap[VIRT_APLIC_M].size * socket);
84
msi_m_phandle, intc_phandles,
417
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
85
aplic_m_phandle, aplic_s_phandle,
418
- qemu_fdt_add_subnode(mc->fdt, aplic_name);
86
- true);
419
- qemu_fdt_setprop_string(mc->fdt, aplic_name, "compatible", "riscv,aplic");
87
+ true, num_harts);
420
- qemu_fdt_setprop_cell(mc->fdt, aplic_name,
421
+ qemu_fdt_add_subnode(ms->fdt, aplic_name);
422
+ qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
423
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name,
424
"#interrupt-cells", FDT_APLIC_INT_CELLS);
425
- qemu_fdt_setprop(mc->fdt, aplic_name, "interrupt-controller", NULL, 0);
426
+ qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
427
if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
428
- qemu_fdt_setprop(mc->fdt, aplic_name, "interrupts-extended",
429
+ qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
430
aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2);
431
} else {
432
- qemu_fdt_setprop_cell(mc->fdt, aplic_name, "msi-parent",
433
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent",
434
msi_m_phandle);
435
}
88
}
436
- qemu_fdt_setprop_cells(mc->fdt, aplic_name, "reg",
437
+ qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
438
0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_M].size);
439
- qemu_fdt_setprop_cell(mc->fdt, aplic_name, "riscv,num-sources",
440
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
441
VIRT_IRQCHIP_NUM_SOURCES);
442
- qemu_fdt_setprop_cell(mc->fdt, aplic_name, "riscv,children",
443
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,children",
444
aplic_s_phandle);
445
- qemu_fdt_setprop_cells(mc->fdt, aplic_name, "riscv,delegate",
446
+ qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate",
447
aplic_s_phandle, 0x1, VIRT_IRQCHIP_NUM_SOURCES);
448
- riscv_socket_fdt_write_id(mc, aplic_name, socket);
449
- qemu_fdt_setprop_cell(mc->fdt, aplic_name, "phandle", aplic_m_phandle);
450
+ riscv_socket_fdt_write_id(ms, aplic_name, socket);
451
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_m_phandle);
452
g_free(aplic_name);
453
89
454
/* S-level APLIC node */
90
/* S-level APLIC node */
455
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
91
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
456
aplic_addr = memmap[VIRT_APLIC_S].base +
92
create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_S].size,
457
(memmap[VIRT_APLIC_S].size * socket);
93
msi_s_phandle, intc_phandles,
94
aplic_s_phandle, 0,
95
- false);
96
+ false, num_harts);
97
458
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
98
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
459
- qemu_fdt_add_subnode(mc->fdt, aplic_name);
99
460
- qemu_fdt_setprop_string(mc->fdt, aplic_name, "compatible", "riscv,aplic");
461
- qemu_fdt_setprop_cell(mc->fdt, aplic_name,
462
+ qemu_fdt_add_subnode(ms->fdt, aplic_name);
463
+ qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
464
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name,
465
"#interrupt-cells", FDT_APLIC_INT_CELLS);
466
- qemu_fdt_setprop(mc->fdt, aplic_name, "interrupt-controller", NULL, 0);
467
+ qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
468
if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
469
- qemu_fdt_setprop(mc->fdt, aplic_name, "interrupts-extended",
470
+ qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
471
aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2);
472
} else {
473
- qemu_fdt_setprop_cell(mc->fdt, aplic_name, "msi-parent",
474
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent",
475
msi_s_phandle);
476
}
477
- qemu_fdt_setprop_cells(mc->fdt, aplic_name, "reg",
478
+ qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
479
0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_S].size);
480
- qemu_fdt_setprop_cell(mc->fdt, aplic_name, "riscv,num-sources",
481
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
482
VIRT_IRQCHIP_NUM_SOURCES);
483
- riscv_socket_fdt_write_id(mc, aplic_name, socket);
484
- qemu_fdt_setprop_cell(mc->fdt, aplic_name, "phandle", aplic_s_phandle);
485
+ riscv_socket_fdt_write_id(ms, aplic_name, socket);
486
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_s_phandle);
487
488
if (!socket) {
489
- platform_bus_add_all_fdt_nodes(mc->fdt, aplic_name,
490
+ platform_bus_add_all_fdt_nodes(ms->fdt, aplic_name,
491
memmap[VIRT_PLATFORM_BUS].base,
492
memmap[VIRT_PLATFORM_BUS].size,
493
VIRT_PLATFORM_BUS_IRQ);
494
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
495
static void create_fdt_pmu(RISCVVirtState *s)
496
{
497
char *pmu_name;
498
- MachineState *mc = MACHINE(s);
499
+ MachineState *ms = MACHINE(s);
500
RISCVCPU hart = s->soc[0].harts[0];
501
502
pmu_name = g_strdup_printf("/soc/pmu");
503
- qemu_fdt_add_subnode(mc->fdt, pmu_name);
504
- qemu_fdt_setprop_string(mc->fdt, pmu_name, "compatible", "riscv,pmu");
505
- riscv_pmu_generate_fdt_node(mc->fdt, hart.cfg.pmu_num, pmu_name);
506
+ qemu_fdt_add_subnode(ms->fdt, pmu_name);
507
+ qemu_fdt_setprop_string(ms->fdt, pmu_name, "compatible", "riscv,pmu");
508
+ riscv_pmu_generate_fdt_node(ms->fdt, hart.cfg.pmu_num, pmu_name);
509
510
g_free(pmu_name);
511
}
512
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
513
{
514
char *clust_name;
515
int socket, phandle_pos;
516
- MachineState *mc = MACHINE(s);
517
+ MachineState *ms = MACHINE(s);
518
uint32_t msi_m_phandle = 0, msi_s_phandle = 0;
519
uint32_t *intc_phandles, xplic_phandles[MAX_NODES];
520
- int socket_count = riscv_socket_count(mc);
521
+ int socket_count = riscv_socket_count(ms);
522
523
- qemu_fdt_add_subnode(mc->fdt, "/cpus");
524
- qemu_fdt_setprop_cell(mc->fdt, "/cpus", "timebase-frequency",
525
+ qemu_fdt_add_subnode(ms->fdt, "/cpus");
526
+ qemu_fdt_setprop_cell(ms->fdt, "/cpus", "timebase-frequency",
527
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ);
528
- qemu_fdt_setprop_cell(mc->fdt, "/cpus", "#size-cells", 0x0);
529
- qemu_fdt_setprop_cell(mc->fdt, "/cpus", "#address-cells", 0x1);
530
- qemu_fdt_add_subnode(mc->fdt, "/cpus/cpu-map");
531
+ qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
532
+ qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1);
533
+ qemu_fdt_add_subnode(ms->fdt, "/cpus/cpu-map");
534
535
- intc_phandles = g_new0(uint32_t, mc->smp.cpus);
536
+ intc_phandles = g_new0(uint32_t, ms->smp.cpus);
537
538
- phandle_pos = mc->smp.cpus;
539
+ phandle_pos = ms->smp.cpus;
540
for (socket = (socket_count - 1); socket >= 0; socket--) {
541
phandle_pos -= s->soc[socket].num_harts;
542
543
clust_name = g_strdup_printf("/cpus/cpu-map/cluster%d", socket);
544
- qemu_fdt_add_subnode(mc->fdt, clust_name);
545
+ qemu_fdt_add_subnode(ms->fdt, clust_name);
546
547
create_fdt_socket_cpus(s, socket, clust_name, phandle,
548
&intc_phandles[phandle_pos]);
549
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
100
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
550
*msi_pcie_phandle = msi_s_phandle;
101
*msi_pcie_phandle = msi_s_phandle;
551
}
102
}
552
103
553
- phandle_pos = mc->smp.cpus;
104
- phandle_pos = ms->smp.cpus;
554
+ phandle_pos = ms->smp.cpus;
105
- for (socket = (socket_count - 1); socket >= 0; socket--) {
555
for (socket = (socket_count - 1); socket >= 0; socket--) {
106
- phandle_pos -= s->soc[socket].num_harts;
556
phandle_pos -= s->soc[socket].num_harts;
107
-
557
108
- if (s->aia_type == VIRT_AIA_TYPE_NONE) {
558
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
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
+ }
559
}
137
}
560
}
138
}
561
139
562
- riscv_socket_fdt_write_distance_matrix(mc);
140
g_free(intc_phandles);
563
+ riscv_socket_fdt_write_distance_matrix(ms);
141
564
}
142
- for (socket = 0; socket < socket_count; socket++) {
565
143
- if (socket == 0) {
566
static void create_fdt_virtio(RISCVVirtState *s, const MemMapEntry *memmap,
144
- *irq_mmio_phandle = xplic_phandles[socket];
567
@@ -XXX,XX +XXX,XX @@ static void create_fdt_virtio(RISCVVirtState *s, const MemMapEntry *memmap,
145
- *irq_virtio_phandle = xplic_phandles[socket];
568
{
146
- *irq_pcie_phandle = xplic_phandles[socket];
569
int i;
147
- }
570
char *name;
148
- if (socket == 1) {
571
- MachineState *mc = MACHINE(s);
149
- *irq_virtio_phandle = xplic_phandles[socket];
572
+ MachineState *ms = MACHINE(s);
150
- *irq_pcie_phandle = xplic_phandles[socket];
573
151
- }
574
for (i = 0; i < VIRTIO_COUNT; i++) {
152
- if (socket == 2) {
575
name = g_strdup_printf("/soc/virtio_mmio@%lx",
153
- *irq_pcie_phandle = xplic_phandles[socket];
576
(long)(memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size));
154
+ if (virt_use_kvm_aia(s)) {
577
- qemu_fdt_add_subnode(mc->fdt, name);
155
+ *irq_mmio_phandle = xplic_phandles[0];
578
- qemu_fdt_setprop_string(mc->fdt, name, "compatible", "virtio,mmio");
156
+ *irq_virtio_phandle = xplic_phandles[0];
579
- qemu_fdt_setprop_cells(mc->fdt, name, "reg",
157
+ *irq_pcie_phandle = xplic_phandles[0];
580
+ qemu_fdt_add_subnode(ms->fdt, name);
158
+ } else {
581
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible", "virtio,mmio");
159
+ for (socket = 0; socket < socket_count; socket++) {
582
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg",
160
+ if (socket == 0) {
583
0x0, memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size,
161
+ *irq_mmio_phandle = xplic_phandles[socket];
584
0x0, memmap[VIRT_VIRTIO].size);
162
+ *irq_virtio_phandle = xplic_phandles[socket];
585
- qemu_fdt_setprop_cell(mc->fdt, name, "interrupt-parent",
163
+ *irq_pcie_phandle = xplic_phandles[socket];
586
+ qemu_fdt_setprop_cell(ms->fdt, name, "interrupt-parent",
164
+ }
587
irq_virtio_phandle);
165
+ if (socket == 1) {
588
if (s->aia_type == VIRT_AIA_TYPE_NONE) {
166
+ *irq_virtio_phandle = xplic_phandles[socket];
589
- qemu_fdt_setprop_cell(mc->fdt, name, "interrupts",
167
+ *irq_pcie_phandle = xplic_phandles[socket];
590
+ qemu_fdt_setprop_cell(ms->fdt, name, "interrupts",
168
+ }
591
VIRTIO_IRQ + i);
169
+ if (socket == 2) {
592
} else {
170
+ *irq_pcie_phandle = xplic_phandles[socket];
593
- qemu_fdt_setprop_cells(mc->fdt, name, "interrupts",
171
+ }
594
+ qemu_fdt_setprop_cells(ms->fdt, name, "interrupts",
595
VIRTIO_IRQ + i, 0x4);
596
}
597
g_free(name);
598
@@ -XXX,XX +XXX,XX @@ static void create_fdt_pcie(RISCVVirtState *s, const MemMapEntry *memmap,
599
uint32_t msi_pcie_phandle)
600
{
601
char *name;
602
- MachineState *mc = MACHINE(s);
603
+ MachineState *ms = MACHINE(s);
604
605
name = g_strdup_printf("/soc/pci@%lx",
606
(long) memmap[VIRT_PCIE_ECAM].base);
607
- qemu_fdt_add_subnode(mc->fdt, name);
608
- qemu_fdt_setprop_cell(mc->fdt, name, "#address-cells",
609
+ qemu_fdt_add_subnode(ms->fdt, name);
610
+ qemu_fdt_setprop_cell(ms->fdt, name, "#address-cells",
611
FDT_PCI_ADDR_CELLS);
612
- qemu_fdt_setprop_cell(mc->fdt, name, "#interrupt-cells",
613
+ qemu_fdt_setprop_cell(ms->fdt, name, "#interrupt-cells",
614
FDT_PCI_INT_CELLS);
615
- qemu_fdt_setprop_cell(mc->fdt, name, "#size-cells", 0x2);
616
- qemu_fdt_setprop_string(mc->fdt, name, "compatible",
617
+ qemu_fdt_setprop_cell(ms->fdt, name, "#size-cells", 0x2);
618
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible",
619
"pci-host-ecam-generic");
620
- qemu_fdt_setprop_string(mc->fdt, name, "device_type", "pci");
621
- qemu_fdt_setprop_cell(mc->fdt, name, "linux,pci-domain", 0);
622
- qemu_fdt_setprop_cells(mc->fdt, name, "bus-range", 0,
623
+ qemu_fdt_setprop_string(ms->fdt, name, "device_type", "pci");
624
+ qemu_fdt_setprop_cell(ms->fdt, name, "linux,pci-domain", 0);
625
+ qemu_fdt_setprop_cells(ms->fdt, name, "bus-range", 0,
626
memmap[VIRT_PCIE_ECAM].size / PCIE_MMCFG_SIZE_MIN - 1);
627
- qemu_fdt_setprop(mc->fdt, name, "dma-coherent", NULL, 0);
628
+ qemu_fdt_setprop(ms->fdt, name, "dma-coherent", NULL, 0);
629
if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) {
630
- qemu_fdt_setprop_cell(mc->fdt, name, "msi-parent", msi_pcie_phandle);
631
+ qemu_fdt_setprop_cell(ms->fdt, name, "msi-parent", msi_pcie_phandle);
632
}
633
- qemu_fdt_setprop_cells(mc->fdt, name, "reg", 0,
634
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg", 0,
635
memmap[VIRT_PCIE_ECAM].base, 0, memmap[VIRT_PCIE_ECAM].size);
636
- qemu_fdt_setprop_sized_cells(mc->fdt, name, "ranges",
637
+ qemu_fdt_setprop_sized_cells(ms->fdt, name, "ranges",
638
1, FDT_PCI_RANGE_IOPORT, 2, 0,
639
2, memmap[VIRT_PCIE_PIO].base, 2, memmap[VIRT_PCIE_PIO].size,
640
1, FDT_PCI_RANGE_MMIO,
641
@@ -XXX,XX +XXX,XX @@ static void create_fdt_pcie(RISCVVirtState *s, const MemMapEntry *memmap,
642
2, virt_high_pcie_memmap.base,
643
2, virt_high_pcie_memmap.base, 2, virt_high_pcie_memmap.size);
644
645
- create_pcie_irq_map(s, mc->fdt, name, irq_pcie_phandle);
646
+ create_pcie_irq_map(s, ms->fdt, name, irq_pcie_phandle);
647
g_free(name);
648
}
649
650
@@ -XXX,XX +XXX,XX @@ static void create_fdt_reset(RISCVVirtState *s, const MemMapEntry *memmap,
651
{
652
char *name;
653
uint32_t test_phandle;
654
- MachineState *mc = MACHINE(s);
655
+ MachineState *ms = MACHINE(s);
656
657
test_phandle = (*phandle)++;
658
name = g_strdup_printf("/soc/test@%lx",
659
(long)memmap[VIRT_TEST].base);
660
- qemu_fdt_add_subnode(mc->fdt, name);
661
+ qemu_fdt_add_subnode(ms->fdt, name);
662
{
663
static const char * const compat[3] = {
664
"sifive,test1", "sifive,test0", "syscon"
665
};
666
- qemu_fdt_setprop_string_array(mc->fdt, name, "compatible",
667
+ qemu_fdt_setprop_string_array(ms->fdt, name, "compatible",
668
(char **)&compat, ARRAY_SIZE(compat));
669
}
670
- qemu_fdt_setprop_cells(mc->fdt, name, "reg",
671
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg",
672
0x0, memmap[VIRT_TEST].base, 0x0, memmap[VIRT_TEST].size);
673
- qemu_fdt_setprop_cell(mc->fdt, name, "phandle", test_phandle);
674
- test_phandle = qemu_fdt_get_phandle(mc->fdt, name);
675
+ qemu_fdt_setprop_cell(ms->fdt, name, "phandle", test_phandle);
676
+ test_phandle = qemu_fdt_get_phandle(ms->fdt, name);
677
g_free(name);
678
679
name = g_strdup_printf("/reboot");
680
- qemu_fdt_add_subnode(mc->fdt, name);
681
- qemu_fdt_setprop_string(mc->fdt, name, "compatible", "syscon-reboot");
682
- qemu_fdt_setprop_cell(mc->fdt, name, "regmap", test_phandle);
683
- qemu_fdt_setprop_cell(mc->fdt, name, "offset", 0x0);
684
- qemu_fdt_setprop_cell(mc->fdt, name, "value", FINISHER_RESET);
685
+ qemu_fdt_add_subnode(ms->fdt, name);
686
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon-reboot");
687
+ qemu_fdt_setprop_cell(ms->fdt, name, "regmap", test_phandle);
688
+ qemu_fdt_setprop_cell(ms->fdt, name, "offset", 0x0);
689
+ qemu_fdt_setprop_cell(ms->fdt, name, "value", FINISHER_RESET);
690
g_free(name);
691
692
name = g_strdup_printf("/poweroff");
693
- qemu_fdt_add_subnode(mc->fdt, name);
694
- qemu_fdt_setprop_string(mc->fdt, name, "compatible", "syscon-poweroff");
695
- qemu_fdt_setprop_cell(mc->fdt, name, "regmap", test_phandle);
696
- qemu_fdt_setprop_cell(mc->fdt, name, "offset", 0x0);
697
- qemu_fdt_setprop_cell(mc->fdt, name, "value", FINISHER_PASS);
698
+ qemu_fdt_add_subnode(ms->fdt, name);
699
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible", "syscon-poweroff");
700
+ qemu_fdt_setprop_cell(ms->fdt, name, "regmap", test_phandle);
701
+ qemu_fdt_setprop_cell(ms->fdt, name, "offset", 0x0);
702
+ qemu_fdt_setprop_cell(ms->fdt, name, "value", FINISHER_PASS);
703
g_free(name);
704
}
705
706
@@ -XXX,XX +XXX,XX @@ static void create_fdt_uart(RISCVVirtState *s, const MemMapEntry *memmap,
707
uint32_t irq_mmio_phandle)
708
{
709
char *name;
710
- MachineState *mc = MACHINE(s);
711
+ MachineState *ms = MACHINE(s);
712
713
name = g_strdup_printf("/soc/serial@%lx", (long)memmap[VIRT_UART0].base);
714
- qemu_fdt_add_subnode(mc->fdt, name);
715
- qemu_fdt_setprop_string(mc->fdt, name, "compatible", "ns16550a");
716
- qemu_fdt_setprop_cells(mc->fdt, name, "reg",
717
+ qemu_fdt_add_subnode(ms->fdt, name);
718
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible", "ns16550a");
719
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg",
720
0x0, memmap[VIRT_UART0].base,
721
0x0, memmap[VIRT_UART0].size);
722
- qemu_fdt_setprop_cell(mc->fdt, name, "clock-frequency", 3686400);
723
- qemu_fdt_setprop_cell(mc->fdt, name, "interrupt-parent", irq_mmio_phandle);
724
+ qemu_fdt_setprop_cell(ms->fdt, name, "clock-frequency", 3686400);
725
+ qemu_fdt_setprop_cell(ms->fdt, name, "interrupt-parent", irq_mmio_phandle);
726
if (s->aia_type == VIRT_AIA_TYPE_NONE) {
727
- qemu_fdt_setprop_cell(mc->fdt, name, "interrupts", UART0_IRQ);
728
+ qemu_fdt_setprop_cell(ms->fdt, name, "interrupts", UART0_IRQ);
729
} else {
730
- qemu_fdt_setprop_cells(mc->fdt, name, "interrupts", UART0_IRQ, 0x4);
731
+ qemu_fdt_setprop_cells(ms->fdt, name, "interrupts", UART0_IRQ, 0x4);
732
}
733
734
- qemu_fdt_add_subnode(mc->fdt, "/chosen");
735
- qemu_fdt_setprop_string(mc->fdt, "/chosen", "stdout-path", name);
736
+ qemu_fdt_add_subnode(ms->fdt, "/chosen");
737
+ qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", name);
738
g_free(name);
739
}
740
741
@@ -XXX,XX +XXX,XX @@ static void create_fdt_rtc(RISCVVirtState *s, const MemMapEntry *memmap,
742
uint32_t irq_mmio_phandle)
743
{
744
char *name;
745
- MachineState *mc = MACHINE(s);
746
+ MachineState *ms = MACHINE(s);
747
748
name = g_strdup_printf("/soc/rtc@%lx", (long)memmap[VIRT_RTC].base);
749
- qemu_fdt_add_subnode(mc->fdt, name);
750
- qemu_fdt_setprop_string(mc->fdt, name, "compatible",
751
+ qemu_fdt_add_subnode(ms->fdt, name);
752
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible",
753
"google,goldfish-rtc");
754
- qemu_fdt_setprop_cells(mc->fdt, name, "reg",
755
+ qemu_fdt_setprop_cells(ms->fdt, name, "reg",
756
0x0, memmap[VIRT_RTC].base, 0x0, memmap[VIRT_RTC].size);
757
- qemu_fdt_setprop_cell(mc->fdt, name, "interrupt-parent",
758
+ qemu_fdt_setprop_cell(ms->fdt, name, "interrupt-parent",
759
irq_mmio_phandle);
760
if (s->aia_type == VIRT_AIA_TYPE_NONE) {
761
- qemu_fdt_setprop_cell(mc->fdt, name, "interrupts", RTC_IRQ);
762
+ qemu_fdt_setprop_cell(ms->fdt, name, "interrupts", RTC_IRQ);
763
} else {
764
- qemu_fdt_setprop_cells(mc->fdt, name, "interrupts", RTC_IRQ, 0x4);
765
+ qemu_fdt_setprop_cells(ms->fdt, name, "interrupts", RTC_IRQ, 0x4);
766
}
767
g_free(name);
768
}
769
@@ -XXX,XX +XXX,XX @@ static void create_fdt_rtc(RISCVVirtState *s, const MemMapEntry *memmap,
770
static void create_fdt_flash(RISCVVirtState *s, const MemMapEntry *memmap)
771
{
772
char *name;
773
- MachineState *mc = MACHINE(s);
774
+ MachineState *ms = MACHINE(s);
775
hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2;
776
hwaddr flashbase = virt_memmap[VIRT_FLASH].base;
777
778
name = g_strdup_printf("/flash@%" PRIx64, flashbase);
779
- qemu_fdt_add_subnode(mc->fdt, name);
780
- qemu_fdt_setprop_string(mc->fdt, name, "compatible", "cfi-flash");
781
- qemu_fdt_setprop_sized_cells(mc->fdt, name, "reg",
782
+ qemu_fdt_add_subnode(ms->fdt, name);
783
+ qemu_fdt_setprop_string(ms->fdt, name, "compatible", "cfi-flash");
784
+ qemu_fdt_setprop_sized_cells(ms->fdt, name, "reg",
785
2, flashbase, 2, flashsize,
786
2, flashbase + flashsize, 2, flashsize);
787
- qemu_fdt_setprop_cell(mc->fdt, name, "bank-width", 4);
788
+ qemu_fdt_setprop_cell(ms->fdt, name, "bank-width", 4);
789
g_free(name);
790
}
791
792
static void create_fdt_fw_cfg(RISCVVirtState *s, const MemMapEntry *memmap)
793
{
794
char *nodename;
795
- MachineState *mc = MACHINE(s);
796
+ MachineState *ms = MACHINE(s);
797
hwaddr base = memmap[VIRT_FW_CFG].base;
798
hwaddr size = memmap[VIRT_FW_CFG].size;
799
800
nodename = g_strdup_printf("/fw-cfg@%" PRIx64, base);
801
- qemu_fdt_add_subnode(mc->fdt, nodename);
802
- qemu_fdt_setprop_string(mc->fdt, nodename,
803
+ qemu_fdt_add_subnode(ms->fdt, nodename);
804
+ qemu_fdt_setprop_string(ms->fdt, nodename,
805
"compatible", "qemu,fw-cfg-mmio");
806
- qemu_fdt_setprop_sized_cells(mc->fdt, nodename, "reg",
807
+ qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
808
2, base, 2, size);
809
- qemu_fdt_setprop(mc->fdt, nodename, "dma-coherent", NULL, 0);
810
+ qemu_fdt_setprop(ms->fdt, nodename, "dma-coherent", NULL, 0);
811
g_free(nodename);
812
}
813
814
static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap)
815
{
816
- MachineState *mc = MACHINE(s);
817
+ MachineState *ms = MACHINE(s);
818
uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1;
819
uint32_t irq_pcie_phandle = 1, irq_virtio_phandle = 1;
820
uint8_t rng_seed[32];
821
822
- if (mc->dtb) {
823
- mc->fdt = load_device_tree(mc->dtb, &s->fdt_size);
824
- if (!mc->fdt) {
825
+ if (ms->dtb) {
826
+ ms->fdt = load_device_tree(ms->dtb, &s->fdt_size);
827
+ if (!ms->fdt) {
828
error_report("load_device_tree() failed");
829
exit(1);
830
}
831
} else {
832
- mc->fdt = create_device_tree(&s->fdt_size);
833
- if (!mc->fdt) {
834
+ ms->fdt = create_device_tree(&s->fdt_size);
835
+ if (!ms->fdt) {
836
error_report("create_device_tree() failed");
837
exit(1);
838
}
172
}
839
}
173
}
840
174
841
- qemu_fdt_setprop_string(mc->fdt, "/", "model", "riscv-virtio,qemu");
175
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
842
- qemu_fdt_setprop_string(mc->fdt, "/", "compatible", "riscv-virtio");
176
}
843
- qemu_fdt_setprop_cell(mc->fdt, "/", "#size-cells", 0x2);
177
}
844
- qemu_fdt_setprop_cell(mc->fdt, "/", "#address-cells", 0x2);
178
845
+ qemu_fdt_setprop_string(ms->fdt, "/", "model", "riscv-virtio,qemu");
179
+ if (virt_use_kvm_aia(s)) {
846
+ qemu_fdt_setprop_string(ms->fdt, "/", "compatible", "riscv-virtio");
180
+ kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT,
847
+ qemu_fdt_setprop_cell(ms->fdt, "/", "#size-cells", 0x2);
181
+ VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS,
848
+ qemu_fdt_setprop_cell(ms->fdt, "/", "#address-cells", 0x2);
182
+ memmap[VIRT_APLIC_S].base,
849
183
+ memmap[VIRT_IMSIC_S].base,
850
- qemu_fdt_add_subnode(mc->fdt, "/soc");
184
+ s->aia_guests);
851
- qemu_fdt_setprop(mc->fdt, "/soc", "ranges", NULL, 0);
185
+ }
852
- qemu_fdt_setprop_string(mc->fdt, "/soc", "compatible", "simple-bus");
186
+
853
- qemu_fdt_setprop_cell(mc->fdt, "/soc", "#size-cells", 0x2);
187
if (riscv_is_32bit(&s->soc[0])) {
854
- qemu_fdt_setprop_cell(mc->fdt, "/soc", "#address-cells", 0x2);
188
#if HOST_LONG_BITS == 64
855
+ qemu_fdt_add_subnode(ms->fdt, "/soc");
189
/* limit RAM size in a 32-bit system */
856
+ qemu_fdt_setprop(ms->fdt, "/soc", "ranges", NULL, 0);
857
+ qemu_fdt_setprop_string(ms->fdt, "/soc", "compatible", "simple-bus");
858
+ qemu_fdt_setprop_cell(ms->fdt, "/soc", "#size-cells", 0x2);
859
+ qemu_fdt_setprop_cell(ms->fdt, "/soc", "#address-cells", 0x2);
860
861
create_fdt_sockets(s, memmap, &phandle, &irq_mmio_phandle,
862
&irq_pcie_phandle, &irq_virtio_phandle,
863
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap)
864
865
/* Pass seed to RNG */
866
qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
867
- qemu_fdt_setprop(mc->fdt, "/chosen", "rng-seed",
868
+ qemu_fdt_setprop(ms->fdt, "/chosen", "rng-seed",
869
rng_seed, sizeof(rng_seed));
870
}
871
872
@@ -XXX,XX +XXX,XX @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
873
return dev;
874
}
875
876
-static FWCfgState *create_fw_cfg(const MachineState *mc)
877
+static FWCfgState *create_fw_cfg(const MachineState *ms)
878
{
879
hwaddr base = virt_memmap[VIRT_FW_CFG].base;
880
FWCfgState *fw_cfg;
881
882
fw_cfg = fw_cfg_init_mem_wide(base + 8, base, 8, base + 16,
883
&address_space_memory);
884
- fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)mc->smp.cpus);
885
+ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)ms->smp.cpus);
886
887
return fw_cfg;
888
}
889
--
190
--
890
2.39.1
191
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Conor Dooley <conor.dooley@microchip.com>
2
2
3
As it is now, riscv_compute_fdt_addr() is receiving a dram_base, a
3
On a dtb dumped from the virt machine, dt-validate complains:
4
mem_size (which is defaulted to MachineState::ram_size in all boards)
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
and the FDT pointer. And it makes a very important assumption: the DRAM
5
from schema $id: http://devicetree.org/schemas/simple-bus.yaml#
6
interval dram_base + mem_size is contiguous. This is indeed the case for
6
That's pretty cryptic, but running the dtb back through dtc produces
7
most boards that use a FDT.
7
something a lot more reasonable:
8
Warning (simple_bus_reg): /soc/pmu: missing or empty reg/ranges property
8
9
9
The Icicle Kit board works with 2 distinct RAM banks that are separated
10
Moving the riscv,pmu node out of the soc bus solves the problem.
10
by a gap. We have a lower bank with 1GiB size, a gap follows, then at
11
64GiB the high memory starts. MachineClass::default_ram_size for this
12
board is set to 1.5Gb, and machine_init() is enforcing it as minimal RAM
13
size, meaning that there we'll always have at least 512 MiB in the Hi
14
RAM area.
15
11
16
Using riscv_compute_fdt_addr() in this board is weird because not only
12
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
17
the board has sparse RAM, and it's calling it using the base address of
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
18
the Lo RAM area, but it's also using a mem_size that we have guarantees
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
19
that it will go up to the Hi RAM. All the function assumptions doesn't
15
Message-ID: <20230727-groom-decline-2c57ce42841c@spud>
20
work for this board.
21
22
In fact, what makes the function works at all in this case is a
23
coincidence. Commit 1a475d39ef54 introduced a 3GB boundary for the FDT,
24
down from 4Gb, that is enforced if dram_base is lower than 3072 MiB. For
25
the Icicle Kit board, memmap[MICROCHIP_PFSOC_DRAM_LO].base is 0x80000000
26
(2 Gb) and it has a 1Gb size, so it will fall in the conditions to put
27
the FDT under a 3Gb address, which happens to be exactly at the end of
28
DRAM_LO. If the base address of the Lo area started later than 3Gb this
29
function would be unusable by the board. Changing any assumptions inside
30
riscv_compute_fdt_addr() can also break it by accident as well.
31
32
Let's change riscv_compute_fdt_addr() semantics to be appropriate to the
33
Icicle Kit board and for future boards that might have sparse RAM
34
topologies to worry about:
35
36
- relieve the condition that the dram_base + mem_size area is contiguous,
37
since this is already not the case today;
38
39
- receive an extra 'dram_size' size attribute that refers to a contiguous
40
RAM block that the board wants the FDT to reside on.
41
42
Together with 'mem_size' and 'fdt', which are now now being consumed by a
43
MachineState pointer, we're able to make clear assumptions based on the
44
DRAM block and total mem_size available to ensure that the FDT will be put
45
in a valid RAM address.
46
47
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
48
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
49
Message-Id: <20230201171212.1219375-4-dbarboza@ventanamicro.com>
50
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
51
---
17
---
52
include/hw/riscv/boot.h | 2 +-
18
hw/riscv/virt.c | 2 +-
53
hw/riscv/boot.c | 35 +++++++++++++++++++++++------------
19
1 file changed, 1 insertion(+), 1 deletion(-)
54
hw/riscv/microchip_pfsoc.c | 3 ++-
55
hw/riscv/sifive_u.c | 3 ++-
56
hw/riscv/spike.c | 3 ++-
57
hw/riscv/virt.c | 3 ++-
58
6 files changed, 32 insertions(+), 17 deletions(-)
59
20
60
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
61
index XXXXXXX..XXXXXXX 100644
62
--- a/include/hw/riscv/boot.h
63
+++ b/include/hw/riscv/boot.h
64
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(MachineState *machine,
65
symbol_fn_t sym_cb);
66
void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry);
67
uint64_t riscv_compute_fdt_addr(hwaddr dram_start, uint64_t dram_size,
68
- void *fdt);
69
+ MachineState *ms);
70
void riscv_load_fdt(hwaddr fdt_addr, void *fdt);
71
void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts,
72
hwaddr saddr,
73
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/riscv/boot.c
76
+++ b/hw/riscv/boot.c
77
@@ -XXX,XX +XXX,XX @@ void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
78
}
79
80
/*
81
- * The FDT should be put at the farthest point possible to
82
- * avoid overwriting it with the kernel/initrd.
83
+ * This function makes an assumption that the DRAM interval
84
+ * 'dram_base' + 'dram_size' is contiguous.
85
*
86
- * This function makes an assumption that the DRAM is
87
- * contiguous. It also cares about 32-bit systems and
88
- * will limit fdt_addr to be addressable by them even for
89
- * 64-bit CPUs.
90
+ * Considering that 'dram_end' is the lowest value between
91
+ * the end of the DRAM block and MachineState->ram_size, the
92
+ * FDT location will vary according to 'dram_base':
93
+ *
94
+ * - if 'dram_base' is less that 3072 MiB, the FDT will be
95
+ * put at the lowest value between 3072 MiB and 'dram_end';
96
+ *
97
+ * - if 'dram_base' is higher than 3072 MiB, the FDT will be
98
+ * put at 'dram_end'.
99
*
100
* The FDT is fdt_packed() during the calculation.
101
*/
102
-uint64_t riscv_compute_fdt_addr(hwaddr dram_base, uint64_t mem_size,
103
- void *fdt)
104
+uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size,
105
+ MachineState *ms)
106
{
107
- uint64_t temp;
108
- hwaddr dram_end = dram_base + mem_size;
109
- int ret = fdt_pack(fdt);
110
+ int ret = fdt_pack(ms->fdt);
111
+ hwaddr dram_end, temp;
112
int fdtsize;
113
114
/* Should only fail if we've built a corrupted tree */
115
g_assert(ret == 0);
116
117
- fdtsize = fdt_totalsize(fdt);
118
+ fdtsize = fdt_totalsize(ms->fdt);
119
if (fdtsize <= 0) {
120
error_report("invalid device-tree");
121
exit(1);
122
}
123
124
+ /*
125
+ * A dram_size == 0, usually from a MemMapEntry[].size element,
126
+ * means that the DRAM block goes all the way to ms->ram_size.
127
+ */
128
+ dram_end = dram_base;
129
+ dram_end += dram_size ? MIN(ms->ram_size, dram_size) : ms->ram_size;
130
+
131
/*
132
* We should put fdt as far as possible to avoid kernel/initrd overwriting
133
* its content. But it should be addressable by 32 bit system as well.
134
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
135
index XXXXXXX..XXXXXXX 100644
136
--- a/hw/riscv/microchip_pfsoc.c
137
+++ b/hw/riscv/microchip_pfsoc.c
138
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
139
140
/* Compute the fdt load address in dram */
141
fdt_load_addr = riscv_compute_fdt_addr(memmap[MICROCHIP_PFSOC_DRAM_LO].base,
142
- machine->ram_size, machine->fdt);
143
+ memmap[MICROCHIP_PFSOC_DRAM_LO].size,
144
+ machine);
145
riscv_load_fdt(fdt_load_addr, machine->fdt);
146
147
/* Load the reset vector */
148
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/hw/riscv/sifive_u.c
151
+++ b/hw/riscv/sifive_u.c
152
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
153
}
154
155
fdt_load_addr = riscv_compute_fdt_addr(memmap[SIFIVE_U_DEV_DRAM].base,
156
- machine->ram_size, machine->fdt);
157
+ memmap[SIFIVE_U_DEV_DRAM].size,
158
+ machine);
159
riscv_load_fdt(fdt_load_addr, machine->fdt);
160
161
if (!riscv_is_32bit(&s->soc.u_cpus)) {
162
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
163
index XXXXXXX..XXXXXXX 100644
164
--- a/hw/riscv/spike.c
165
+++ b/hw/riscv/spike.c
166
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
167
}
168
169
fdt_load_addr = riscv_compute_fdt_addr(memmap[SPIKE_DRAM].base,
170
- machine->ram_size, machine->fdt);
171
+ memmap[SPIKE_DRAM].size,
172
+ machine);
173
riscv_load_fdt(fdt_load_addr, machine->fdt);
174
175
/* load the reset vector */
176
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
21
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
177
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
178
--- a/hw/riscv/virt.c
23
--- a/hw/riscv/virt.c
179
+++ b/hw/riscv/virt.c
24
+++ b/hw/riscv/virt.c
180
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
25
@@ -XXX,XX +XXX,XX @@ static void create_fdt_pmu(RISCVVirtState *s)
181
}
26
MachineState *ms = MACHINE(s);
182
27
RISCVCPU hart = s->soc[0].harts[0];
183
fdt_load_addr = riscv_compute_fdt_addr(memmap[VIRT_DRAM].base,
28
184
- machine->ram_size, machine->fdt);
29
- pmu_name = g_strdup_printf("/soc/pmu");
185
+ memmap[VIRT_DRAM].size,
30
+ pmu_name = g_strdup_printf("/pmu");
186
+ machine);
31
qemu_fdt_add_subnode(ms->fdt, pmu_name);
187
riscv_load_fdt(fdt_load_addr, machine->fdt);
32
qemu_fdt_setprop_string(ms->fdt, pmu_name, "compatible", "riscv,pmu");
188
33
riscv_pmu_generate_fdt_node(ms->fdt, hart.cfg.pmu_num, pmu_name);
189
/* load the reset vector */
190
--
34
--
191
2.39.1
35
2.41.0
diff view generated by jsdifflib
1
From: Anup Patel <apatel@ventanamicro.com>
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
2
2
3
Instead of clearing mask in riscv_cpu_update_mip() for VSTIP, we
3
The Svadu specification updated the name of the *envcfg bit from
4
should call riscv_cpu_update_mip() with mask == 0 from timer_helper.c
4
HADE to ADUE.
5
for VSTIP.
6
5
7
Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp suppor")
6
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
7
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Message-Id: <20230120125950.2246378-3-apatel@ventanamicro.com>
9
Message-ID: <20230816141916.66898-1-liweiwei@iscas.ac.cn>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
11
---
13
target/riscv/cpu_helper.c | 2 --
12
target/riscv/cpu_bits.h | 8 ++++----
14
target/riscv/time_helper.c | 12 ++++++++----
13
target/riscv/cpu.c | 4 ++--
15
2 files changed, 8 insertions(+), 6 deletions(-)
14
target/riscv/cpu_helper.c | 6 +++---
15
target/riscv/csr.c | 12 ++++++------
16
4 files changed, 15 insertions(+), 15 deletions(-)
16
17
18
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/cpu_bits.h
21
+++ b/target/riscv/cpu_bits.h
22
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
23
#define MENVCFG_CBIE (3UL << 4)
24
#define MENVCFG_CBCFE BIT(6)
25
#define MENVCFG_CBZE BIT(7)
26
-#define MENVCFG_HADE (1ULL << 61)
27
+#define MENVCFG_ADUE (1ULL << 61)
28
#define MENVCFG_PBMTE (1ULL << 62)
29
#define MENVCFG_STCE (1ULL << 63)
30
31
/* For RV32 */
32
-#define MENVCFGH_HADE BIT(29)
33
+#define MENVCFGH_ADUE BIT(29)
34
#define MENVCFGH_PBMTE BIT(30)
35
#define MENVCFGH_STCE BIT(31)
36
37
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
38
#define HENVCFG_CBIE MENVCFG_CBIE
39
#define HENVCFG_CBCFE MENVCFG_CBCFE
40
#define HENVCFG_CBZE MENVCFG_CBZE
41
-#define HENVCFG_HADE MENVCFG_HADE
42
+#define HENVCFG_ADUE MENVCFG_ADUE
43
#define HENVCFG_PBMTE MENVCFG_PBMTE
44
#define HENVCFG_STCE MENVCFG_STCE
45
46
/* For RV32 */
47
-#define HENVCFGH_HADE MENVCFGH_HADE
48
+#define HENVCFGH_ADUE MENVCFGH_ADUE
49
#define HENVCFGH_PBMTE MENVCFGH_PBMTE
50
#define HENVCFGH_STCE MENVCFGH_STCE
51
52
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/riscv/cpu.c
55
+++ b/target/riscv/cpu.c
56
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj)
57
env->two_stage_lookup = false;
58
59
env->menvcfg = (cpu->cfg.ext_svpbmt ? MENVCFG_PBMTE : 0) |
60
- (cpu->cfg.ext_svadu ? MENVCFG_HADE : 0);
61
+ (cpu->cfg.ext_svadu ? MENVCFG_ADUE : 0);
62
env->henvcfg = (cpu->cfg.ext_svpbmt ? HENVCFG_PBMTE : 0) |
63
- (cpu->cfg.ext_svadu ? HENVCFG_HADE : 0);
64
+ (cpu->cfg.ext_svadu ? HENVCFG_ADUE : 0);
65
66
/* Initialized default priorities of local interrupts. */
67
for (i = 0; i < ARRAY_SIZE(env->miprio); i++) {
17
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
68
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
18
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu_helper.c
70
--- a/target/riscv/cpu_helper.c
20
+++ b/target/riscv/cpu_helper.c
71
+++ b/target/riscv/cpu_helper.c
21
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value)
72
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
22
vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
23
}
73
}
24
74
25
- /* No need to update mip for VSTIP */
75
bool pbmte = env->menvcfg & MENVCFG_PBMTE;
26
- mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask;
76
- bool hade = env->menvcfg & MENVCFG_HADE;
27
vstip = env->vstime_irq ? MIP_VSTIP : 0;
77
+ bool adue = env->menvcfg & MENVCFG_ADUE;
28
78
29
QEMU_IOTHREAD_LOCK_GUARD();
79
if (first_stage && two_stage && env->virt_enabled) {
30
diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
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
31
index XXXXXXX..XXXXXXX 100644
96
index XXXXXXX..XXXXXXX 100644
32
--- a/target/riscv/time_helper.c
97
--- a/target/riscv/csr.c
33
+++ b/target/riscv/time_helper.c
98
+++ b/target/riscv/csr.c
34
@@ -XXX,XX +XXX,XX @@ static void riscv_vstimer_cb(void *opaque)
99
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
35
RISCVCPU *cpu = opaque;
100
if (riscv_cpu_mxl(env) == MXL_RV64) {
36
CPURISCVState *env = &cpu->env;
101
mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
37
env->vstime_irq = 1;
102
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
38
- riscv_cpu_update_mip(cpu, MIP_VSTIP, BOOL_TO_MASK(1));
103
- (cfg->ext_svadu ? MENVCFG_HADE : 0);
39
+ riscv_cpu_update_mip(cpu, 0, BOOL_TO_MASK(1));
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;
40
}
125
}
41
126
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
42
static void riscv_stimer_cb(void *opaque)
43
@@ -XXX,XX +XXX,XX @@ void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer,
44
*/
45
if (timer_irq == MIP_VSTIP) {
46
env->vstime_irq = 1;
47
+ riscv_cpu_update_mip(cpu, 0, BOOL_TO_MASK(1));
48
+ } else {
49
+ riscv_cpu_update_mip(cpu, MIP_STIP, BOOL_TO_MASK(1));
50
}
51
- riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(1));
52
return;
53
}
127
}
54
128
55
+ /* Clear the [VS|S]TIP bit in mip */
129
if (riscv_cpu_mxl(env) == MXL_RV64) {
56
if (timer_irq == MIP_VSTIP) {
130
- mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE);
57
env->vstime_irq = 0;
131
+ mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE);
58
+ riscv_cpu_update_mip(cpu, 0, BOOL_TO_MASK(0));
59
+ } else {
60
+ riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
61
}
132
}
62
- /* Clear the [V]STIP bit in mip */
133
63
- riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
134
env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
64
135
@@ -XXX,XX +XXX,XX @@ static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
65
/* otherwise, set up the future timer interrupt */
136
return ret;
66
diff = timecmp - rtc_r;
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
67
--
153
--
68
2.39.1
154
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Follow the QEMU convention of naming MachineState pointers as 'ms' by
3
In the same emulated RISC-V host, the 'host' KVM CPU takes 4 times
4
renaming the instances where we're calling it 'mc'.
4
longer to boot than the 'rv64' KVM CPU.
5
5
6
Suggested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
The reason is an unintended behavior of riscv_cpu_satp_mode_finalize()
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
when satp_mode.supported = 0, i.e. when cpu_init() does not set
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
satp_mode_max_supported(). satp_mode_max_from_map(map) does:
9
10
31 - __builtin_clz(map)
11
12
This means that, if satp_mode.supported = 0, satp_mode_supported_max
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
16
17
cfg.satp_mode.map = cfg.satp_mode.supported
18
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")
9
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
41
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Message-Id: <20230124212234.412630-4-dbarboza@ventanamicro.com>
42
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
43
Message-ID: <20230817152903.694926-1-dbarboza@ventanamicro.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
44
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
45
---
13
hw/riscv/spike.c | 18 +++++++++---------
46
target/riscv/cpu.c | 23 ++++++++++++++++++++---
14
1 file changed, 9 insertions(+), 9 deletions(-)
47
1 file changed, 20 insertions(+), 3 deletions(-)
15
48
16
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
49
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
17
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/spike.c
51
--- a/target/riscv/cpu.c
19
+++ b/hw/riscv/spike.c
52
+++ b/target/riscv/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
53
@@ -XXX,XX +XXX,XX @@ static uint8_t satp_mode_from_str(const char *satp_mode_str)
21
uint64_t addr, size;
54
22
unsigned long clint_addr;
55
uint8_t satp_mode_max_from_map(uint32_t map)
23
int cpu, socket;
56
{
24
- MachineState *mc = MACHINE(s);
57
+ /*
25
+ MachineState *ms = MACHINE(s);
58
+ * 'map = 0' will make us return (31 - 32), which C will
26
uint32_t *clint_cells;
59
+ * happily overflow to UINT_MAX. There's no good result to
27
uint32_t cpu_phandle, intc_phandle, phandle = 1;
60
+ * return if 'map = 0' (e.g. returning 0 will be ambiguous
28
char *name, *mem_name, *clint_name, *clust_name;
61
+ * with the result for 'map = 1').
29
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
62
+ *
30
"sifive,clint0", "riscv,clint0"
63
+ * Assert out if map = 0. Callers will have to deal with
31
};
64
+ * it outside of this function.
32
65
+ */
33
- fdt = mc->fdt = create_device_tree(&fdt_size);
66
+ g_assert(map > 0);
34
+ fdt = ms->fdt = create_device_tree(&fdt_size);
67
+
35
if (!fdt) {
68
/* map here has at least one bit set, so no problem with clz */
36
error_report("create_device_tree() failed");
69
return 31 - __builtin_clz(map);
37
exit(1);
70
}
38
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
71
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
39
qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
72
static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
40
qemu_fdt_add_subnode(fdt, "/cpus/cpu-map");
73
{
41
74
bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
42
- for (socket = (riscv_socket_count(mc) - 1); socket >= 0; socket--) {
75
- uint8_t satp_mode_map_max;
43
+ for (socket = (riscv_socket_count(ms) - 1); socket >= 0; socket--) {
76
- uint8_t satp_mode_supported_max =
44
clust_name = g_strdup_printf("/cpus/cpu-map/cluster%d", socket);
77
- satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
45
qemu_fdt_add_subnode(fdt, clust_name);
78
+ uint8_t satp_mode_map_max, satp_mode_supported_max;
46
79
+
47
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
80
+ /* The CPU wants the OS to decide which satp mode to use */
48
qemu_fdt_setprop_cell(fdt, cpu_name, "reg",
81
+ if (cpu->cfg.satp_mode.supported == 0) {
49
s->soc[socket].hartid_base + cpu);
82
+ return;
50
qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu");
83
+ }
51
- riscv_socket_fdt_write_id(mc, cpu_name, socket);
84
+
52
+ riscv_socket_fdt_write_id(ms, cpu_name, socket);
85
+ satp_mode_supported_max =
53
qemu_fdt_setprop_cell(fdt, cpu_name, "phandle", cpu_phandle);
86
+ satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
54
87
55
intc_name = g_strdup_printf("%s/interrupt-controller", cpu_name);
88
if (cpu->cfg.satp_mode.map == 0) {
56
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
89
if (cpu->cfg.satp_mode.init == 0) {
57
g_free(cpu_name);
58
}
59
60
- addr = memmap[SPIKE_DRAM].base + riscv_socket_mem_offset(mc, socket);
61
- size = riscv_socket_mem_size(mc, socket);
62
+ addr = memmap[SPIKE_DRAM].base + riscv_socket_mem_offset(ms, socket);
63
+ size = riscv_socket_mem_size(ms, socket);
64
mem_name = g_strdup_printf("/memory@%lx", (long)addr);
65
qemu_fdt_add_subnode(fdt, mem_name);
66
qemu_fdt_setprop_cells(fdt, mem_name, "reg",
67
addr >> 32, addr, size >> 32, size);
68
qemu_fdt_setprop_string(fdt, mem_name, "device_type", "memory");
69
- riscv_socket_fdt_write_id(mc, mem_name, socket);
70
+ riscv_socket_fdt_write_id(ms, mem_name, socket);
71
g_free(mem_name);
72
73
clint_addr = memmap[SPIKE_CLINT].base +
74
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
75
0x0, clint_addr, 0x0, memmap[SPIKE_CLINT].size);
76
qemu_fdt_setprop(fdt, clint_name, "interrupts-extended",
77
clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
78
- riscv_socket_fdt_write_id(mc, clint_name, socket);
79
+ riscv_socket_fdt_write_id(ms, clint_name, socket);
80
81
g_free(clint_name);
82
g_free(clint_cells);
83
g_free(clust_name);
84
}
85
86
- riscv_socket_fdt_write_distance_matrix(mc);
87
+ riscv_socket_fdt_write_distance_matrix(ms);
88
89
qemu_fdt_add_subnode(fdt, "/chosen");
90
qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", "/htif");
91
--
90
--
92
2.39.1
91
2.41.0
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Vineet Gupta <vineetg@rivosinc.com>
2
2
3
There are no differences for floating point instructions in priv version 1.11
3
zicond is now codegen supported in both llvm and gcc.
4
and 1.12. There is also no dependency for Zfh to priv version 1.12.
5
Therefore allow Zfh to be enabled for priv version 1.11.
6
4
7
Acked-by: Alistair Francis <alistair.francis@wdc.com>
5
This change allows seamless enabling/testing of zicond in downstream
8
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
6
projects. e.g. currently riscv-gnu-toolchain parses elf attributes
9
Message-Id: <20230131202013.2541053-12-christoph.muellner@vrull.eu>
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>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.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/cpu.c | 2 +-
15
target/riscv/cpu.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
16
1 file changed, 1 insertion(+), 1 deletion(-)
14
17
15
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
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu.c
20
--- a/target/riscv/cpu.c
18
+++ b/target/riscv/cpu.c
21
+++ b/target/riscv/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
22
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
20
ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei),
23
DEFINE_PROP_BOOL("zcf", RISCVCPU, cfg.ext_zcf, false),
21
ISA_EXT_DATA_ENTRY(zihintpause, true, PRIV_VERSION_1_10_0, ext_zihintpause),
24
DEFINE_PROP_BOOL("zcmp", RISCVCPU, cfg.ext_zcmp, false),
22
ISA_EXT_DATA_ENTRY(zawrs, true, PRIV_VERSION_1_12_0, ext_zawrs),
25
DEFINE_PROP_BOOL("zcmt", RISCVCPU, cfg.ext_zcmt, false),
23
- ISA_EXT_DATA_ENTRY(zfh, true, PRIV_VERSION_1_12_0, ext_zfh),
26
+ DEFINE_PROP_BOOL("zicond", RISCVCPU, cfg.ext_zicond, false),
24
+ ISA_EXT_DATA_ENTRY(zfh, true, PRIV_VERSION_1_11_0, ext_zfh),
27
25
ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
28
/* Vendor-specific custom extensions */
26
ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
29
DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
27
ISA_EXT_DATA_ENTRY(zdinx, true, PRIV_VERSION_1_12_0, ext_zdinx),
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),
28
--
38
--
29
2.39.1
39
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
riscv_socket_count() returns either ms->numa_state->num_nodes or 1
3
A build with --enable-debug and without KVM will fail as follows:
4
depending on NUMA support. In any case the value can be retrieved only
5
once and used in the rest of the function.
6
4
7
This will also alleviate the rename we're going to do next by reducing
5
/usr/bin/ld: libqemu-riscv64-softmmu.fa.p/hw_riscv_virt.c.o: in function `virt_machine_init':
8
the instances of MachineState 'mc' inside hw/riscv/virt.c.
6
./qemu/build/../hw/riscv/virt.c:1465: undefined reference to `kvm_riscv_aia_create'
9
7
8
This happens because the code block with "if virt_use_kvm_aia(s)" isn't
9
being ignored by the debug build, resulting in an undefined reference to
10
a KVM only function.
11
12
Add a 'kvm_enabled()' conditional together with virt_use_kvm_aia() will
13
make the compiler crop the kvm_riscv_aia_create() call entirely from a
14
non-KVM build. Note that adding the 'kvm_enabled()' conditional inside
15
virt_use_kvm_aia() won't fix the build because this function would need
16
to be inlined multiple times to make the compiler zero out the entire
17
block.
18
19
While we're at it, use kvm_enabled() in all instances where
20
virt_use_kvm_aia() is checked to allow the compiler to elide these other
21
kvm-only instances as well.
22
23
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
24
Fixes: dbdb99948e ("target/riscv: select KVM AIA in riscv virt machine")
25
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
26
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
27
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
29
Message-ID: <20230830133503.711138-2-dbarboza@ventanamicro.com>
13
Message-Id: <20230124212234.412630-2-dbarboza@ventanamicro.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
31
---
16
hw/riscv/virt.c | 34 +++++++++++++++++++---------------
32
hw/riscv/virt.c | 6 +++---
17
1 file changed, 19 insertions(+), 15 deletions(-)
33
1 file changed, 3 insertions(+), 3 deletions(-)
18
34
19
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
35
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
20
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/riscv/virt.c
37
--- a/hw/riscv/virt.c
22
+++ b/hw/riscv/virt.c
38
+++ b/hw/riscv/virt.c
23
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
24
int cpu, socket;
25
char *imsic_name;
26
MachineState *mc = MACHINE(s);
27
+ int socket_count = riscv_socket_count(mc);
28
uint32_t imsic_max_hart_per_socket, imsic_guest_bits;
29
uint32_t *imsic_cells, *imsic_regs, imsic_addr, imsic_size;
30
31
*msi_m_phandle = (*phandle)++;
32
*msi_s_phandle = (*phandle)++;
33
imsic_cells = g_new0(uint32_t, mc->smp.cpus * 2);
34
- imsic_regs = g_new0(uint32_t, riscv_socket_count(mc) * 4);
35
+ imsic_regs = g_new0(uint32_t, socket_count * 4);
36
37
/* M-level IMSIC node */
38
for (cpu = 0; cpu < mc->smp.cpus; cpu++) {
39
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
40
imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
41
}
42
imsic_max_hart_per_socket = 0;
43
- for (socket = 0; socket < riscv_socket_count(mc); socket++) {
44
+ for (socket = 0; socket < socket_count; socket++) {
45
imsic_addr = memmap[VIRT_IMSIC_M].base +
46
socket * VIRT_IMSIC_GROUP_MAX_SIZE;
47
imsic_size = IMSIC_HART_SIZE(0) * s->soc[socket].num_harts;
48
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
49
qemu_fdt_setprop(mc->fdt, imsic_name, "interrupts-extended",
50
imsic_cells, mc->smp.cpus * sizeof(uint32_t) * 2);
51
qemu_fdt_setprop(mc->fdt, imsic_name, "reg", imsic_regs,
52
- riscv_socket_count(mc) * sizeof(uint32_t) * 4);
53
+ socket_count * sizeof(uint32_t) * 4);
54
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
55
VIRT_IRQCHIP_NUM_MSIS);
56
- if (riscv_socket_count(mc) > 1) {
57
+ if (socket_count > 1) {
58
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits",
59
imsic_num_bits(imsic_max_hart_per_socket));
60
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-bits",
61
- imsic_num_bits(riscv_socket_count(mc)));
62
+ imsic_num_bits(socket_count));
63
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-shift",
64
IMSIC_MMIO_GROUP_MIN_SHIFT);
65
}
66
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
67
}
68
imsic_guest_bits = imsic_num_bits(s->aia_guests + 1);
69
imsic_max_hart_per_socket = 0;
70
- for (socket = 0; socket < riscv_socket_count(mc); socket++) {
71
+ for (socket = 0; socket < socket_count; socket++) {
72
imsic_addr = memmap[VIRT_IMSIC_S].base +
73
socket * VIRT_IMSIC_GROUP_MAX_SIZE;
74
imsic_size = IMSIC_HART_SIZE(imsic_guest_bits) *
75
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
76
qemu_fdt_setprop(mc->fdt, imsic_name, "interrupts-extended",
77
imsic_cells, mc->smp.cpus * sizeof(uint32_t) * 2);
78
qemu_fdt_setprop(mc->fdt, imsic_name, "reg", imsic_regs,
79
- riscv_socket_count(mc) * sizeof(uint32_t) * 4);
80
+ socket_count * sizeof(uint32_t) * 4);
81
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
82
VIRT_IRQCHIP_NUM_MSIS);
83
if (imsic_guest_bits) {
84
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,guest-index-bits",
85
imsic_guest_bits);
86
}
87
- if (riscv_socket_count(mc) > 1) {
88
+ if (socket_count > 1) {
89
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits",
90
imsic_num_bits(imsic_max_hart_per_socket));
91
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-bits",
92
- imsic_num_bits(riscv_socket_count(mc)));
93
+ imsic_num_bits(socket_count));
94
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,group-index-shift",
95
IMSIC_MMIO_GROUP_MIN_SHIFT);
96
}
97
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
98
MachineState *mc = MACHINE(s);
99
uint32_t msi_m_phandle = 0, msi_s_phandle = 0;
100
uint32_t *intc_phandles, xplic_phandles[MAX_NODES];
101
+ int socket_count = riscv_socket_count(mc);
102
103
qemu_fdt_add_subnode(mc->fdt, "/cpus");
104
qemu_fdt_setprop_cell(mc->fdt, "/cpus", "timebase-frequency",
105
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
106
intc_phandles = g_new0(uint32_t, mc->smp.cpus);
107
108
phandle_pos = mc->smp.cpus;
109
- for (socket = (riscv_socket_count(mc) - 1); socket >= 0; socket--) {
110
+ for (socket = (socket_count - 1); socket >= 0; socket--) {
111
phandle_pos -= s->soc[socket].num_harts;
112
113
clust_name = g_strdup_printf("/cpus/cpu-map/cluster%d", socket);
114
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
39
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
115
}
40
}
116
41
117
phandle_pos = mc->smp.cpus;
42
/* KVM AIA only has one APLIC instance */
118
- for (socket = (riscv_socket_count(mc) - 1); socket >= 0; socket--) {
43
- if (virt_use_kvm_aia(s)) {
119
+ for (socket = (socket_count - 1); socket >= 0; socket--) {
44
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
120
phandle_pos -= s->soc[socket].num_harts;
45
create_fdt_socket_aplic(s, memmap, 0,
121
46
msi_m_phandle, msi_s_phandle, phandle,
122
if (s->aia_type == VIRT_AIA_TYPE_NONE) {
47
&intc_phandles[0], xplic_phandles,
123
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
48
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
124
49
125
g_free(intc_phandles);
50
g_free(intc_phandles);
126
51
127
- for (socket = 0; socket < riscv_socket_count(mc); socket++) {
52
- if (virt_use_kvm_aia(s)) {
128
+ for (socket = 0; socket < socket_count; socket++) {
53
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
129
if (socket == 0) {
54
*irq_mmio_phandle = xplic_phandles[0];
130
*irq_mmio_phandle = xplic_phandles[socket];
55
*irq_virtio_phandle = xplic_phandles[0];
131
*irq_virtio_phandle = xplic_phandles[socket];
56
*irq_pcie_phandle = xplic_phandles[0];
132
@@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap)
133
134
/* Pass seed to RNG */
135
qemu_guest_getrandom_nofail(rng_seed, sizeof(rng_seed));
136
- qemu_fdt_setprop(mc->fdt, "/chosen", "rng-seed", rng_seed, sizeof(rng_seed));
137
+ qemu_fdt_setprop(mc->fdt, "/chosen", "rng-seed",
138
+ rng_seed, sizeof(rng_seed));
139
}
140
141
static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
142
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
57
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
143
char *soc_name;
58
}
144
DeviceState *mmio_irqchip, *virtio_irqchip, *pcie_irqchip;
59
}
145
int i, base_hartid, hart_count;
60
146
+ int socket_count = riscv_socket_count(machine);
61
- if (virt_use_kvm_aia(s)) {
147
62
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
148
/* Check socket count limit */
63
kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT,
149
- if (VIRT_SOCKETS_MAX < riscv_socket_count(machine)) {
64
VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS,
150
+ if (VIRT_SOCKETS_MAX < socket_count) {
65
memmap[VIRT_APLIC_S].base,
151
error_report("number of sockets/nodes should be less than %d",
152
VIRT_SOCKETS_MAX);
153
exit(1);
154
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
155
156
/* Initialize sockets */
157
mmio_irqchip = virtio_irqchip = pcie_irqchip = NULL;
158
- for (i = 0; i < riscv_socket_count(machine); i++) {
159
+ for (i = 0; i < socket_count; i++) {
160
if (!riscv_socket_check_hartids(machine, i)) {
161
error_report("discontinuous hartids in socket%d", i);
162
exit(1);
163
--
66
--
164
2.39.1
67
2.41.0
68
69
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
A common trend in other archs is to calculate the fdt address, which is
3
Commit 6df0b37e2ab breaks a --enable-debug build in a non-KVM
4
usually straightforward, and then calling a function that loads the
4
environment with the following error:
5
fdt/dtb by using that address.
6
5
7
riscv_load_fdt() is doing a bit too much in comparison. It's calculating
6
/usr/bin/ld: libqemu-riscv64-softmmu.fa.p/hw_intc_riscv_aplic.c.o: in function `riscv_kvm_aplic_request':
8
the fdt address via an elaborated heuristic to put the FDT at the bottom
7
./qemu/build/../hw/intc/riscv_aplic.c:486: undefined reference to `kvm_set_irq'
9
of DRAM, and "bottom of DRAM" will vary across boards and
8
collect2: error: ld returned 1 exit status
10
configurations, then it's actually loading the fdt, and finally it's
11
returning the fdt address used to the caller.
12
9
13
Reduce the existing complexity of riscv_load_fdt() by splitting its code
10
This happens because the debug build will poke into the
14
into a new function, riscv_compute_fdt_addr(), that will take care of
11
'if (is_kvm_aia(aplic->msimode))' block and fail to find a reference to
15
all fdt address logic. riscv_load_fdt() can then be a simple function
12
the KVM only function riscv_kvm_aplic_request().
16
that just loads a fdt at the given fdt address.
17
13
18
We're also taken the opportunity to clarify the intentions and
14
There are multiple solutions to fix this. We'll go with the same
19
assumptions made by these functions. riscv_load_fdt() is now receiving a
15
solution from the previous patch, i.e. add a kvm_enabled() conditional
20
hwaddr as fdt_addr because there is no restriction of having to load the
16
to filter out the block. But there's a catch: riscv_kvm_aplic_request()
21
fdt in higher addresses that doesn't fit in an uint32_t.
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]:
22
20
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
"(...) the compiler won't eliminate entire unused functions with -O0"
22
23
We'll solve it by moving riscv_kvm_aplic_request() to kvm.c and add its
24
declaration in kvm_riscv.h, where all other KVM specific public
25
functions are already declared. Other archs handles KVM specific code in
26
this manner and we expect to do the same from now on.
27
28
[1] https://lore.kernel.org/qemu-riscv/d2f1ad02-eb03-138f-9d08-db676deeed05@linaro.org/
29
24
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
30
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
25
Message-Id: <20230201171212.1219375-3-dbarboza@ventanamicro.com>
31
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
32
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
34
Message-ID: <20230830133503.711138-3-dbarboza@ventanamicro.com>
26
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
---
36
---
28
include/hw/riscv/boot.h | 4 +++-
37
target/riscv/kvm_riscv.h | 1 +
29
hw/riscv/boot.c | 30 +++++++++++++++++++++++++-----
38
hw/intc/riscv_aplic.c | 8 ++------
30
hw/riscv/microchip_pfsoc.c | 6 ++++--
39
target/riscv/kvm.c | 5 +++++
31
hw/riscv/sifive_u.c | 7 ++++---
40
3 files changed, 8 insertions(+), 6 deletions(-)
32
hw/riscv/spike.c | 6 +++---
33
hw/riscv/virt.c | 7 ++++---
34
6 files changed, 43 insertions(+), 17 deletions(-)
35
41
36
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
42
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
37
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
38
--- a/include/hw/riscv/boot.h
44
--- a/target/riscv/kvm_riscv.h
39
+++ b/include/hw/riscv/boot.h
45
+++ b/target/riscv/kvm_riscv.h
40
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(MachineState *machine,
46
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
41
target_ulong firmware_end_addr,
47
uint64_t aia_irq_num, uint64_t aia_msi_num,
42
symbol_fn_t sym_cb);
48
uint64_t aplic_base, uint64_t imsic_base,
43
void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry);
49
uint64_t guest_num);
44
-uint64_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt);
50
+void riscv_kvm_aplic_request(void *opaque, int irq, int level);
45
+uint64_t riscv_compute_fdt_addr(hwaddr dram_start, uint64_t dram_size,
51
46
+ void *fdt);
52
#endif
47
+void riscv_load_fdt(hwaddr fdt_addr, void *fdt);
53
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
48
void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts,
49
hwaddr saddr,
50
hwaddr rom_base, hwaddr rom_size,
51
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
52
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/riscv/boot.c
55
--- a/hw/intc/riscv_aplic.c
54
+++ b/hw/riscv/boot.c
56
+++ b/hw/intc/riscv_aplic.c
55
@@ -XXX,XX +XXX,XX @@ void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
57
@@ -XXX,XX +XXX,XX @@
56
}
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;
57
}
67
}
58
68
59
-uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
69
-static void riscv_kvm_aplic_request(void *opaque, int irq, int level)
60
+/*
70
-{
61
+ * The FDT should be put at the farthest point possible to
71
- kvm_set_irq(kvm_state, irq, !!level);
62
+ * avoid overwriting it with the kernel/initrd.
72
-}
63
+ *
73
-
64
+ * This function makes an assumption that the DRAM is
74
static void riscv_aplic_request(void *opaque, int irq, int level)
65
+ * contiguous. It also cares about 32-bit systems and
66
+ * will limit fdt_addr to be addressable by them even for
67
+ * 64-bit CPUs.
68
+ *
69
+ * The FDT is fdt_packed() during the calculation.
70
+ */
71
+uint64_t riscv_compute_fdt_addr(hwaddr dram_base, uint64_t mem_size,
72
+ void *fdt)
73
{
75
{
74
- uint64_t temp, fdt_addr;
76
bool update = false;
75
+ uint64_t temp;
77
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
76
hwaddr dram_end = dram_base + mem_size;
78
* have IRQ lines delegated by their parent APLIC.
77
int ret = fdt_pack(fdt);
78
int fdtsize;
79
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
80
* end of dram or 3GB whichever is lesser.
81
*/
79
*/
82
temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end;
80
if (!aplic->parent) {
83
- fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB);
81
- if (is_kvm_aia(aplic->msimode)) {
84
+
82
+ if (kvm_enabled() && is_kvm_aia(aplic->msimode)) {
85
+ return QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB);
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);
86
+}
97
+}
87
+
98
+
88
+/*
99
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
89
+ * 'fdt_addr' is received as hwaddr because boards might put
100
uint64_t idx)
90
+ * the FDT beyond 32-bit addressing boundary.
101
{
91
+ */
92
+void riscv_load_fdt(hwaddr fdt_addr, void *fdt)
93
+{
94
+ uint32_t fdtsize = fdt_totalsize(fdt);
95
96
/* copy in the device tree */
97
qemu_fdt_dumpdtb(fdt, fdtsize);
98
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
99
&address_space_memory);
100
qemu_register_reset_nosnapshotload(qemu_fdt_randomize_seeds,
101
rom_ptr_for_as(&address_space_memory, fdt_addr, fdtsize));
102
-
103
- return fdt_addr;
104
}
105
106
void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base,
107
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/hw/riscv/microchip_pfsoc.c
110
+++ b/hw/riscv/microchip_pfsoc.c
111
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
112
}
113
114
/* Compute the fdt load address in dram */
115
- fdt_load_addr = riscv_load_fdt(memmap[MICROCHIP_PFSOC_DRAM_LO].base,
116
- machine->ram_size, machine->fdt);
117
+ fdt_load_addr = riscv_compute_fdt_addr(memmap[MICROCHIP_PFSOC_DRAM_LO].base,
118
+ machine->ram_size, machine->fdt);
119
+ riscv_load_fdt(fdt_load_addr, machine->fdt);
120
+
121
/* Load the reset vector */
122
riscv_setup_rom_reset_vec(machine, &s->soc.u_cpus, firmware_load_addr,
123
memmap[MICROCHIP_PFSOC_ENVM_DATA].base,
124
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
125
index XXXXXXX..XXXXXXX 100644
126
--- a/hw/riscv/sifive_u.c
127
+++ b/hw/riscv/sifive_u.c
128
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
129
kernel_entry = 0;
130
}
131
132
- /* Compute the fdt load address in dram */
133
- fdt_load_addr = riscv_load_fdt(memmap[SIFIVE_U_DEV_DRAM].base,
134
- machine->ram_size, machine->fdt);
135
+ fdt_load_addr = riscv_compute_fdt_addr(memmap[SIFIVE_U_DEV_DRAM].base,
136
+ machine->ram_size, machine->fdt);
137
+ riscv_load_fdt(fdt_load_addr, machine->fdt);
138
+
139
if (!riscv_is_32bit(&s->soc.u_cpus)) {
140
start_addr_hi32 = (uint64_t)start_addr >> 32;
141
}
142
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
143
index XXXXXXX..XXXXXXX 100644
144
--- a/hw/riscv/spike.c
145
+++ b/hw/riscv/spike.c
146
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
147
kernel_entry = 0;
148
}
149
150
- /* Compute the fdt load address in dram */
151
- fdt_load_addr = riscv_load_fdt(memmap[SPIKE_DRAM].base,
152
- machine->ram_size, machine->fdt);
153
+ fdt_load_addr = riscv_compute_fdt_addr(memmap[SPIKE_DRAM].base,
154
+ machine->ram_size, machine->fdt);
155
+ riscv_load_fdt(fdt_load_addr, machine->fdt);
156
157
/* load the reset vector */
158
riscv_setup_rom_reset_vec(machine, &s->soc[0], memmap[SPIKE_DRAM].base,
159
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/hw/riscv/virt.c
162
+++ b/hw/riscv/virt.c
163
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
164
start_addr = virt_memmap[VIRT_FLASH].base;
165
}
166
167
- /* Compute the fdt load address in dram */
168
- fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
169
- machine->ram_size, machine->fdt);
170
+ fdt_load_addr = riscv_compute_fdt_addr(memmap[VIRT_DRAM].base,
171
+ machine->ram_size, machine->fdt);
172
+ riscv_load_fdt(fdt_load_addr, machine->fdt);
173
+
174
/* load the reset vector */
175
riscv_setup_rom_reset_vec(machine, &s->soc[0], start_addr,
176
virt_memmap[VIRT_MROM].base,
177
--
102
--
178
2.39.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
1
From: Deepak Gupta <debug@rivosinc.com>
1
From: Ard Biesheuvel <ardb@kernel.org>
2
2
3
commit fb3f3730e4 added mechanism to generate virtual instruction
3
Use the accelerated SubBytes/ShiftRows/AddRoundKey AES helper to
4
exception during instruction decode when virt is enabled.
4
implement the first half of the key schedule derivation. This does not
5
actually involve shifting rows, so clone the same value into all four
6
columns of the AES vector to counter that operation.
5
7
6
However in some situations, illegal instruction exception can be raised
8
Cc: Richard Henderson <richard.henderson@linaro.org>
7
due to state of CPU. One such situation is implementing branch tracking.
9
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
8
[1] An indirect branch if doesn't land on a landing pad instruction, then
10
Cc: Palmer Dabbelt <palmer@dabbelt.com>
9
cpu must raise an illegal instruction exception.
11
Cc: Alistair Francis <alistair.francis@wdc.com>
10
Implementation would raise such expcetion due to missing landing pad inst
12
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
11
and not due to decode. Thus DisasContext must have `virt_inst_excp`
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
initialized to false during DisasContxt initialization for TB.
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
15
Message-ID: <20230831154118.138727-1-ardb@kernel.org>
14
[1] - https://github.com/riscv/riscv-cfi
15
16
Signed-off-by: Deepak Gupta <debug@rivosinc.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-Id: <20230127191758.755844-1-debug@rivosinc.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
17
---
21
target/riscv/translate.c | 1 +
18
target/riscv/crypto_helper.c | 17 +++++------------
22
1 file changed, 1 insertion(+)
19
1 file changed, 5 insertions(+), 12 deletions(-)
23
20
24
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
21
diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c
25
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/translate.c
23
--- a/target/riscv/crypto_helper.c
27
+++ b/target/riscv/translate.c
24
+++ b/target/riscv/crypto_helper.c
28
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
25
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(aes64ks1i)(target_ulong rs1, target_ulong rnum)
29
ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
26
30
ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
27
uint8_t enc_rnum = rnum;
31
ctx->zero = tcg_constant_tl(0);
28
uint32_t temp = (RS1 >> 32) & 0xFFFFFFFF;
32
+ ctx->virt_inst_excp = false;
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];
33
}
52
}
34
53
35
static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
54
target_ulong HELPER(aes64im)(target_ulong rs1)
36
--
55
--
37
2.39.1
56
2.41.0
57
58
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
This patch adds the T-Head C906 to the list of known CPUs.
3
riscv_trigger_init() had been called on reset events that can happen
4
Selecting this CPUs will automatically enable the available
4
several times for a CPU and it allocated timers for itrigger. If old
5
ISA extensions of the CPUs (incl. vendor extensions).
5
timers were present, they were simply overwritten by the new timers,
6
resulting in a memory leak.
6
7
7
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
Divide riscv_trigger_init() into two functions, namely
9
riscv_trigger_realize() and riscv_trigger_reset() and call them in
10
appropriate timing. The timer allocation will happen only once for a
11
CPU in riscv_trigger_realize().
12
13
Fixes: 5a4ae64cac ("target/riscv: Add itrigger support when icount is enabled")
14
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
18
Message-ID: <20230818034059.9146-1-akihiko.odaki@daynix.com>
10
Message-Id: <20230131202013.2541053-13-christoph.muellner@vrull.eu>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
20
---
13
target/riscv/cpu.h | 1 +
21
target/riscv/debug.h | 3 ++-
14
target/riscv/cpu_vendorid.h | 6 ++++++
22
target/riscv/cpu.c | 8 +++++++-
15
target/riscv/cpu.c | 31 +++++++++++++++++++++++++++++++
23
target/riscv/debug.c | 15 ++++++++++++---
16
3 files changed, 38 insertions(+)
24
3 files changed, 21 insertions(+), 5 deletions(-)
17
create mode 100644 target/riscv/cpu_vendorid.h
18
25
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
26
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
20
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.h
28
--- a/target/riscv/debug.h
22
+++ b/target/riscv/cpu.h
29
+++ b/target/riscv/debug.h
23
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_debug_excp_handler(CPUState *cs);
24
#define TYPE_RISCV_CPU_SIFIVE_E51 RISCV_CPU_TYPE_NAME("sifive-e51")
31
bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
25
#define TYPE_RISCV_CPU_SIFIVE_U34 RISCV_CPU_TYPE_NAME("sifive-u34")
32
bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
26
#define TYPE_RISCV_CPU_SIFIVE_U54 RISCV_CPU_TYPE_NAME("sifive-u54")
33
27
+#define TYPE_RISCV_CPU_THEAD_C906 RISCV_CPU_TYPE_NAME("thead-c906")
34
-void riscv_trigger_init(CPURISCVState *env);
28
#define TYPE_RISCV_CPU_HOST RISCV_CPU_TYPE_NAME("host")
35
+void riscv_trigger_realize(CPURISCVState *env);
29
36
+void riscv_trigger_reset_hold(CPURISCVState *env);
30
#if defined(TARGET_RISCV32)
37
31
diff --git a/target/riscv/cpu_vendorid.h b/target/riscv/cpu_vendorid.h
38
bool riscv_itrigger_enabled(CPURISCVState *env);
32
new file mode 100644
39
void riscv_itrigger_update_priv(CPURISCVState *env);
33
index XXXXXXX..XXXXXXX
34
--- /dev/null
35
+++ b/target/riscv/cpu_vendorid.h
36
@@ -XXX,XX +XXX,XX @@
37
+#ifndef TARGET_RISCV_CPU_VENDORID_H
38
+#define TARGET_RISCV_CPU_VENDORID_H
39
+
40
+#define THEAD_VENDOR_ID 0x5b7
41
+
42
+#endif /* TARGET_RISCV_CPU_VENDORID_H */
43
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
40
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
44
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/cpu.c
42
--- a/target/riscv/cpu.c
46
+++ b/target/riscv/cpu.c
43
+++ b/target/riscv/cpu.c
47
@@ -XXX,XX +XXX,XX @@
44
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj)
48
#include "qemu/ctype.h"
45
49
#include "qemu/log.h"
46
#ifndef CONFIG_USER_ONLY
50
#include "cpu.h"
47
if (cpu->cfg.debug) {
51
+#include "cpu_vendorid.h"
48
- riscv_trigger_init(env);
52
#include "pmu.h"
49
+ riscv_trigger_reset_hold(env);
53
#include "internals.h"
50
}
54
#include "time_helper.h"
51
55
@@ -XXX,XX +XXX,XX @@ static void rv64_sifive_e_cpu_init(Object *obj)
52
if (kvm_enabled()) {
56
cpu->cfg.mmu = false;
53
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
54
55
riscv_cpu_register_gdb_regs_for_features(cs);
56
57
+#ifndef CONFIG_USER_ONLY
58
+ if (cpu->cfg.debug) {
59
+ riscv_trigger_realize(&cpu->env);
60
+ }
61
+#endif
62
+
63
qemu_init_vcpu(cs);
64
cpu_reset(cs);
65
66
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/debug.c
69
+++ b/target/riscv/debug.c
70
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
71
return false;
57
}
72
}
58
73
59
+static void rv64_thead_c906_cpu_init(Object *obj)
74
-void riscv_trigger_init(CPURISCVState *env)
75
+void riscv_trigger_realize(CPURISCVState *env)
60
+{
76
+{
61
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
77
+ int i;
62
+ RISCVCPU *cpu = RISCV_CPU(obj);
63
+
78
+
64
+ set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
79
+ for (i = 0; i < RV_MAX_TRIGGERS; i++) {
65
+ set_priv_version(env, PRIV_VERSION_1_11_0);
80
+ env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
66
+
81
+ riscv_itrigger_timer_cb, env);
67
+ cpu->cfg.ext_g = true;
82
+ }
68
+ cpu->cfg.ext_c = true;
69
+ cpu->cfg.ext_u = true;
70
+ cpu->cfg.ext_s = true;
71
+ cpu->cfg.ext_icsr = true;
72
+ cpu->cfg.ext_zfh = true;
73
+ cpu->cfg.mmu = true;
74
+ cpu->cfg.ext_xtheadba = true;
75
+ cpu->cfg.ext_xtheadbb = true;
76
+ cpu->cfg.ext_xtheadbs = true;
77
+ cpu->cfg.ext_xtheadcmo = true;
78
+ cpu->cfg.ext_xtheadcondmov = true;
79
+ cpu->cfg.ext_xtheadfmemidx = true;
80
+ cpu->cfg.ext_xtheadmac = true;
81
+ cpu->cfg.ext_xtheadmemidx = true;
82
+ cpu->cfg.ext_xtheadmempair = true;
83
+ cpu->cfg.ext_xtheadsync = true;
84
+
85
+ cpu->cfg.mvendorid = THEAD_VENDOR_ID;
86
+}
83
+}
87
+
84
+
88
static void rv128_base_cpu_init(Object *obj)
85
+void riscv_trigger_reset_hold(CPURISCVState *env)
89
{
86
{
90
if (qemu_tcg_mttcg_enabled()) {
87
target_ulong tdata1 = build_tdata1(env, TRIGGER_TYPE_AD_MATCH, 0, 0);
91
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
88
int i;
92
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init),
89
@@ -XXX,XX +XXX,XX @@ void riscv_trigger_init(CPURISCVState *env)
93
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init),
90
env->tdata3[i] = 0;
94
DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init),
91
env->cpu_breakpoint[i] = NULL;
95
+ DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C906, rv64_thead_c906_cpu_init),
92
env->cpu_watchpoint[i] = NULL;
96
DEFINE_CPU(TYPE_RISCV_CPU_BASE128, rv128_base_cpu_init),
93
- env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
97
#endif
94
- riscv_itrigger_timer_cb, env);
98
};
95
+ timer_del(env->itrigger_timer[i]);
96
}
97
}
99
--
98
--
100
2.39.1
99
2.41.0
100
101
diff view generated by jsdifflib
New patch
1
From: Leon Schuermann <leons@opentitan.org>
1
2
3
When the rule-lock bypass (RLB) bit is set in the mseccfg CSR, the PMP
4
configuration lock bits must not apply. While this behavior is
5
implemented for the pmpcfgX CSRs, this bit is not respected for
6
changes to the pmpaddrX CSRs. This patch ensures that pmpaddrX CSR
7
writes work even on locked regions when the global rule-lock bypass is
8
enabled.
9
10
Signed-off-by: Leon Schuermann <leons@opentitan.org>
11
Reviewed-by: Mayuresh Chitale <mchitale@ventanamicro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <20230829215046.1430463-1-leon@is.currently.online>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
target/riscv/pmp.c | 4 ++++
17
1 file changed, 4 insertions(+)
18
19
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/pmp.c
22
+++ b/target/riscv/pmp.c
23
@@ -XXX,XX +XXX,XX @@ static inline uint8_t pmp_get_a_field(uint8_t cfg)
24
*/
25
static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
26
{
27
+ /* mseccfg.RLB is set */
28
+ if (MSECCFG_RLB_ISSET(env)) {
29
+ return 0;
30
+ }
31
32
if (env->pmp_state.pmp[pmp_index].cfg_reg & PMP_LOCK) {
33
return 1;
34
--
35
2.41.0
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@wdc.com>
1
From: Tommy Wu <tommy.wu@sifive.com>
2
2
3
If the CSRs and CSR instructions are disabled because the Zicsr
3
According to the new spec, when vsiselect has a reserved value, attempts
4
extension isn't enabled then we want to make sure we don't run any CSR
4
from M-mode or HS-mode to access vsireg, or from VS-mode to access
5
instructions in the boot ROM.
5
sireg, should preferably raise an illegal instruction exception.
6
6
7
This patches removes the CSR instructions from the reset-vec if the
7
Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
8
extension isn't enabled. We replace the instruction with a NOP instead.
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
9
9
Message-ID: <20230816061647.600672-1-tommy.wu@sifive.com>
10
Note that we don't do this for the SiFive U machine, as we are modelling
11
the hardware in that case.
12
13
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1447
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
16
Message-Id: <20230123035754.75553-1-alistair.francis@opensource.wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
11
---
19
hw/riscv/boot.c | 9 +++++++++
12
target/riscv/csr.c | 7 +++++--
20
1 file changed, 9 insertions(+)
13
1 file changed, 5 insertions(+), 2 deletions(-)
21
14
22
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
23
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/riscv/boot.c
17
--- a/target/riscv/csr.c
25
+++ b/hw/riscv/boot.c
18
+++ b/target/riscv/csr.c
26
@@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts
19
@@ -XXX,XX +XXX,XX @@ static int rmw_iprio(target_ulong xlen,
27
reset_vec[4] = 0x0182b283; /* ld t0, 24(t0) */
20
static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
21
target_ulong new_val, target_ulong wr_mask)
22
{
23
- bool virt;
24
+ bool virt, isel_reserved;
25
uint8_t *iprio;
26
int ret = -EINVAL;
27
target_ulong priv, isel, vgein;
28
@@ -XXX,XX +XXX,XX @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
29
30
/* Decode register details from CSR number */
31
virt = false;
32
+ isel_reserved = false;
33
switch (csrno) {
34
case CSR_MIREG:
35
iprio = env->miprio;
36
@@ -XXX,XX +XXX,XX @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
37
riscv_cpu_mxl_bits(env)),
38
val, new_val, wr_mask);
39
}
40
+ } else {
41
+ isel_reserved = true;
28
}
42
}
29
43
30
+ if (!harts->harts[0].cfg.ext_icsr) {
44
done:
31
+ /*
45
if (ret) {
32
+ * The Zicsr extension has been disabled, so let's ensure we don't
46
- return (env->virt_enabled && virt) ?
33
+ * run the CSR instruction. Let's fill the address with a non
47
+ return (env->virt_enabled && virt && !isel_reserved) ?
34
+ * compressed nop.
48
RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
35
+ */
49
}
36
+ reset_vec[2] = 0x00000013; /* addi x0, x0, 0 */
50
return RISCV_EXCP_NONE;
37
+ }
38
+
39
/* copy in the reset vector in little_endian byte order */
40
for (i = 0; i < ARRAY_SIZE(reset_vec); i++) {
41
reset_vec[i] = cpu_to_le32(reset_vec[i]);
42
--
51
--
43
2.39.1
52
2.41.0
diff view generated by jsdifflib
1
From: Philipp Tomsich <philipp.tomsich@vrull.eu>
1
From: Nikita Shubin <n.shubin@yadro.com>
2
2
3
The decoding of the following instructions from Zb[abcs] currently
3
As per ISA:
4
contains decoding/printing errors:
5
* xnor,orn,andn: the rs2 operand is not being printed
6
* slli.uw: decodes and prints the immediate shift-amount as a
7
register (e.g. 'shift-by-2' becomes 'sp') instead of
8
     interpreting this as an immediate
9
4
10
This commit updates the instruction descriptions to use the
5
"For CSRRWI, if rd=x0, then the instruction shall not read the CSR and
11
appropriate decoding/printing formats.
6
shall not cause any of the side effects that might occur on a CSR read."
12
7
13
Signed-off-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
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>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-Id: <20230120151551.1022761-1-philipp.tomsich@vrull.eu>
13
Message-ID: <20230808090914.17634-1-nikita.shubin@maquefel.me>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
15
---
18
disas/riscv.c | 8 ++++----
16
target/riscv/csr.c | 24 +++++++++++++++---------
19
1 file changed, 4 insertions(+), 4 deletions(-)
17
1 file changed, 15 insertions(+), 9 deletions(-)
20
18
21
diff --git a/disas/riscv.c b/disas/riscv.c
19
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
22
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
23
--- a/disas/riscv.c
21
--- a/target/riscv/csr.c
24
+++ b/disas/riscv.c
22
+++ b/target/riscv/csr.c
25
@@ -XXX,XX +XXX,XX @@ const rv_opcode_data opcode_data[] = {
23
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
26
{ "cpop", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
24
target_ulong write_mask)
27
{ "sext.h", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
25
{
28
{ "sext.b", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
26
RISCVException ret;
29
- { "xnor", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
27
- target_ulong old_value;
30
- { "orn", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
28
+ target_ulong old_value = 0;
31
- { "andn", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
29
32
+ { "xnor", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
30
/* execute combined read/write operation if it exists */
33
+ { "orn", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
31
if (csr_ops[csrno].op) {
34
+ { "andn", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
32
return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
35
{ "rol", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
33
}
36
{ "ror", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
34
37
{ "sh1add", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
35
- /* if no accessor exists then return failure */
38
@@ -XXX,XX +XXX,XX @@ const rv_opcode_data opcode_data[] = {
36
- if (!csr_ops[csrno].read) {
39
{ "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
37
- return RISCV_EXCP_ILLEGAL_INST;
40
{ "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
38
- }
41
{ "cpopw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
39
- /* read old value */
42
- { "slli.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
40
- ret = csr_ops[csrno].read(env, csrno, &old_value);
43
+ { "slli.uw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
41
- if (ret != RISCV_EXCP_NONE) {
44
{ "add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
42
- return ret;
45
{ "rolw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
43
+ /*
46
{ "rorw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
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
+ }
57
}
58
59
/* write value if writable and write mask set, otherwise drop writes */
47
--
60
--
48
2.39.1
61
2.41.0
diff view generated by jsdifflib