1
The following changes since commit fcb237e64f9d026c03d635579c7b288d0008a6e5:
1
The following changes since commit c5ea91da443b458352c1b629b490ee6631775cb4:
2
2
3
Merge tag 'pull-vfio-20230710' of https://github.com/legoater/qemu into staging (2023-07-10 09:17:06 +0100)
3
Merge tag 'pull-trivial-patches' of https://gitlab.com/mjt0k/qemu into staging (2023-09-08 10:06:25 -0400)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20230710-1
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20230911
8
8
9
for you to fetch changes up to a47842d16653b4f73b5d56ff0c252dd8a329481b:
9
for you to fetch changes up to e7a03409f29e2da59297d55afbaec98c96e43e3a:
10
10
11
riscv: Add support for the Zfa extension (2023-07-10 22:29:20 +1000)
11
target/riscv: don't read CSR in riscv_csrrw_do64 (2023-09-11 11:45:55 +1000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Third RISC-V PR for 8.1
14
First RISC-V PR for 8.2
15
15
16
* Use xl instead of mxl for disassemble
16
* Remove 'host' CPU from TCG
17
* Factor out extension tests to cpu_cfg.h
17
* riscv_htif Fixup printing on big endian hosts
18
* disas/riscv: Add vendor extension support
18
* Add zmmul isa string
19
* disas/riscv: Add support for XVentanaCondOps
19
* Add smepmp isa string
20
* disas/riscv: Add support for XThead* instructions
20
* Fix page_check_range use in fault-only-first
21
* Fix mstatus related problems
21
* Use existing lookup tables for MixColumns
22
* Fix veyron-v1 CPU properties
22
* Add RISC-V vector cryptographic instruction set support
23
* Fix the xlen for data address when MPRV=1
23
* Implement WARL behaviour for mcountinhibit/mcounteren
24
* opensbi: Upgrade from v1.2 to v1.3
24
* Add Zihintntl extension ISA string to DTS
25
* Enable 32-bit Spike OpenSBI boot testing
25
* Fix zfa fleq.d and fltq.d
26
* Support the watchdog timer of HiFive 1 rev b
26
* Fix upper/lower mtime write calculation
27
* Only build qemu-system-riscv$$ on rv$$ host
27
* Make rtc variable names consistent
28
* Add RVV registers to log
28
* Use abi type for linux-user target_ucontext
29
* Restrict ACLINT to TCG
29
* Add RISC-V KVM AIA Support
30
* Add syscall riscv_hwprobe
30
* Fix riscv,pmu DT node path in the virt machine
31
* Add support for BF16 extensions
31
* Update CSR bits name for svadu extension
32
* KVM_RISCV_SET_TIMER macro is not configured correctly
32
* Mark zicond non-experimental
33
* Generate devicetree only after machine initialization is complete
33
* Fix satp_mode_finalize() when satp_mode.supported = 0
34
* virt: Convert fdt_load_addr to uint64_t
34
* Fix non-KVM --enable-debug build
35
* KVM: fixes and enhancements
35
* Add new extensions to hwprobe
36
* Add support for the Zfa extension
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
37
41
38
----------------------------------------------------------------
42
----------------------------------------------------------------
39
Bin Meng (2):
43
Akihiko Odaki (1):
40
roms/opensbi: Upgrade from v1.2 to v1.3
44
target/riscv: Allocate itrigger timers only once
41
tests/avocado: riscv: Enable 32-bit Spike OpenSBI boot testing
42
45
43
Christoph Müllner (8):
46
Ard Biesheuvel (2):
44
target/riscv: Factor out extension tests to cpu_cfg.h
47
target/riscv: Use existing lookup tables for MixColumns
45
disas/riscv: Move types/constants to new header file
48
target/riscv: Use accelerated helper for AES64KS1I
46
disas/riscv: Make rv_op_illegal a shared enum value
47
disas/riscv: Encapsulate opcode_data into decode
48
disas/riscv: Provide infrastructure for vendor extensions
49
disas/riscv: Add support for XVentanaCondOps
50
disas/riscv: Add support for XThead* instructions
51
riscv: Add support for the Zfa extension
52
49
53
Daniel Henrique Barboza (20):
50
Conor Dooley (1):
54
target/riscv/cpu.c: fix veyron-v1 CPU properties
51
hw/riscv: virt: Fix riscv,pmu DT node path
55
target/riscv: skip features setup for KVM CPUs
56
hw/riscv/virt.c: skip 'mmu-type' FDT if satp mode not set
57
target/riscv/cpu.c: restrict 'mvendorid' value
58
target/riscv/cpu.c: restrict 'mimpid' value
59
target/riscv/cpu.c: restrict 'marchid' value
60
target/riscv: use KVM scratch CPUs to init KVM properties
61
target/riscv: read marchid/mimpid in kvm_riscv_init_machine_ids()
62
target/riscv: handle mvendorid/marchid/mimpid for KVM CPUs
63
target/riscv/kvm.c: init 'misa_ext_mask' with scratch CPU
64
target/riscv/cpu: add misa_ext_info_arr[]
65
target/riscv: add KVM specific MISA properties
66
target/riscv/kvm.c: update KVM MISA bits
67
target/riscv/kvm.c: add multi-letter extension KVM properties
68
target/riscv/cpu.c: add satp_mode properties earlier
69
target/riscv/cpu.c: remove priv_ver check from riscv_isa_string_ext()
70
target/riscv/cpu.c: create KVM mock properties
71
target/riscv: update multi-letter extension KVM properties
72
target/riscv/kvm.c: add kvmconfig_get_cfg_addr() helper
73
target/riscv/kvm.c: read/write (cbom|cboz)_blocksize in KVM
74
52
75
Guenter Roeck (1):
53
Daniel Henrique Barboza (6):
76
riscv: Generate devicetree only after machine initialization is complete
54
target/riscv/cpu.c: do not run 'host' CPU with TCG
55
target/riscv/cpu.c: add zmmul isa string
56
target/riscv/cpu.c: add smepmp isa string
57
target/riscv: fix satp_mode_finalize() when satp_mode.supported = 0
58
hw/riscv/virt.c: fix non-KVM --enable-debug build
59
hw/intc/riscv_aplic.c fix non-KVM --enable-debug build
77
60
78
Ivan Klokov (1):
61
Dickon Hood (2):
79
target/riscv: Add RVV registers to log
62
target/riscv: Refactor translation of vector-widening instruction
63
target/riscv: Add Zvbb ISA extension support
80
64
81
Jason Chien (1):
65
Jason Chien (3):
82
target/riscv: Set the correct exception for implict G-stage translation fail
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
83
69
84
LIU Zhiwei (1):
70
Kiran Ostrolenk (4):
85
target/riscv: Use xl instead of mxl for disassemble
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
86
75
87
Lakshmi Bai Raja Subramanian (1):
76
LIU Zhiwei (3):
88
hw/riscv: virt: Convert fdt_load_addr to uint64_t
77
target/riscv: Fix page_check_range use in fault-only-first
78
target/riscv: Fix zfa fleq.d and fltq.d
79
linux-user/riscv: Use abi type for target_ucontext
89
80
90
Philippe Mathieu-Daudé (3):
81
Lawrence Hunter (2):
91
target/riscv: Only unify 'riscv32/64' -> 'riscv' for host cpu in meson
82
target/riscv: Add Zvbc ISA extension support
92
target/riscv: Only build KVM guest with same wordsize as host
83
target/riscv: Add Zvksh ISA extension support
93
hw/riscv/virt: Restrict ACLINT to TCG
84
85
Leon Schuermann (1):
86
target/riscv/pmp.c: respect mseccfg.RLB for pmpaddrX changes
87
88
Max Chou (3):
89
crypto: Create sm4_subword
90
crypto: Add SM4 constant parameter CK
91
target/riscv: Add Zvksed ISA extension support
92
93
Nazar Kazakov (4):
94
target/riscv: Remove redundant "cpu_vl == 0" checks
95
target/riscv: Move vector translation checks
96
target/riscv: Add Zvkned ISA extension support
97
target/riscv: Add Zvkg ISA extension support
98
99
Nikita Shubin (1):
100
target/riscv: don't read CSR in riscv_csrrw_do64
101
102
Rob Bradford (1):
103
target/riscv: Implement WARL behaviour for mcountinhibit/mcounteren
94
104
95
Robbin Ehn (1):
105
Robbin Ehn (1):
96
linux-user/riscv: Add syscall riscv_hwprobe
106
linux-user/riscv: Add new extensions to hwprobe
97
107
98
Tommy Wu (3):
108
Thomas Huth (2):
99
hw/misc: sifive_e_aon: Support the watchdog timer of HiFive 1 rev b.
109
hw/char/riscv_htif: Fix printing of console characters on big endian hosts
100
hw/riscv: sifive_e: Support the watchdog timer of HiFive 1 rev b.
110
hw/char/riscv_htif: Fix the console syscall on big endian hosts
101
tests/qtest: sifive-e-aon-watchdog-test.c: Add QTest of watchdog of sifive_e
102
111
103
Weiwei Li (11):
112
Tommy Wu (1):
104
target/riscv: Make MPV only work when MPP != PRV_M
113
target/riscv: Align the AIA model to v1.0 ratified spec
105
target/riscv: Support MSTATUS.MPV/GVA only when RVH is enabled
106
target/riscv: Remove redundant assignment to SXL
107
target/riscv: Add additional xlen for address when MPRV=1
108
target/riscv: update cur_pmbase/pmmask based on mode affected by MPRV
109
target/riscv: Add properties for BF16 extensions
110
target/riscv: Add support for Zfbfmin extension
111
target/riscv: Add support for Zvfbfmin extension
112
target/riscv: Add support for Zvfbfwma extension
113
target/riscv: Expose properties for BF16 extensions
114
target/riscv: Add disas support for BF16 extensions
115
114
116
yang.zhang (1):
115
Vineet Gupta (1):
117
target/riscv KVM_RISCV_SET_TIMER macro is not configured correctly
116
riscv: zicond: make non-experimental
118
117
119
docs/system/riscv/virt.rst | 1 +
118
Weiwei Li (1):
120
meson.build | 15 +-
119
target/riscv: Update CSR bits name for svadu extension
121
disas/riscv-xthead.h | 28 +
122
disas/riscv-xventana.h | 18 +
123
disas/riscv.h | 302 +++++++++++
124
include/hw/misc/sifive_e_aon.h | 60 +++
125
include/hw/riscv/sifive_e.h | 9 +-
126
linux-user/riscv/syscall32_nr.h | 1 +
127
linux-user/riscv/syscall64_nr.h | 1 +
128
target/riscv/cpu.h | 56 +-
129
target/riscv/cpu_cfg.h | 41 ++
130
target/riscv/helper.h | 29 +
131
target/riscv/kvm_riscv.h | 1 +
132
target/riscv/insn32.decode | 38 ++
133
disas/riscv-xthead.c | 707 +++++++++++++++++++++++++
134
disas/riscv-xventana.c | 41 ++
135
disas/riscv.c | 559 +++++++++----------
136
hw/misc/sifive_e_aon.c | 319 +++++++++++
137
hw/riscv/sifive_e.c | 17 +-
138
hw/riscv/virt.c | 56 +-
139
linux-user/syscall.c | 146 +++++
140
target/riscv/cpu.c | 439 +++++++++++++--
141
target/riscv/cpu_helper.c | 12 +-
142
target/riscv/csr.c | 41 +-
143
target/riscv/fpu_helper.c | 166 ++++++
144
target/riscv/kvm.c | 501 +++++++++++++++++-
145
target/riscv/op_helper.c | 3 +-
146
target/riscv/translate.c | 42 +-
147
target/riscv/vector_helper.c | 17 +
148
tests/qtest/sifive-e-aon-watchdog-test.c | 450 ++++++++++++++++
149
tests/tcg/riscv64/test-fcvtmod.c | 345 ++++++++++++
150
target/riscv/insn_trans/trans_rvbf16.c.inc | 175 ++++++
151
target/riscv/insn_trans/trans_rvzfa.c.inc | 521 ++++++++++++++++++
152
target/riscv/insn_trans/trans_rvzfh.c.inc | 12 +-
153
disas/meson.build | 6 +-
154
hw/misc/Kconfig | 3 +
155
hw/misc/meson.build | 1 +
156
hw/riscv/Kconfig | 1 +
157
pc-bios/opensbi-riscv32-generic-fw_dynamic.bin | Bin 123072 -> 135344 bytes
158
pc-bios/opensbi-riscv64-generic-fw_dynamic.bin | Bin 121800 -> 138304 bytes
159
roms/opensbi | 2 +-
160
tests/avocado/riscv_opensbi.py | 2 -
161
tests/qtest/meson.build | 3 +
162
tests/tcg/riscv64/Makefile.target | 6 +
163
44 files changed, 4751 insertions(+), 442 deletions(-)
164
create mode 100644 disas/riscv-xthead.h
165
create mode 100644 disas/riscv-xventana.h
166
create mode 100644 disas/riscv.h
167
create mode 100644 include/hw/misc/sifive_e_aon.h
168
create mode 100644 disas/riscv-xthead.c
169
create mode 100644 disas/riscv-xventana.c
170
create mode 100644 hw/misc/sifive_e_aon.c
171
create mode 100644 tests/qtest/sifive-e-aon-watchdog-test.c
172
create mode 100644 tests/tcg/riscv64/test-fcvtmod.c
173
create mode 100644 target/riscv/insn_trans/trans_rvbf16.c.inc
174
create mode 100644 target/riscv/insn_trans/trans_rvzfa.c.inc
175
120
121
Yong-Xuan Wang (5):
122
target/riscv: support the AIA device emulation with KVM enabled
123
target/riscv: check the in-kernel irqchip support
124
target/riscv: Create an KVM AIA irqchip
125
target/riscv: update APLIC and IMSIC to support KVM AIA
126
target/riscv: select KVM AIA in riscv virt machine
127
128
include/crypto/aes.h | 7 +
129
include/crypto/sm4.h | 9 +
130
target/riscv/cpu_bits.h | 8 +-
131
target/riscv/cpu_cfg.h | 9 +
132
target/riscv/debug.h | 3 +-
133
target/riscv/helper.h | 98 +++
134
target/riscv/kvm_riscv.h | 5 +
135
target/riscv/vector_internals.h | 228 +++++++
136
target/riscv/insn32.decode | 58 ++
137
crypto/aes.c | 4 +-
138
crypto/sm4.c | 10 +
139
hw/char/riscv_htif.c | 12 +-
140
hw/intc/riscv_aclint.c | 11 +-
141
hw/intc/riscv_aplic.c | 52 +-
142
hw/intc/riscv_imsic.c | 25 +-
143
hw/riscv/virt.c | 374 ++++++------
144
linux-user/riscv/signal.c | 4 +-
145
linux-user/syscall.c | 14 +-
146
target/arm/tcg/crypto_helper.c | 10 +-
147
target/riscv/cpu.c | 83 ++-
148
target/riscv/cpu_helper.c | 6 +-
149
target/riscv/crypto_helper.c | 51 +-
150
target/riscv/csr.c | 54 +-
151
target/riscv/debug.c | 15 +-
152
target/riscv/kvm.c | 201 ++++++-
153
target/riscv/pmp.c | 4 +
154
target/riscv/translate.c | 1 +
155
target/riscv/vcrypto_helper.c | 970 ++++++++++++++++++++++++++++++
156
target/riscv/vector_helper.c | 245 +-------
157
target/riscv/vector_internals.c | 81 +++
158
target/riscv/insn_trans/trans_rvv.c.inc | 171 +++---
159
target/riscv/insn_trans/trans_rvvk.c.inc | 606 +++++++++++++++++++
160
target/riscv/insn_trans/trans_rvzfa.c.inc | 4 +-
161
target/riscv/meson.build | 4 +-
162
34 files changed, 2785 insertions(+), 652 deletions(-)
163
create mode 100644 target/riscv/vector_internals.h
164
create mode 100644 target/riscv/vcrypto_helper.c
165
create mode 100644 target/riscv/vector_internals.c
166
create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
As it is today it's not possible to use '-cpu host' if the RISC-V host
3
The 'host' CPU is available in a CONFIG_KVM build and it's currently
4
has RVH enabled. This is the resulting error:
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
$ ./qemu/build/qemu-system-riscv64 \
7
$ ./build/qemu-system-riscv64 -M virt,accel=tcg -cpu host --nographic
7
-machine virt,accel=kvm -m 2G -smp 1 \
8
-nographic -snapshot -kernel ./guest_imgs/Image \
9
-initrd ./guest_imgs/rootfs_kvm_riscv64.img \
10
-append "earlycon=sbi root=/dev/ram rw" \
11
-cpu host
12
qemu-system-riscv64: H extension requires priv spec 1.12.0
8
qemu-system-riscv64: H extension requires priv spec 1.12.0
13
9
14
This happens because we're checking for priv spec for all CPUs, and
10
This CPU does not have a priv spec because we don't filter its extensions
15
since we're not setting env->priv_ver for the 'host' CPU, it's being
11
via priv spec. We shouldn't be reaching riscv_cpu_realize_tcg() at all
16
default to zero (i.e. PRIV_SPEC_1_10_0).
12
with the 'host' CPU.
17
13
18
In reality env->priv_ver does not make sense when running with the KVM
14
We don't have a way to filter the 'host' CPU out of the available CPU
19
'host' CPU. It's used to gate certain CSRs/extensions during translation
15
options (-cpu help) if the build includes both KVM and TCG. What we can
20
to make them unavailable if the hart declares an older spec version. It
16
do is to error out during riscv_cpu_realize_tcg() if the user chooses
21
doesn't have any other use. E.g. OpenSBI version 1.2 retrieves the spec
17
the 'host' CPU with accel=tcg:
22
checking if the CSR_MCOUNTEREN, CSR_MCOUNTINHIBIT and CSR_MENVCFG CSRs
23
are available [1].
24
18
25
'priv_ver' is just one example. We're doing a lot of feature validation
19
$ ./build/qemu-system-riscv64 -M virt,accel=tcg -cpu host --nographic
26
and setup during riscv_cpu_realize() that it doesn't apply to KVM CPUs.
20
qemu-system-riscv64: 'host' CPU is not compatible with TCG acceleration
27
Validating the feature set for those CPUs is a KVM problem that should
28
be handled in KVM specific code.
29
30
The new riscv_cpu_realize_tcg() helper contains all validation logic that
31
are applicable to TCG CPUs only. riscv_cpu_realize() verifies if we're
32
running TCG and, if it's the case, proceed with the usual TCG realize()
33
logic.
34
35
[1] lib/sbi/sbi_hart.c, hart_detect_features()
36
21
37
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
38
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
39
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
40
Message-Id: <20230706101738.460804-2-dbarboza@ventanamicro.com>
24
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
25
Message-Id: <20230721133411.474105-1-dbarboza@ventanamicro.com>
41
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
26
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
42
---
27
---
43
target/riscv/cpu.c | 35 +++++++++++++++++++++++++----------
28
target/riscv/cpu.c | 5 +++++
44
1 file changed, 25 insertions(+), 10 deletions(-)
29
1 file changed, 5 insertions(+)
45
30
46
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
47
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/cpu.c
33
--- a/target/riscv/cpu.c
49
+++ b/target/riscv/cpu.c
34
+++ b/target/riscv/cpu.c
50
@@ -XXX,XX +XXX,XX @@
35
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize_tcg(DeviceState *dev, Error **errp)
51
#include "migration/vmstate.h"
52
#include "fpu/softfloat-helpers.h"
53
#include "sysemu/kvm.h"
54
+#include "sysemu/tcg.h"
55
#include "kvm_riscv.h"
56
#include "tcg/tcg.h"
57
58
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_validate_misa_priv(CPURISCVState *env, Error **errp)
59
}
60
}
61
62
-static void riscv_cpu_realize(DeviceState *dev, Error **errp)
63
+static void riscv_cpu_realize_tcg(DeviceState *dev, Error **errp)
64
{
65
- CPUState *cs = CPU(dev);
66
RISCVCPU *cpu = RISCV_CPU(dev);
67
CPURISCVState *env = &cpu->env;
36
CPURISCVState *env = &cpu->env;
68
- RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
69
Error *local_err = NULL;
37
Error *local_err = NULL;
70
38
71
- cpu_exec_realizefn(cs, &local_err);
39
+ if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_CPU_HOST)) {
72
- if (local_err != NULL) {
40
+ error_setg(errp, "'host' CPU is not compatible with TCG acceleration");
73
- error_propagate(errp, local_err);
41
+ return;
74
- return;
42
+ }
75
- }
43
+
76
-
77
riscv_cpu_validate_misa_mxl(cpu, &local_err);
44
riscv_cpu_validate_misa_mxl(cpu, &local_err);
78
if (local_err != NULL) {
45
if (local_err != NULL) {
79
error_propagate(errp, local_err);
46
error_propagate(errp, local_err);
80
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
81
}
82
83
#ifndef CONFIG_USER_ONLY
84
- cs->tcg_cflags |= CF_PCREL;
85
+ CPU(dev)->tcg_cflags |= CF_PCREL;
86
87
if (cpu->cfg.ext_sstc) {
88
riscv_timer_init(cpu);
89
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
90
}
91
}
92
#endif
93
+}
94
+
95
+static void riscv_cpu_realize(DeviceState *dev, Error **errp)
96
+{
97
+ CPUState *cs = CPU(dev);
98
+ RISCVCPU *cpu = RISCV_CPU(dev);
99
+ RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
100
+ Error *local_err = NULL;
101
+
102
+ cpu_exec_realizefn(cs, &local_err);
103
+ if (local_err != NULL) {
104
+ error_propagate(errp, local_err);
105
+ return;
106
+ }
107
+
108
+ if (tcg_enabled()) {
109
+ riscv_cpu_realize_tcg(dev, &local_err);
110
+ if (local_err != NULL) {
111
+ error_propagate(errp, local_err);
112
+ return;
113
+ }
114
+ }
115
116
riscv_cpu_finalize_features(cpu, &local_err);
117
if (local_err != NULL) {
118
--
47
--
119
2.40.1
48
2.41.0
49
50
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Per Anup Patel in [*]:
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.
4
9
5
> Currently, we only support running rv64 guest on rv64 host
10
Fixes: 5033606780 ("RISC-V HTIF Console")
6
> and rv32 guest on rv32 host.
11
Signed-off-by: Thomas Huth <thuth@redhat.com>
7
>
8
> In the future, we might support running rv32 guest on rv64
9
> host but as of now we don't see a strong push for it.
10
11
Therefore, when only using the KVM accelerator it is pointless
12
to build qemu-system-riscv32 on a rv64 host (or qemu-system-riscv64
13
on a rv32 host). Restrict meson to only build the correct binary,
14
avoiding to waste ressources building unusable code.
15
16
[*] https://lore.kernel.org/qemu-devel/CAAhSdy2JeRHeeoEc1XKQhPO3aDz4YKeyQsPT4S8yKJcYTA+AiQ@mail.gmail.com/
17
18
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-Id: <20230627143235.29947-3-philmd@linaro.org>
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>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
18
---
24
meson.build | 6 ++++--
19
hw/char/riscv_htif.c | 3 ++-
25
1 file changed, 4 insertions(+), 2 deletions(-)
20
1 file changed, 2 insertions(+), 1 deletion(-)
26
21
27
diff --git a/meson.build b/meson.build
22
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
28
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
29
--- a/meson.build
24
--- a/hw/char/riscv_htif.c
30
+++ b/meson.build
25
+++ b/hw/char/riscv_htif.c
31
@@ -XXX,XX +XXX,XX @@ elif cpu in ['ppc', 'ppc64']
26
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
32
kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
27
s->tohost = 0; /* clear to indicate we read */
33
elif cpu in ['mips', 'mips64']
28
return;
34
kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
29
} else if (cmd == HTIF_CONSOLE_CMD_PUTC) {
35
-elif cpu in ['riscv32', 'riscv64']
30
- qemu_chr_fe_write(&s->chr, (uint8_t *)&payload, 1);
36
- kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
31
+ uint8_t ch = (uint8_t)payload;
37
+elif cpu in ['riscv32']
32
+ qemu_chr_fe_write(&s->chr, &ch, 1);
38
+ kvm_targets = ['riscv32-softmmu']
33
resp = 0x100 | (uint8_t)payload;
39
+elif cpu in ['riscv64']
34
} else {
40
+ kvm_targets = ['riscv64-softmmu']
35
qemu_log("HTIF device %d: unknown command\n", device);
41
else
42
kvm_targets = []
43
endif
44
--
36
--
45
2.40.1
37
2.41.0
46
38
47
39
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
There are 2 places in which we need to get a pointer to a certain
3
Values that have been read via cpu_physical_memory_read() from the
4
property of the cpu->cfg struct based on property offset. Next patch
4
guest's memory have to be swapped in case the host endianess differs
5
will add a couple more.
5
from the guest.
6
6
7
Create a helper to avoid repeating this code over and over.
7
Fixes: a6e13e31d5 ("riscv_htif: Support console output via proxy syscall")
8
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-Id: <20230706101738.460804-20-dbarboza@ventanamicro.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>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
14
---
15
target/riscv/kvm.c | 11 +++++++----
15
hw/char/riscv_htif.c | 9 +++++----
16
1 file changed, 7 insertions(+), 4 deletions(-)
16
1 file changed, 5 insertions(+), 4 deletions(-)
17
17
18
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
18
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/kvm.c
20
--- a/hw/char/riscv_htif.c
21
+++ b/target/riscv/kvm.c
21
+++ b/hw/char/riscv_htif.c
22
@@ -XXX,XX +XXX,XX @@ static KVMCPUConfig kvm_multi_ext_cfgs[] = {
22
@@ -XXX,XX +XXX,XX @@
23
KVM_EXT_CFG("svpbmt", ext_svpbmt, KVM_RISCV_ISA_EXT_SVPBMT),
23
#include "qemu/timer.h"
24
};
24
#include "qemu/error-report.h"
25
25
#include "exec/address-spaces.h"
26
+static void *kvmconfig_get_cfg_addr(RISCVCPU *cpu, KVMCPUConfig *kvmcfg)
26
+#include "exec/tswap.h"
27
+{
27
#include "sysemu/dma.h"
28
+ return (void *)&cpu->cfg + kvmcfg->offset;
28
29
+}
29
#define RISCV_DEBUG_HTIF 0
30
+
30
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
31
static void kvm_cpu_cfg_set(RISCVCPU *cpu, KVMCPUConfig *multi_ext,
31
} else {
32
uint32_t val)
32
uint64_t syscall[8];
33
{
33
cpu_physical_memory_read(payload, syscall, sizeof(syscall));
34
- int cpu_cfg_offset = multi_ext->offset;
34
- if (syscall[0] == PK_SYS_WRITE &&
35
- bool *ext_enabled = (void *)&cpu->cfg + cpu_cfg_offset;
35
- syscall[1] == HTIF_DEV_CONSOLE &&
36
+ bool *ext_enabled = kvmconfig_get_cfg_addr(cpu, multi_ext);
36
- syscall[3] == HTIF_CONSOLE_CMD_PUTC) {
37
37
+ if (tswap64(syscall[0]) == PK_SYS_WRITE &&
38
*ext_enabled = val;
38
+ tswap64(syscall[1]) == HTIF_DEV_CONSOLE &&
39
}
39
+ tswap64(syscall[3]) == HTIF_CONSOLE_CMD_PUTC) {
40
@@ -XXX,XX +XXX,XX @@ static void kvm_cpu_cfg_set(RISCVCPU *cpu, KVMCPUConfig *multi_ext,
40
uint8_t ch;
41
static uint32_t kvm_cpu_cfg_get(RISCVCPU *cpu,
41
- cpu_physical_memory_read(syscall[2], &ch, 1);
42
KVMCPUConfig *multi_ext)
42
+ cpu_physical_memory_read(tswap64(syscall[2]), &ch, 1);
43
{
43
qemu_chr_fe_write(&s->chr, &ch, 1);
44
- int cpu_cfg_offset = multi_ext->offset;
44
resp = 0x100 | (uint8_t)payload;
45
- bool *ext_enabled = (void *)&cpu->cfg + cpu_cfg_offset;
45
} else {
46
+ bool *ext_enabled = kvmconfig_get_cfg_addr(cpu, multi_ext);
47
48
return *ext_enabled;
49
}
50
--
46
--
51
2.40.1
47
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
riscv_isa_string_ext() is being used by riscv_isa_string(), which is
3
zmmul was promoted from experimental to ratified in commit 6d00ffad4e95.
4
then used by boards to retrieve the 'riscv,isa' string to be written in
4
Add a riscv,isa string for it.
5
the FDT. All this happens after riscv_cpu_realize(), meaning that we're
6
already past riscv_cpu_validate_set_extensions() and, more important,
7
riscv_cpu_disable_priv_spec_isa_exts().
8
5
9
This means that all extensions that needed to be disabled due to
6
Fixes: 6d00ffad4e95 ("target/riscv: move zmmul out of the experimental properties")
10
priv_spec mismatch are already disabled. Checking this again during
11
riscv_isa_string_ext() is unneeded. Remove it.
12
13
As a bonus, riscv_isa_string_ext() can now be used with the 'host'
14
KVM-only CPU type since it doesn't have a env->priv_ver assigned and it
15
would fail this check for no good reason.
16
17
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
18
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
8
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
19
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
20
Message-Id: <20230706101738.460804-17-dbarboza@ventanamicro.com>
10
Message-Id: <20230720132424.371132-2-dbarboza@ventanamicro.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
---
12
---
23
target/riscv/cpu.c | 3 +--
13
target/riscv/cpu.c | 1 +
24
1 file changed, 1 insertion(+), 2 deletions(-)
14
1 file changed, 1 insertion(+)
25
15
26
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
27
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/cpu.c
18
--- a/target/riscv/cpu.c
29
+++ b/target/riscv/cpu.c
19
+++ b/target/riscv/cpu.c
30
@@ -XXX,XX +XXX,XX @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str,
20
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
31
int i;
21
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
32
22
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
33
for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
23
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
34
- if (cpu->env.priv_ver >= isa_edata_arr[i].min_version &&
24
+ ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
35
- isa_ext_is_enabled(cpu, &isa_edata_arr[i])) {
25
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
36
+ if (isa_ext_is_enabled(cpu, &isa_edata_arr[i])) {
26
ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
37
new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL);
27
ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
38
g_free(old);
39
old = new;
40
--
28
--
41
2.40.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
riscv_cpu_add_user_properties() ended up with an excess of "#ifndef
3
The cpu->cfg.epmp extension is still experimental, but it already has a
4
CONFIG_USER_ONLY" blocks after changes that added KVM properties
4
'smepmp' riscv,isa string. Add it.
5
handling.
6
7
KVM specific properties are required to be created earlier than their
8
TCG counterparts, but the remaining props can be created at any order.
9
Move riscv_add_satp_mode_properties() to the start of the function,
10
inside the !CONFIG_USER_ONLY block already present there, to remove the
11
last ifndef block.
12
5
13
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
6
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
7
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-Id: <20230706101738.460804-16-dbarboza@ventanamicro.com>
9
Message-Id: <20230720132424.371132-3-dbarboza@ventanamicro.com>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
11
---
20
target/riscv/cpu.c | 6 ++----
12
target/riscv/cpu.c | 1 +
21
1 file changed, 2 insertions(+), 4 deletions(-)
13
1 file changed, 1 insertion(+)
22
14
23
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/target/riscv/cpu.c
17
--- a/target/riscv/cpu.c
26
+++ b/target/riscv/cpu.c
18
+++ b/target/riscv/cpu.c
27
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_add_user_properties(Object *obj)
19
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
28
DeviceState *dev = DEVICE(obj);
20
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
29
21
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
30
#ifndef CONFIG_USER_ONLY
22
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
31
+ riscv_add_satp_mode_properties(obj);
23
+ ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, epmp),
32
+
24
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
33
if (kvm_enabled()) {
25
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
34
kvm_riscv_init_user_properties(obj);
26
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
35
}
36
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_add_user_properties(Object *obj)
37
#endif
38
qdev_property_add_static(dev, prop);
39
}
40
-
41
-#ifndef CONFIG_USER_ONLY
42
- riscv_add_satp_mode_properties(obj);
43
-#endif
44
}
45
46
static Property riscv_cpu_properties[] = {
47
--
27
--
48
2.40.1
28
2.41.0
49
50
diff view generated by jsdifflib
1
From: "yang.zhang" <yang.zhang@hexintek.com>
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
2
3
Should set/get riscv all reg timer,i.e, time/compare/frequency/state.
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.
4
7
5
Signed-off-by: Yang Zhang <yang.zhang@hexintek.com>
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1688
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-ID: <20230729031618.821-1-zhiwei_liu@linux.alibaba.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Message-Id: <20230707032306.4606-1-gaoshanliukou@163.com>
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/kvm.c | 2 +-
13
target/riscv/vector_helper.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
15
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
16
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/kvm.c
18
--- a/target/riscv/vector_helper.c
18
+++ b/target/riscv/kvm.c
19
+++ b/target/riscv/vector_helper.c
19
@@ -XXX,XX +XXX,XX @@ static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
20
@@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base,
20
21
cpu_mmu_index(env, false));
21
#define KVM_RISCV_SET_TIMER(cs, env, name, reg) \
22
if (host) {
22
do { \
23
#ifdef CONFIG_USER_ONLY
23
- int ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(env, time), &reg); \
24
- if (page_check_range(addr, offset, PAGE_READ)) {
24
+ int ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(env, name), &reg); \
25
+ if (!page_check_range(addr, offset, PAGE_READ)) {
25
if (ret) { \
26
vl = i;
26
abort(); \
27
goto ProbeSuccess;
27
} \
28
}
28
--
29
--
29
2.40.1
30
2.41.0
diff view generated by jsdifflib
1
From: Ivan Klokov <ivan.klokov@syntacore.com>
1
From: Ard Biesheuvel <ardb@kernel.org>
2
2
3
Print RvV extension register to log if VPU option is enabled.
3
The AES MixColumns and InvMixColumns operations are relatively
4
expensive 4x4 matrix multiplications in GF(2^8), which is why C
5
implementations usually rely on precomputed lookup tables rather than
6
performing the calculations on demand.
4
7
5
Signed-off-by: Ivan Klokov <ivan.klokov@syntacore.com>
8
Given that we already carry those tables in QEMU, we can just grab the
6
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
right value in the implementation of the RISC-V AES32 instructions. Note
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
that the tables in question are permuted according to the respective
8
Message-Id: <20230629083730.386604-1-ivan.klokov@syntacore.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>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
22
---
11
target/riscv/cpu.c | 57 +++++++++++++++++++++++++++++++++++++++++++++-
23
include/crypto/aes.h | 7 +++++++
12
1 file changed, 56 insertions(+), 1 deletion(-)
24
crypto/aes.c | 4 ++--
25
target/riscv/crypto_helper.c | 34 ++++------------------------------
26
3 files changed, 13 insertions(+), 32 deletions(-)
13
27
14
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
28
diff --git a/include/crypto/aes.h b/include/crypto/aes.h
15
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu.c
30
--- a/include/crypto/aes.h
17
+++ b/target/riscv/cpu.c
31
+++ b/include/crypto/aes.h
18
@@ -XXX,XX +XXX,XX @@ struct isa_ext_data {
32
@@ -XXX,XX +XXX,XX @@ void AES_decrypt(const unsigned char *in, unsigned char *out,
19
#define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \
33
extern const uint8_t AES_sbox[256];
20
{#_name, _min_ver, offsetof(struct RISCVCPUConfig, _prop)}
34
extern const uint8_t AES_isbox[256];
21
35
22
+/*
36
+/*
23
+ * From vector_helper.c
37
+AES_Te0[x] = S [x].[02, 01, 01, 03];
24
+ * Note that vector data is stored in host-endian 64-bit chunks,
38
+AES_Td0[x] = Si[x].[0e, 09, 0d, 0b];
25
+ * so addressing bytes needs a host-endian fixup.
39
+*/
26
+ */
27
+#if HOST_BIG_ENDIAN
28
+#define BYTE(x) ((x) ^ 7)
29
+#else
30
+#define BYTE(x) (x)
31
+#endif
32
+
40
+
33
/*
41
+extern const uint32_t AES_Te0[256], AES_Td0[256];
34
* Here are the ordering rules of extension naming defined by RISC-V
42
+
35
* specification :
43
#endif
36
@@ -XXX,XX +XXX,XX @@ const char * const riscv_fpr_regnames[] = {
44
diff --git a/crypto/aes.c b/crypto/aes.c
37
"f30/ft10", "f31/ft11"
45
index XXXXXXX..XXXXXXX 100644
46
--- a/crypto/aes.c
47
+++ b/crypto/aes.c
48
@@ -XXX,XX +XXX,XX @@ AES_Td3[x] = Si[x].[09, 0d, 0b, 0e];
49
AES_Td4[x] = Si[x].[01, 01, 01, 01];
50
*/
51
52
-static const uint32_t AES_Te0[256] = {
53
+const uint32_t AES_Te0[256] = {
54
0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
55
0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
56
0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
57
@@ -XXX,XX +XXX,XX @@ static const uint32_t AES_Te4[256] = {
58
0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
38
};
59
};
39
60
40
+const char * const riscv_rvv_regnames[] = {
61
-static const uint32_t AES_Td0[256] = {
41
+ "v0", "v1", "v2", "v3", "v4", "v5", "v6",
62
+const uint32_t AES_Td0[256] = {
42
+ "v7", "v8", "v9", "v10", "v11", "v12", "v13",
63
0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
43
+ "v14", "v15", "v16", "v17", "v18", "v19", "v20",
64
0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
44
+ "v21", "v22", "v23", "v24", "v25", "v26", "v27",
65
0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
45
+ "v28", "v29", "v30", "v31"
66
diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c
46
+};
67
index XXXXXXX..XXXXXXX 100644
47
+
68
--- a/target/riscv/crypto_helper.c
48
static const char * const riscv_excp_names[] = {
69
+++ b/target/riscv/crypto_helper.c
49
"misaligned_fetch",
70
@@ -XXX,XX +XXX,XX @@
50
"fault_fetch",
71
#include "crypto/aes-round.h"
51
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
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)
52
{
102
{
53
RISCVCPU *cpu = RISCV_CPU(cs);
103
uint8_t si = rs2 >> shamt;
54
CPURISCVState *env = &cpu->env;
104
- uint8_t so;
55
- int i;
105
uint32_t mixed;
56
+ int i, j;
106
target_ulong res;
57
+ uint8_t *p;
107
58
108
if (enc) {
59
#if !defined(CONFIG_USER_ONLY)
109
- so = AES_sbox[si];
60
if (riscv_has_ext(env, RVH)) {
110
if (mix) {
61
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
111
- mixed = aes_mixcolumn_byte(so, true);
62
}
112
+ mixed = be32_to_cpu(AES_Te0[si]);
113
} else {
114
- mixed = so;
115
+ mixed = AES_sbox[si];
116
}
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];
63
}
125
}
64
}
126
}
65
+ if (riscv_has_ext(env, RVV) && (flags & CPU_DUMP_VPU)) {
127
mixed = rol32(mixed, shamt);
66
+ static const int dump_rvv_csrs[] = {
67
+ CSR_VSTART,
68
+ CSR_VXSAT,
69
+ CSR_VXRM,
70
+ CSR_VCSR,
71
+ CSR_VL,
72
+ CSR_VTYPE,
73
+ CSR_VLENB,
74
+ };
75
+ for (int i = 0; i < ARRAY_SIZE(dump_rvv_csrs); ++i) {
76
+ int csrno = dump_rvv_csrs[i];
77
+ target_ulong val = 0;
78
+ RISCVException res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
79
+
80
+ /*
81
+ * Rely on the smode, hmode, etc, predicates within csr.c
82
+ * to do the filtering of the registers that are present.
83
+ */
84
+ if (res == RISCV_EXCP_NONE) {
85
+ qemu_fprintf(f, " %-8s " TARGET_FMT_lx "\n",
86
+ csr_ops[csrno].name, val);
87
+ }
88
+ }
89
+ uint16_t vlenb = cpu->cfg.vlen >> 3;
90
+
91
+ for (i = 0; i < 32; i++) {
92
+ qemu_fprintf(f, " %-8s ", riscv_rvv_regnames[i]);
93
+ p = (uint8_t *)env->vreg;
94
+ for (j = vlenb - 1 ; j >= 0; j--) {
95
+ qemu_fprintf(f, "%02x", *(p + i * vlenb + BYTE(j)));
96
+ }
97
+ qemu_fprintf(f, "\n");
98
+ }
99
+ }
100
}
101
102
static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
103
--
128
--
104
2.40.1
129
2.41.0
130
131
diff view generated by jsdifflib
1
From: Tommy Wu <tommy.wu@sifive.com>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
The watchdog timer is in the always-on domain device of HiFive 1 rev b,
3
Take some functions/macros out of `vector_helper` and put them in a new
4
so this patch added the AON device to the sifive_e machine. This patch
4
module called `vector_internals`. This ensures they can be used by both
5
only implemented the functionality of the watchdog timer.
5
vector and vector-crypto helpers (latter implemented in proceeding
6
commits).
6
7
7
Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
8
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
9
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
10
Signed-off-by: Max Chou <max.chou@sifive.com>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
11
Acked-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20230627141216.3962299-2-tommy.wu@sifive.com>
12
Message-ID: <20230711165917.2629866-2-max.chou@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
14
---
13
include/hw/misc/sifive_e_aon.h | 60 +++++++
15
target/riscv/vector_internals.h | 182 +++++++++++++++++++++++++++++
14
hw/misc/sifive_e_aon.c | 319 +++++++++++++++++++++++++++++++++
16
target/riscv/vector_helper.c | 201 +-------------------------------
15
hw/misc/Kconfig | 3 +
17
target/riscv/vector_internals.c | 81 +++++++++++++
16
hw/misc/meson.build | 1 +
18
target/riscv/meson.build | 1 +
17
4 files changed, 383 insertions(+)
19
4 files changed, 265 insertions(+), 200 deletions(-)
18
create mode 100644 include/hw/misc/sifive_e_aon.h
20
create mode 100644 target/riscv/vector_internals.h
19
create mode 100644 hw/misc/sifive_e_aon.c
21
create mode 100644 target/riscv/vector_internals.c
20
22
21
diff --git a/include/hw/misc/sifive_e_aon.h b/include/hw/misc/sifive_e_aon.h
23
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
22
new file mode 100644
24
new file mode 100644
23
index XXXXXXX..XXXXXXX
25
index XXXXXXX..XXXXXXX
24
--- /dev/null
26
--- /dev/null
25
+++ b/include/hw/misc/sifive_e_aon.h
27
+++ b/target/riscv/vector_internals.h
26
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
27
+/*
29
+/*
28
+ * SiFive HiFive1 AON (Always On Domain) interface.
30
+ * RISC-V Vector Extension Internals
29
+ *
31
+ *
30
+ * Copyright (c) 2022 SiFive, Inc. All rights reserved.
32
+ * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
31
+ *
33
+ *
32
+ * 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
33
+ * under the terms and conditions of the GNU General Public License,
35
+ * under the terms and conditions of the GNU General Public License,
34
+ * version 2 or later, as published by the Free Software Foundation.
36
+ * version 2 or later, as published by the Free Software Foundation.
35
+ *
37
+ *
...
...
40
+ *
42
+ *
41
+ * 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
42
+ * this program. If not, see <http://www.gnu.org/licenses/>.
44
+ * this program. If not, see <http://www.gnu.org/licenses/>.
43
+ */
45
+ */
44
+
46
+
45
+#ifndef HW_SIFIVE_AON_H
47
+#ifndef TARGET_RISCV_VECTOR_INTERNALS_H
46
+#define HW_SIFIVE_AON_H
48
+#define TARGET_RISCV_VECTOR_INTERNALS_H
47
+
49
+
48
+#include "hw/sysbus.h"
50
+#include "qemu/osdep.h"
49
+#include "qom/object.h"
51
+#include "qemu/bitops.h"
50
+
52
+#include "cpu.h"
51
+#define TYPE_SIFIVE_E_AON "riscv.sifive.e.aon"
53
+#include "tcg/tcg-gvec-desc.h"
52
+OBJECT_DECLARE_SIMPLE_TYPE(SiFiveEAONState, SIFIVE_E_AON)
54
+#include "internals.h"
53
+
55
+
54
+#define SIFIVE_E_AON_WDOGKEY (0x51F15E)
56
+static inline uint32_t vext_nf(uint32_t desc)
55
+#define SIFIVE_E_AON_WDOGFEED (0xD09F00D)
57
+{
56
+#define SIFIVE_E_LFCLK_DEFAULT_FREQ (32768)
58
+ return FIELD_EX32(simd_data(desc), VDATA, NF);
57
+
59
+}
58
+enum {
60
+
59
+ SIFIVE_E_AON_WDT = 0x0,
61
+/*
60
+ SIFIVE_E_AON_RTC = 0x40,
62
+ * Note that vector data is stored in host-endian 64-bit chunks,
61
+ SIFIVE_E_AON_LFROSC = 0x70,
63
+ * so addressing units smaller than that needs a host-endian fixup.
62
+ SIFIVE_E_AON_BACKUP = 0x80,
64
+ */
63
+ SIFIVE_E_AON_PMU = 0x100,
65
+#if HOST_BIG_ENDIAN
64
+ SIFIVE_E_AON_MAX = 0x150
66
+#define H1(x) ((x) ^ 7)
65
+};
67
+#define H1_2(x) ((x) ^ 6)
66
+
68
+#define H1_4(x) ((x) ^ 4)
67
+struct SiFiveEAONState {
69
+#define H2(x) ((x) ^ 3)
68
+ /*< private >*/
70
+#define H4(x) ((x) ^ 1)
69
+ SysBusDevice parent_obj;
71
+#define H8(x) ((x))
70
+
72
+#else
71
+ /*< public >*/
73
+#define H1(x) (x)
72
+ MemoryRegion mmio;
74
+#define H1_2(x) (x)
73
+
75
+#define H1_4(x) (x)
74
+ /*< watchdog timer >*/
76
+#define H2(x) (x)
75
+ QEMUTimer *wdog_timer;
77
+#define H4(x) (x)
76
+ qemu_irq wdog_irq;
78
+#define H8(x) (x)
77
+ uint64_t wdog_restart_time;
78
+ uint64_t wdogclk_freq;
79
+
80
+ uint32_t wdogcfg;
81
+ uint16_t wdogcmp0;
82
+ uint32_t wdogcount;
83
+ uint8_t wdogunlock;
84
+};
85
+
86
+#endif
79
+#endif
87
diff --git a/hw/misc/sifive_e_aon.c b/hw/misc/sifive_e_aon.c
80
+
81
+/*
82
+ * Encode LMUL to lmul as following:
83
+ * LMUL vlmul lmul
84
+ * 1 000 0
85
+ * 2 001 1
86
+ * 4 010 2
87
+ * 8 011 3
88
+ * - 100 -
89
+ * 1/8 101 -3
90
+ * 1/4 110 -2
91
+ * 1/2 111 -1
92
+ */
93
+static inline int32_t vext_lmul(uint32_t desc)
94
+{
95
+ return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3);
96
+}
97
+
98
+static inline uint32_t vext_vm(uint32_t desc)
99
+{
100
+ return FIELD_EX32(simd_data(desc), VDATA, VM);
101
+}
102
+
103
+static inline uint32_t vext_vma(uint32_t desc)
104
+{
105
+ return FIELD_EX32(simd_data(desc), VDATA, VMA);
106
+}
107
+
108
+static inline uint32_t vext_vta(uint32_t desc)
109
+{
110
+ return FIELD_EX32(simd_data(desc), VDATA, VTA);
111
+}
112
+
113
+static inline uint32_t vext_vta_all_1s(uint32_t desc)
114
+{
115
+ return FIELD_EX32(simd_data(desc), VDATA, VTA_ALL_1S);
116
+}
117
+
118
+/*
119
+ * Earlier designs (pre-0.9) had a varying number of bits
120
+ * per mask value (MLEN). In the 0.9 design, MLEN=1.
121
+ * (Section 4.5)
122
+ */
123
+static inline int vext_elem_mask(void *v0, int index)
124
+{
125
+ int idx = index / 64;
126
+ int pos = index % 64;
127
+ return (((uint64_t *)v0)[idx] >> pos) & 1;
128
+}
129
+
130
+/*
131
+ * Get number of total elements, including prestart, body and tail elements.
132
+ * Note that when LMUL < 1, the tail includes the elements past VLMAX that
133
+ * are held in the same vector register.
134
+ */
135
+static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t desc,
136
+ uint32_t esz)
137
+{
138
+ uint32_t vlenb = simd_maxsz(desc);
139
+ uint32_t sew = 1 << FIELD_EX64(env->vtype, VTYPE, VSEW);
140
+ int8_t emul = ctzl(esz) - ctzl(sew) + vext_lmul(desc) < 0 ? 0 :
141
+ ctzl(esz) - ctzl(sew) + vext_lmul(desc);
142
+ return (vlenb << emul) / esz;
143
+}
144
+
145
+/* set agnostic elements to 1s */
146
+void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
147
+ uint32_t tot);
148
+
149
+/* expand macro args before macro */
150
+#define RVVCALL(macro, ...) macro(__VA_ARGS__)
151
+
152
+/* (TD, T1, T2, TX1, TX2) */
153
+#define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
154
+#define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t
155
+#define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t
156
+#define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t
157
+
158
+/* operation of two vector elements */
159
+typedef void opivv2_fn(void *vd, void *vs1, void *vs2, int i);
160
+
161
+#define OPIVV2(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP) \
162
+static void do_##NAME(void *vd, void *vs1, void *vs2, int i) \
163
+{ \
164
+ TX1 s1 = *((T1 *)vs1 + HS1(i)); \
165
+ TX2 s2 = *((T2 *)vs2 + HS2(i)); \
166
+ *((TD *)vd + HD(i)) = OP(s2, s1); \
167
+}
168
+
169
+void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
170
+ CPURISCVState *env, uint32_t desc,
171
+ opivv2_fn *fn, uint32_t esz);
172
+
173
+/* generate the helpers for OPIVV */
174
+#define GEN_VEXT_VV(NAME, ESZ) \
175
+void HELPER(NAME)(void *vd, void *v0, void *vs1, \
176
+ void *vs2, CPURISCVState *env, \
177
+ uint32_t desc) \
178
+{ \
179
+ do_vext_vv(vd, v0, vs1, vs2, env, desc, \
180
+ do_##NAME, ESZ); \
181
+}
182
+
183
+typedef void opivx2_fn(void *vd, target_long s1, void *vs2, int i);
184
+
185
+/*
186
+ * (T1)s1 gives the real operator type.
187
+ * (TX1)(T1)s1 expands the operator type of widen or narrow operations.
188
+ */
189
+#define OPIVX2(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \
190
+static void do_##NAME(void *vd, target_long s1, void *vs2, int i) \
191
+{ \
192
+ TX2 s2 = *((T2 *)vs2 + HS2(i)); \
193
+ *((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1); \
194
+}
195
+
196
+void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
197
+ CPURISCVState *env, uint32_t desc,
198
+ opivx2_fn fn, uint32_t esz);
199
+
200
+/* generate the helpers for OPIVX */
201
+#define GEN_VEXT_VX(NAME, ESZ) \
202
+void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
203
+ void *vs2, CPURISCVState *env, \
204
+ uint32_t desc) \
205
+{ \
206
+ do_vext_vx(vd, v0, s1, vs2, env, desc, \
207
+ do_##NAME, ESZ); \
208
+}
209
+
210
+#endif /* TARGET_RISCV_VECTOR_INTERNALS_H */
211
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
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
88
new file mode 100644
492
new file mode 100644
89
index XXXXXXX..XXXXXXX
493
index XXXXXXX..XXXXXXX
90
--- /dev/null
494
--- /dev/null
91
+++ b/hw/misc/sifive_e_aon.c
495
+++ b/target/riscv/vector_internals.c
92
@@ -XXX,XX +XXX,XX @@
496
@@ -XXX,XX +XXX,XX @@
93
+/*
497
+/*
94
+ * SiFive HiFive1 AON (Always On Domain) for QEMU.
498
+ * RISC-V Vector Extension Internals
95
+ *
499
+ *
96
+ * Copyright (c) 2022 SiFive, Inc. All rights reserved.
500
+ * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
97
+ *
501
+ *
98
+ * This program is free software; you can redistribute it and/or modify it
502
+ * This program is free software; you can redistribute it and/or modify it
99
+ * under the terms and conditions of the GNU General Public License,
503
+ * under the terms and conditions of the GNU General Public License,
100
+ * version 2 or later, as published by the Free Software Foundation.
504
+ * version 2 or later, as published by the Free Software Foundation.
101
+ *
505
+ *
...
...
106
+ *
510
+ *
107
+ * You should have received a copy of the GNU General Public License along with
511
+ * You should have received a copy of the GNU General Public License along with
108
+ * this program. If not, see <http://www.gnu.org/licenses/>.
512
+ * this program. If not, see <http://www.gnu.org/licenses/>.
109
+ */
513
+ */
110
+
514
+
111
+#include "qemu/osdep.h"
515
+#include "vector_internals.h"
112
+#include "qemu/timer.h"
516
+
113
+#include "qemu/log.h"
517
+/* set agnostic elements to 1s */
114
+#include "hw/irq.h"
518
+void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
115
+#include "hw/registerfields.h"
519
+ uint32_t tot)
116
+#include "hw/misc/sifive_e_aon.h"
520
+{
117
+#include "qapi/visitor.h"
521
+ if (is_agnostic == 0) {
118
+#include "qapi/error.h"
522
+ /* policy undisturbed */
119
+#include "sysemu/watchdog.h"
120
+#include "hw/qdev-properties.h"
121
+
122
+REG32(AON_WDT_WDOGCFG, 0x0)
123
+ FIELD(AON_WDT_WDOGCFG, SCALE, 0, 4)
124
+ FIELD(AON_WDT_WDOGCFG, RSVD0, 4, 4)
125
+ FIELD(AON_WDT_WDOGCFG, RSTEN, 8, 1)
126
+ FIELD(AON_WDT_WDOGCFG, ZEROCMP, 9, 1)
127
+ FIELD(AON_WDT_WDOGCFG, RSVD1, 10, 2)
128
+ FIELD(AON_WDT_WDOGCFG, EN_ALWAYS, 12, 1)
129
+ FIELD(AON_WDT_WDOGCFG, EN_CORE_AWAKE, 13, 1)
130
+ FIELD(AON_WDT_WDOGCFG, RSVD2, 14, 14)
131
+ FIELD(AON_WDT_WDOGCFG, IP0, 28, 1)
132
+ FIELD(AON_WDT_WDOGCFG, RSVD3, 29, 3)
133
+REG32(AON_WDT_WDOGCOUNT, 0x8)
134
+ FIELD(AON_WDT_WDOGCOUNT, VALUE, 0, 31)
135
+REG32(AON_WDT_WDOGS, 0x10)
136
+REG32(AON_WDT_WDOGFEED, 0x18)
137
+REG32(AON_WDT_WDOGKEY, 0x1c)
138
+REG32(AON_WDT_WDOGCMP0, 0x20)
139
+
140
+static void sifive_e_aon_wdt_update_wdogcount(SiFiveEAONState *r)
141
+{
142
+ int64_t now;
143
+ if (FIELD_EX32(r->wdogcfg, AON_WDT_WDOGCFG, EN_ALWAYS) == 0 &&
144
+ FIELD_EX32(r->wdogcfg, AON_WDT_WDOGCFG, EN_CORE_AWAKE) == 0) {
145
+ return;
523
+ return;
146
+ }
524
+ }
147
+
525
+ if (tot - cnt == 0) {
148
+ now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
526
+ return ;
149
+ r->wdogcount += muldiv64(now - r->wdog_restart_time,
527
+ }
150
+ r->wdogclk_freq, NANOSECONDS_PER_SECOND);
528
+ memset(base + cnt, -1, tot - cnt);
151
+
529
+}
152
+ /* Clean the most significant bit. */
530
+
153
+ r->wdogcount &= R_AON_WDT_WDOGCOUNT_VALUE_MASK;
531
+void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
154
+ r->wdog_restart_time = now;
532
+ CPURISCVState *env, uint32_t desc,
155
+}
533
+ opivv2_fn *fn, uint32_t esz)
156
+
534
+{
157
+static void sifive_e_aon_wdt_update_state(SiFiveEAONState *r)
535
+ uint32_t vm = vext_vm(desc);
158
+{
536
+ uint32_t vl = env->vl;
159
+ uint16_t wdogs;
537
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
160
+ bool cmp_signal = false;
538
+ uint32_t vta = vext_vta(desc);
161
+ sifive_e_aon_wdt_update_wdogcount(r);
539
+ uint32_t vma = vext_vma(desc);
162
+ wdogs = (uint16_t)(r->wdogcount >>
540
+ uint32_t i;
163
+ FIELD_EX32(r->wdogcfg, AON_WDT_WDOGCFG, SCALE));
541
+
164
+
542
+ for (i = env->vstart; i < vl; i++) {
165
+ if (wdogs >= r->wdogcmp0) {
543
+ if (!vm && !vext_elem_mask(v0, i)) {
166
+ cmp_signal = true;
544
+ /* set masked-off elements to 1s */
167
+ if (FIELD_EX32(r->wdogcfg, AON_WDT_WDOGCFG, ZEROCMP) == 1) {
545
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
168
+ r->wdogcount = 0;
546
+ continue;
169
+ wdogs = 0;
170
+ }
547
+ }
548
+ fn(vd, vs1, vs2, i);
171
+ }
549
+ }
172
+
550
+ env->vstart = 0;
173
+ if (cmp_signal) {
551
+ /* set tail elements to 1s */
174
+ if (FIELD_EX32(r->wdogcfg, AON_WDT_WDOGCFG, RSTEN) == 1) {
552
+ vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
175
+ watchdog_perform_action();
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;
176
+ }
571
+ }
177
+ r->wdogcfg = FIELD_DP32(r->wdogcfg, AON_WDT_WDOGCFG, IP0, 1);
572
+ fn(vd, s1, vs2, i);
178
+ }
573
+ }
179
+
574
+ env->vstart = 0;
180
+ qemu_set_irq(r->wdog_irq, FIELD_EX32(r->wdogcfg, AON_WDT_WDOGCFG, IP0));
575
+ /* set tail elements to 1s */
181
+
576
+ vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
182
+ if (wdogs < r->wdogcmp0 &&
577
+}
183
+ (FIELD_EX32(r->wdogcfg, AON_WDT_WDOGCFG, EN_ALWAYS) == 1 ||
578
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
184
+ FIELD_EX32(r->wdogcfg, AON_WDT_WDOGCFG, EN_CORE_AWAKE) == 1)) {
185
+ int64_t next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
186
+ next += muldiv64((r->wdogcmp0 - wdogs) <<
187
+ FIELD_EX32(r->wdogcfg, AON_WDT_WDOGCFG, SCALE),
188
+ NANOSECONDS_PER_SECOND, r->wdogclk_freq);
189
+ timer_mod(r->wdog_timer, next);
190
+ } else {
191
+ timer_mod(r->wdog_timer, INT64_MAX);
192
+ }
193
+}
194
+
195
+/*
196
+ * Callback used when the timer set using timer_mod expires.
197
+ */
198
+static void sifive_e_aon_wdt_expired_cb(void *opaque)
199
+{
200
+ SiFiveEAONState *r = SIFIVE_E_AON(opaque);
201
+ sifive_e_aon_wdt_update_state(r);
202
+}
203
+
204
+static uint64_t
205
+sifive_e_aon_wdt_read(void *opaque, hwaddr addr, unsigned int size)
206
+{
207
+ SiFiveEAONState *r = SIFIVE_E_AON(opaque);
208
+
209
+ switch (addr) {
210
+ case A_AON_WDT_WDOGCFG:
211
+ return r->wdogcfg;
212
+ case A_AON_WDT_WDOGCOUNT:
213
+ sifive_e_aon_wdt_update_wdogcount(r);
214
+ return r->wdogcount;
215
+ case A_AON_WDT_WDOGS:
216
+ sifive_e_aon_wdt_update_wdogcount(r);
217
+ return r->wdogcount >>
218
+ FIELD_EX32(r->wdogcfg,
219
+ AON_WDT_WDOGCFG,
220
+ SCALE);
221
+ case A_AON_WDT_WDOGFEED:
222
+ return 0;
223
+ case A_AON_WDT_WDOGKEY:
224
+ return r->wdogunlock;
225
+ case A_AON_WDT_WDOGCMP0:
226
+ return r->wdogcmp0;
227
+ default:
228
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: bad read: addr=0x%x\n",
229
+ __func__, (int)addr);
230
+ }
231
+
232
+ return 0;
233
+}
234
+
235
+static void
236
+sifive_e_aon_wdt_write(void *opaque, hwaddr addr,
237
+ uint64_t val64, unsigned int size)
238
+{
239
+ SiFiveEAONState *r = SIFIVE_E_AON(opaque);
240
+ uint32_t value = val64;
241
+
242
+ switch (addr) {
243
+ case A_AON_WDT_WDOGCFG: {
244
+ uint8_t new_en_always;
245
+ uint8_t new_en_core_awake;
246
+ uint8_t old_en_always;
247
+ uint8_t old_en_core_awake;
248
+ if (r->wdogunlock == 0) {
249
+ return;
250
+ }
251
+
252
+ new_en_always = FIELD_EX32(value, AON_WDT_WDOGCFG, EN_ALWAYS);
253
+ new_en_core_awake = FIELD_EX32(value, AON_WDT_WDOGCFG, EN_CORE_AWAKE);
254
+ old_en_always = FIELD_EX32(r->wdogcfg, AON_WDT_WDOGCFG, EN_ALWAYS);
255
+ old_en_core_awake = FIELD_EX32(r->wdogcfg, AON_WDT_WDOGCFG,
256
+ EN_CORE_AWAKE);
257
+
258
+ if ((old_en_always ||
259
+ old_en_core_awake) == 1 &&
260
+ (new_en_always ||
261
+ new_en_core_awake) == 0) {
262
+ sifive_e_aon_wdt_update_wdogcount(r);
263
+ } else if ((old_en_always ||
264
+ old_en_core_awake) == 0 &&
265
+ (new_en_always ||
266
+ new_en_core_awake) == 1) {
267
+ r->wdog_restart_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
268
+ }
269
+ r->wdogcfg = value;
270
+ r->wdogunlock = 0;
271
+ break;
272
+ }
273
+ case A_AON_WDT_WDOGCOUNT:
274
+ if (r->wdogunlock == 0) {
275
+ return;
276
+ }
277
+ r->wdogcount = value & R_AON_WDT_WDOGCOUNT_VALUE_MASK;
278
+ r->wdog_restart_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
279
+ r->wdogunlock = 0;
280
+ break;
281
+ case A_AON_WDT_WDOGS:
282
+ return;
283
+ case A_AON_WDT_WDOGFEED:
284
+ if (r->wdogunlock == 0) {
285
+ return;
286
+ }
287
+ if (value == SIFIVE_E_AON_WDOGFEED) {
288
+ r->wdogcount = 0;
289
+ r->wdog_restart_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
290
+ }
291
+ r->wdogunlock = 0;
292
+ break;
293
+ case A_AON_WDT_WDOGKEY:
294
+ if (value == SIFIVE_E_AON_WDOGKEY) {
295
+ r->wdogunlock = 1;
296
+ }
297
+ break;
298
+ case A_AON_WDT_WDOGCMP0:
299
+ if (r->wdogunlock == 0) {
300
+ return;
301
+ }
302
+ r->wdogcmp0 = (uint16_t) value;
303
+ r->wdogunlock = 0;
304
+ break;
305
+ default:
306
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: bad write: addr=0x%x v=0x%x\n",
307
+ __func__, (int)addr, (int)value);
308
+ }
309
+ sifive_e_aon_wdt_update_state(r);
310
+}
311
+
312
+static uint64_t
313
+sifive_e_aon_read(void *opaque, hwaddr addr, unsigned int size)
314
+{
315
+ if (addr < SIFIVE_E_AON_RTC) {
316
+ return sifive_e_aon_wdt_read(opaque, addr, size);
317
+ } else if (addr < SIFIVE_E_AON_MAX) {
318
+ qemu_log_mask(LOG_UNIMP, "%s: Unimplemented read: addr=0x%x\n",
319
+ __func__, (int)addr);
320
+ } else {
321
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: bad read: addr=0x%x\n",
322
+ __func__, (int)addr);
323
+ }
324
+ return 0;
325
+}
326
+
327
+static void
328
+sifive_e_aon_write(void *opaque, hwaddr addr,
329
+ uint64_t val64, unsigned int size)
330
+{
331
+ if (addr < SIFIVE_E_AON_RTC) {
332
+ sifive_e_aon_wdt_write(opaque, addr, val64, size);
333
+ } else if (addr < SIFIVE_E_AON_MAX) {
334
+ qemu_log_mask(LOG_UNIMP, "%s: Unimplemented write: addr=0x%x\n",
335
+ __func__, (int)addr);
336
+ } else {
337
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: bad write: addr=0x%x\n",
338
+ __func__, (int)addr);
339
+ }
340
+}
341
+
342
+static const MemoryRegionOps sifive_e_aon_ops = {
343
+ .read = sifive_e_aon_read,
344
+ .write = sifive_e_aon_write,
345
+ .endianness = DEVICE_NATIVE_ENDIAN,
346
+ .impl = {
347
+ .min_access_size = 4,
348
+ .max_access_size = 4
349
+ },
350
+ .valid = {
351
+ .min_access_size = 4,
352
+ .max_access_size = 4
353
+ }
354
+};
355
+
356
+static void sifive_e_aon_reset(DeviceState *dev)
357
+{
358
+ SiFiveEAONState *r = SIFIVE_E_AON(dev);
359
+
360
+ r->wdogcfg = FIELD_DP32(r->wdogcfg, AON_WDT_WDOGCFG, RSTEN, 0);
361
+ r->wdogcfg = FIELD_DP32(r->wdogcfg, AON_WDT_WDOGCFG, EN_ALWAYS, 0);
362
+ r->wdogcfg = FIELD_DP32(r->wdogcfg, AON_WDT_WDOGCFG, EN_CORE_AWAKE, 0);
363
+ r->wdogcmp0 = 0xbeef;
364
+
365
+ sifive_e_aon_wdt_update_state(r);
366
+}
367
+
368
+static void sifive_e_aon_init(Object *obj)
369
+{
370
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
371
+ SiFiveEAONState *r = SIFIVE_E_AON(obj);
372
+
373
+ memory_region_init_io(&r->mmio, OBJECT(r), &sifive_e_aon_ops, r,
374
+ TYPE_SIFIVE_E_AON, SIFIVE_E_AON_MAX);
375
+ sysbus_init_mmio(sbd, &r->mmio);
376
+
377
+ /* watchdog timer */
378
+ r->wdog_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
379
+ sifive_e_aon_wdt_expired_cb, r);
380
+ r->wdogclk_freq = SIFIVE_E_LFCLK_DEFAULT_FREQ;
381
+ sysbus_init_irq(sbd, &r->wdog_irq);
382
+}
383
+
384
+static Property sifive_e_aon_properties[] = {
385
+ DEFINE_PROP_UINT64("wdogclk-frequency", SiFiveEAONState, wdogclk_freq,
386
+ SIFIVE_E_LFCLK_DEFAULT_FREQ),
387
+ DEFINE_PROP_END_OF_LIST(),
388
+};
389
+
390
+static void sifive_e_aon_class_init(ObjectClass *oc, void *data)
391
+{
392
+ DeviceClass *dc = DEVICE_CLASS(oc);
393
+
394
+ dc->reset = sifive_e_aon_reset;
395
+ device_class_set_props(dc, sifive_e_aon_properties);
396
+}
397
+
398
+static const TypeInfo sifive_e_aon_info = {
399
+ .name = TYPE_SIFIVE_E_AON,
400
+ .parent = TYPE_SYS_BUS_DEVICE,
401
+ .instance_size = sizeof(SiFiveEAONState),
402
+ .instance_init = sifive_e_aon_init,
403
+ .class_init = sifive_e_aon_class_init,
404
+};
405
+
406
+static void sifive_e_aon_register_types(void)
407
+{
408
+ type_register_static(&sifive_e_aon_info);
409
+}
410
+
411
+type_init(sifive_e_aon_register_types)
412
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
413
index XXXXXXX..XXXXXXX 100644
579
index XXXXXXX..XXXXXXX 100644
414
--- a/hw/misc/Kconfig
580
--- a/target/riscv/meson.build
415
+++ b/hw/misc/Kconfig
581
+++ b/target/riscv/meson.build
416
@@ -XXX,XX +XXX,XX @@ config SIFIVE_TEST
582
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(files(
417
config SIFIVE_E_PRCI
583
'gdbstub.c',
418
bool
584
'op_helper.c',
419
585
'vector_helper.c',
420
+config SIFIVE_E_AON
586
+ 'vector_internals.c',
421
+ bool
587
'bitmanip_helper.c',
422
+
588
'translate.c',
423
config SIFIVE_U_OTP
589
'm128_helper.c',
424
bool
425
426
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
427
index XXXXXXX..XXXXXXX 100644
428
--- a/hw/misc/meson.build
429
+++ b/hw/misc/meson.build
430
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_MCHP_PFSOC_IOSCB', if_true: files('mchp_pfsoc_ioscb.
431
system_ss.add(when: 'CONFIG_MCHP_PFSOC_SYSREG', if_true: files('mchp_pfsoc_sysreg.c'))
432
system_ss.add(when: 'CONFIG_SIFIVE_TEST', if_true: files('sifive_test.c'))
433
system_ss.add(when: 'CONFIG_SIFIVE_E_PRCI', if_true: files('sifive_e_prci.c'))
434
+system_ss.add(when: 'CONFIG_SIFIVE_E_AON', if_true: files('sifive_e_aon.c'))
435
system_ss.add(when: 'CONFIG_SIFIVE_U_OTP', if_true: files('sifive_u_otp.c'))
436
system_ss.add(when: 'CONFIG_SIFIVE_U_PRCI', if_true: files('sifive_u_prci.c'))
437
438
--
590
--
439
2.40.1
591
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
Our design philosophy with KVM properties can be resumed in two main
3
Refactor the non SEW-specific stuff out of `GEN_OPIVV_TRANS` into
4
decisions based on KVM interface availability and what the user wants to
4
function `opivv_trans` (similar to `opivi_trans`). `opivv_trans` will be
5
do:
5
used in proceeding vector-crypto commits.
6
6
7
- if the user disables an extension that the host KVM module doesn't
7
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
8
know about (i.e. it doesn't implement the kvm_get_one_reg() interface),
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
keep booting the CPU. This will avoid users having to deal with issues
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
with older KVM versions while disabling features they don't care;
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
11
11
Signed-off-by: Max Chou <max.chou@sifive.com>
12
- for any other case we're going to error out immediately. If the user
12
Message-ID: <20230711165917.2629866-3-max.chou@sifive.com>
13
wants to enable a feature that KVM doesn't know about this a problem that
14
is worth aborting - the user must know that the feature wasn't enabled
15
in the hart. Likewise, if KVM knows about the extension, the user wants
16
to enable/disable it, and we fail to do it so, that's also a problem we
17
can't shrug it off.
18
19
In the case of MISA bits we won't even try enabling bits that aren't
20
already available in the host. The ioctl() is so likely to fail that
21
it's not worth trying. This check is already done in the previous patch,
22
in kvm_cpu_set_misa_ext_cfg(), thus we don't need to worry about it now.
23
24
In kvm_riscv_update_cpu_misa_ext() we'll go through every potential user
25
option and do as follows:
26
27
- if the user didn't set the property or set to the same value of the
28
host, do nothing;
29
30
- Disable the given extension in KVM. Error out if anything goes wrong.
31
32
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
33
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
34
Acked-by: Alistair Francis <alistair.francis@wdc.com>
35
Message-Id: <20230706101738.460804-14-dbarboza@ventanamicro.com>
36
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
37
---
14
---
38
target/riscv/kvm.c | 40 ++++++++++++++++++++++++++++++++++++++++
15
target/riscv/insn_trans/trans_rvv.c.inc | 62 +++++++++++++------------
39
1 file changed, 40 insertions(+)
16
1 file changed, 32 insertions(+), 30 deletions(-)
40
17
41
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
18
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
42
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
43
--- a/target/riscv/kvm.c
20
--- a/target/riscv/insn_trans/trans_rvv.c.inc
44
+++ b/target/riscv/kvm.c
21
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
45
@@ -XXX,XX +XXX,XX @@ static void kvm_cpu_set_misa_ext_cfg(Object *obj, Visitor *v,
22
@@ -XXX,XX +XXX,XX @@ GEN_OPIWX_WIDEN_TRANS(vwadd_wx)
46
"enabled in the host", misa_ext_cfg->name);
23
GEN_OPIWX_WIDEN_TRANS(vwsubu_wx)
47
}
24
GEN_OPIWX_WIDEN_TRANS(vwsub_wx)
48
25
49
+static void kvm_riscv_update_cpu_misa_ext(RISCVCPU *cpu, CPUState *cs)
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)
50
+{
28
+{
51
+ CPURISCVState *env = &cpu->env;
29
+ uint32_t data = 0;
52
+ uint64_t id, reg;
30
+ TCGLabel *over = gen_new_label();
53
+ int i, ret;
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);
54
+
33
+
55
+ for (i = 0; i < ARRAY_SIZE(kvm_misa_ext_cfgs); i++) {
34
+ data = FIELD_DP32(data, VDATA, VM, vm);
56
+ KVMCPUConfig *misa_cfg = &kvm_misa_ext_cfgs[i];
35
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
57
+ target_ulong misa_bit = misa_cfg->offset;
36
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
58
+
37
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
59
+ if (!misa_cfg->user_set) {
38
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
60
+ continue;
39
+ tcg_gen_gvec_4_ptr(vreg_ofs(s, vd), vreg_ofs(s, 0), vreg_ofs(s, vs1),
61
+ }
40
+ vreg_ofs(s, vs2), cpu_env, s->cfg_ptr->vlen / 8,
62
+
41
+ s->cfg_ptr->vlen / 8, data, fn);
63
+ /* If we're here we're going to disable the MISA bit */
42
+ mark_vs_dirty(s);
64
+ reg = 0;
43
+ gen_set_label(over);
65
+ id = kvm_riscv_reg_id(env, KVM_REG_RISCV_ISA_EXT,
44
+ return true;
66
+ misa_cfg->kvm_reg_id);
67
+ ret = kvm_set_one_reg(cs, id, &reg);
68
+ if (ret != 0) {
69
+ /*
70
+ * We're not checking for -EINVAL because if the bit is about
71
+ * to be disabled, it means that it was already enabled by
72
+ * KVM. We determined that by fetching the 'isa' register
73
+ * during init() time. Any error at this point is worth
74
+ * aborting.
75
+ */
76
+ error_report("Unable to set KVM reg %s, error %d",
77
+ misa_cfg->name, ret);
78
+ exit(EXIT_FAILURE);
79
+ }
80
+ env->misa_ext &= ~misa_bit;
81
+ }
82
+}
45
+}
83
+
46
+
84
static void kvm_riscv_add_cpu_user_properties(Object *cpu_obj)
47
/* Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions */
85
{
48
/* OPIVV without GVEC IR */
86
int i;
49
-#define GEN_OPIVV_TRANS(NAME, CHECK) \
87
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
50
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
88
51
-{ \
89
if (!object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST)) {
52
- if (CHECK(s, a)) { \
90
ret = kvm_vcpu_set_machine_ids(cpu, cs);
53
- uint32_t data = 0; \
91
+ if (ret != 0) {
54
- static gen_helper_gvec_4_ptr * const fns[4] = { \
92
+ return ret;
55
- gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
93
+ }
56
- gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
94
}
57
- }; \
95
58
- TCGLabel *over = gen_new_label(); \
96
+ kvm_riscv_update_cpu_misa_ext(cpu, cs);
59
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
97
+
60
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
98
return ret;
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; \
99
}
90
}
100
91
92
/*
101
--
93
--
102
2.40.1
94
2.41.0
diff view generated by jsdifflib
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
Upon MRET or explicit memory access with MPRV=1, MPV should be ignored
3
Remove the redundant "vl == 0" check which is already included within the vstart >= vl check, when vl == 0.
4
when MPP=PRV_M.
5
4
6
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
5
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
7
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
6
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Signed-off-by: Max Chou <max.chou@sifive.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20230603134236.15719-2-liweiwei@iscas.ac.cn>
9
Message-ID: <20230711165917.2629866-4-max.chou@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
11
---
13
target/riscv/cpu_helper.c | 3 ++-
12
target/riscv/insn_trans/trans_rvv.c.inc | 31 +------------------------
14
target/riscv/op_helper.c | 3 ++-
13
1 file changed, 1 insertion(+), 30 deletions(-)
15
2 files changed, 4 insertions(+), 2 deletions(-)
16
14
17
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
15
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
16
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu_helper.c
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
20
+++ b/target/riscv/cpu_helper.c
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
21
@@ -XXX,XX +XXX,XX @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
19
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
22
20
TCGv_i32 desc;
23
if (mode == PRV_M && get_field(status, MSTATUS_MPRV)) {
21
24
mode = get_field(env->mstatus, MSTATUS_MPP);
22
TCGLabel *over = gen_new_label();
25
- virt = get_field(env->mstatus, MSTATUS_MPV);
23
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
26
+ virt = get_field(env->mstatus, MSTATUS_MPV) &&
24
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
27
+ (mode != PRV_M);
25
28
if (virt) {
26
dest = tcg_temp_new_ptr();
29
status = env->vsstatus;
27
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
30
}
28
TCGv_i32 desc;
31
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
29
32
index XXXXXXX..XXXXXXX 100644
30
TCGLabel *over = gen_new_label();
33
--- a/target/riscv/op_helper.c
31
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
34
+++ b/target/riscv/op_helper.c
32
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
35
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mret(CPURISCVState *env)
33
36
riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC());
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;
37
}
53
}
38
54
39
- target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV);
55
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
40
+ target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV) &&
56
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
41
+ (prev_priv != PRV_M);
57
42
mstatus = set_field(mstatus, MSTATUS_MIE,
58
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
43
get_field(mstatus, MSTATUS_MPIE));
59
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
44
mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
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] = {
45
--
253
--
46
2.40.1
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 introduces the RISC-V Zfa extension, which introduces
3
This commit adds support for the Zvbc vector-crypto extension, which
4
additional floating-point instructions:
4
consists of the following instructions:
5
* fli (load-immediate) with pre-defined immediates
5
6
* fminm/fmaxm (like fmin/fmax but with different NaN behaviour)
6
* vclmulh.[vx,vv]
7
* fround/froundmx (round to integer)
7
* vclmul.[vx,vv]
8
* fcvtmod.w.d (Modular Convert-to-Integer)
8
9
* fmv* to access high bits of float register bigger than XLEN
9
Translation functions are defined in
10
* Quiet comparison instructions (fleq/fltq)
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
11
`target/riscv/vcrypto_helper.c`.
12
Zfa defines its instructions in combination with the following extensions:
12
13
* single-precision floating-point (F)
13
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
14
* double-precision floating-point (D)
14
Co-authored-by: Max Chou <max.chou@sifive.com>
15
* quad-precision floating-point (Q)
15
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
16
* half-precision floating-point (Zfh)
16
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
17
17
Signed-off-by: Max Chou <max.chou@sifive.com>
18
Since QEMU does not support the RISC-V quad-precision floating-point
18
[max.chou@sifive.com: Exposed x-zvbc property]
19
ISA extension (Q), this patch does not include the instructions that
19
Message-ID: <20230711165917.2629866-5-max.chou@sifive.com>
20
depend on this extension. All other instructions are included in this
21
patch.
22
23
The Zfa specification can be found here:
24
https://github.com/riscv/riscv-isa-manual/blob/master/src/zfa.tex
25
The Zfa specifciation is frozen and is in public review since May 3, 2023:
26
https://groups.google.com/a/groups.riscv.org/g/isa-dev/c/SED4ntBkabg
27
28
The patch also includes a TCG test for the fcvtmod.w.d instruction.
29
The test cases test for correct results and flag behaviour.
30
Note, that the Zfa specification requires fcvtmod's flag behaviour
31
to be identical to a fcvt with the same operands (which is also
32
tested).
33
34
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
35
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
36
Message-Id: <20230710071243.282464-1-christoph.muellner@vrull.eu>
37
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
38
---
21
---
39
disas/riscv.h | 3 +
22
target/riscv/cpu_cfg.h | 1 +
40
target/riscv/cpu_cfg.h | 1 +
23
target/riscv/helper.h | 6 +++
41
target/riscv/helper.h | 19 +
24
target/riscv/insn32.decode | 6 +++
42
target/riscv/insn32.decode | 26 ++
25
target/riscv/cpu.c | 9 ++++
43
disas/riscv.c | 139 ++++++
26
target/riscv/translate.c | 1 +
44
target/riscv/cpu.c | 8 +
27
target/riscv/vcrypto_helper.c | 59 ++++++++++++++++++++++
45
target/riscv/fpu_helper.c | 154 +++++++
28
target/riscv/insn_trans/trans_rvvk.c.inc | 62 ++++++++++++++++++++++++
46
target/riscv/translate.c | 1 +
29
target/riscv/meson.build | 3 +-
47
tests/tcg/riscv64/test-fcvtmod.c | 345 ++++++++++++++
30
8 files changed, 146 insertions(+), 1 deletion(-)
48
target/riscv/insn_trans/trans_rvzfa.c.inc | 521 ++++++++++++++++++++++
31
create mode 100644 target/riscv/vcrypto_helper.c
49
tests/tcg/riscv64/Makefile.target | 6 +
32
create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc
50
11 files changed, 1223 insertions(+)
33
51
create mode 100644 tests/tcg/riscv64/test-fcvtmod.c
52
create mode 100644 target/riscv/insn_trans/trans_rvzfa.c.inc
53
54
diff --git a/disas/riscv.h b/disas/riscv.h
55
index XXXXXXX..XXXXXXX 100644
56
--- a/disas/riscv.h
57
+++ b/disas/riscv.h
58
@@ -XXX,XX +XXX,XX @@ typedef enum {
59
rv_codec_r_imm2,
60
rv_codec_r2_immhl,
61
rv_codec_r2_imm2_imm5,
62
+ rv_codec_fli,
63
} rv_codec;
64
65
/* structures */
66
@@ -XXX,XX +XXX,XX @@ enum {
67
#define rv_fmt_rd_offset "O\t0,o"
68
#define rv_fmt_rd_rs1_rs2 "O\t0,1,2"
69
#define rv_fmt_frd_rs1 "O\t3,1"
70
+#define rv_fmt_frd_rs1_rs2 "O\t3,1,2"
71
#define rv_fmt_frd_frs1 "O\t3,4"
72
#define rv_fmt_rd_frs1 "O\t0,4"
73
#define rv_fmt_rd_frs1_frs2 "O\t0,4,5"
74
@@ -XXX,XX +XXX,XX @@ enum {
75
#define rv_fmt_rd_rs1_immh_imml "O\t0,1,i,j"
76
#define rv_fmt_rd_rs1_immh_imml_addr "O\t0,(1),i,j"
77
#define rv_fmt_rd2_imm "O\t0,2,(1),i"
78
+#define rv_fmt_fli "O\t3,h"
79
80
#endif /* DISAS_RISCV_H */
81
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
34
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
82
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
83
--- a/target/riscv/cpu_cfg.h
36
--- a/target/riscv/cpu_cfg.h
84
+++ b/target/riscv/cpu_cfg.h
37
+++ b/target/riscv/cpu_cfg.h
85
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
38
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
86
bool ext_svpbmt;
39
bool ext_zve32f;
87
bool ext_zdinx;
40
bool ext_zve64f;
88
bool ext_zawrs;
41
bool ext_zve64d;
89
+ bool ext_zfa;
42
+ bool ext_zvbc;
90
bool ext_zfbfmin;
43
bool ext_zmmul;
91
bool ext_zfh;
44
bool ext_zvfbfmin;
92
bool ext_zfhmin;
45
bool ext_zvfbfwma;
93
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
46
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
94
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
95
--- a/target/riscv/helper.h
48
--- a/target/riscv/helper.h
96
+++ b/target/riscv/helper.h
49
+++ b/target/riscv/helper.h
97
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fsub_s, TCG_CALL_NO_RWG, i64, env, i64, i64)
50
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vfwcvtbf16_f_f_v, void, ptr, ptr, ptr, env, i32)
98
DEF_HELPER_FLAGS_3(fmul_s, TCG_CALL_NO_RWG, i64, env, i64, i64)
51
99
DEF_HELPER_FLAGS_3(fdiv_s, TCG_CALL_NO_RWG, i64, env, i64, i64)
52
DEF_HELPER_6(vfwmaccbf16_vv, void, ptr, ptr, ptr, ptr, env, i32)
100
DEF_HELPER_FLAGS_3(fmin_s, TCG_CALL_NO_RWG, i64, env, i64, i64)
53
DEF_HELPER_6(vfwmaccbf16_vf, void, ptr, ptr, i64, ptr, env, i32)
101
+DEF_HELPER_FLAGS_3(fminm_s, TCG_CALL_NO_RWG, i64, env, i64, i64)
54
+
102
DEF_HELPER_FLAGS_3(fmax_s, TCG_CALL_NO_RWG, i64, env, i64, i64)
55
+/* Vector crypto functions */
103
+DEF_HELPER_FLAGS_3(fmaxm_s, TCG_CALL_NO_RWG, i64, env, i64, i64)
56
+DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
104
DEF_HELPER_FLAGS_2(fsqrt_s, TCG_CALL_NO_RWG, i64, env, i64)
57
+DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
105
DEF_HELPER_FLAGS_3(fle_s, TCG_CALL_NO_RWG, tl, env, i64, i64)
58
+DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
106
+DEF_HELPER_FLAGS_3(fleq_s, TCG_CALL_NO_RWG, tl, env, i64, i64)
59
+DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
107
DEF_HELPER_FLAGS_3(flt_s, TCG_CALL_NO_RWG, tl, env, i64, i64)
108
+DEF_HELPER_FLAGS_3(fltq_s, TCG_CALL_NO_RWG, tl, env, i64, i64)
109
DEF_HELPER_FLAGS_3(feq_s, TCG_CALL_NO_RWG, tl, env, i64, i64)
110
DEF_HELPER_FLAGS_2(fcvt_w_s, TCG_CALL_NO_RWG, tl, env, i64)
111
DEF_HELPER_FLAGS_2(fcvt_wu_s, TCG_CALL_NO_RWG, tl, env, i64)
112
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(fcvt_s_wu, TCG_CALL_NO_RWG, i64, env, tl)
113
DEF_HELPER_FLAGS_2(fcvt_s_l, TCG_CALL_NO_RWG, i64, env, tl)
114
DEF_HELPER_FLAGS_2(fcvt_s_lu, TCG_CALL_NO_RWG, i64, env, tl)
115
DEF_HELPER_FLAGS_2(fclass_s, TCG_CALL_NO_RWG_SE, tl, env, i64)
116
+DEF_HELPER_FLAGS_2(fround_s, TCG_CALL_NO_RWG_SE, i64, env, i64)
117
+DEF_HELPER_FLAGS_2(froundnx_s, TCG_CALL_NO_RWG_SE, i64, env, i64)
118
119
/* Floating Point - Double Precision */
120
DEF_HELPER_FLAGS_3(fadd_d, TCG_CALL_NO_RWG, i64, env, i64, i64)
121
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fsub_d, TCG_CALL_NO_RWG, i64, env, i64, i64)
122
DEF_HELPER_FLAGS_3(fmul_d, TCG_CALL_NO_RWG, i64, env, i64, i64)
123
DEF_HELPER_FLAGS_3(fdiv_d, TCG_CALL_NO_RWG, i64, env, i64, i64)
124
DEF_HELPER_FLAGS_3(fmin_d, TCG_CALL_NO_RWG, i64, env, i64, i64)
125
+DEF_HELPER_FLAGS_3(fminm_d, TCG_CALL_NO_RWG, i64, env, i64, i64)
126
DEF_HELPER_FLAGS_3(fmax_d, TCG_CALL_NO_RWG, i64, env, i64, i64)
127
+DEF_HELPER_FLAGS_3(fmaxm_d, TCG_CALL_NO_RWG, i64, env, i64, i64)
128
DEF_HELPER_FLAGS_2(fcvt_s_d, TCG_CALL_NO_RWG, i64, env, i64)
129
DEF_HELPER_FLAGS_2(fcvt_d_s, TCG_CALL_NO_RWG, i64, env, i64)
130
DEF_HELPER_FLAGS_2(fsqrt_d, TCG_CALL_NO_RWG, i64, env, i64)
131
DEF_HELPER_FLAGS_3(fle_d, TCG_CALL_NO_RWG, tl, env, i64, i64)
132
+DEF_HELPER_FLAGS_3(fleq_d, TCG_CALL_NO_RWG, tl, env, i64, i64)
133
DEF_HELPER_FLAGS_3(flt_d, TCG_CALL_NO_RWG, tl, env, i64, i64)
134
+DEF_HELPER_FLAGS_3(fltq_d, TCG_CALL_NO_RWG, tl, env, i64, i64)
135
DEF_HELPER_FLAGS_3(feq_d, TCG_CALL_NO_RWG, tl, env, i64, i64)
136
DEF_HELPER_FLAGS_2(fcvt_w_d, TCG_CALL_NO_RWG, tl, env, i64)
137
+DEF_HELPER_FLAGS_2(fcvtmod_w_d, TCG_CALL_NO_RWG, i64, env, i64)
138
DEF_HELPER_FLAGS_2(fcvt_wu_d, TCG_CALL_NO_RWG, tl, env, i64)
139
DEF_HELPER_FLAGS_2(fcvt_l_d, TCG_CALL_NO_RWG, tl, env, i64)
140
DEF_HELPER_FLAGS_2(fcvt_lu_d, TCG_CALL_NO_RWG, tl, env, i64)
141
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(fcvt_d_wu, TCG_CALL_NO_RWG, i64, env, tl)
142
DEF_HELPER_FLAGS_2(fcvt_d_l, TCG_CALL_NO_RWG, i64, env, tl)
143
DEF_HELPER_FLAGS_2(fcvt_d_lu, TCG_CALL_NO_RWG, i64, env, tl)
144
DEF_HELPER_FLAGS_1(fclass_d, TCG_CALL_NO_RWG_SE, tl, i64)
145
+DEF_HELPER_FLAGS_2(fround_d, TCG_CALL_NO_RWG_SE, i64, env, i64)
146
+DEF_HELPER_FLAGS_2(froundnx_d, TCG_CALL_NO_RWG_SE, i64, env, i64)
147
148
/* Bitmanip */
149
DEF_HELPER_FLAGS_2(clmul, TCG_CALL_NO_RWG_SE, tl, tl, tl)
150
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fsub_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
151
DEF_HELPER_FLAGS_3(fmul_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
152
DEF_HELPER_FLAGS_3(fdiv_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
153
DEF_HELPER_FLAGS_3(fmin_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
154
+DEF_HELPER_FLAGS_3(fminm_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
155
DEF_HELPER_FLAGS_3(fmax_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
156
+DEF_HELPER_FLAGS_3(fmaxm_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
157
DEF_HELPER_FLAGS_2(fsqrt_h, TCG_CALL_NO_RWG, i64, env, i64)
158
DEF_HELPER_FLAGS_3(fle_h, TCG_CALL_NO_RWG, tl, env, i64, i64)
159
+DEF_HELPER_FLAGS_3(fleq_h, TCG_CALL_NO_RWG, tl, env, i64, i64)
160
DEF_HELPER_FLAGS_3(flt_h, TCG_CALL_NO_RWG, tl, env, i64, i64)
161
+DEF_HELPER_FLAGS_3(fltq_h, TCG_CALL_NO_RWG, tl, env, i64, i64)
162
DEF_HELPER_FLAGS_3(feq_h, TCG_CALL_NO_RWG, tl, env, i64, i64)
163
DEF_HELPER_FLAGS_2(fcvt_s_h, TCG_CALL_NO_RWG, i64, env, i64)
164
DEF_HELPER_FLAGS_2(fcvt_h_s, TCG_CALL_NO_RWG, i64, env, i64)
165
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(fcvt_h_wu, TCG_CALL_NO_RWG, i64, env, tl)
166
DEF_HELPER_FLAGS_2(fcvt_h_l, TCG_CALL_NO_RWG, i64, env, tl)
167
DEF_HELPER_FLAGS_2(fcvt_h_lu, TCG_CALL_NO_RWG, i64, env, tl)
168
DEF_HELPER_FLAGS_2(fclass_h, TCG_CALL_NO_RWG_SE, tl, env, i64)
169
+DEF_HELPER_FLAGS_2(fround_h, TCG_CALL_NO_RWG_SE, i64, env, i64)
170
+DEF_HELPER_FLAGS_2(froundnx_h, TCG_CALL_NO_RWG_SE, i64, env, i64)
171
172
/* Cache-block operations */
173
DEF_HELPER_2(cbo_clean_flush, void, env, tl)
174
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
60
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
175
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
176
--- a/target/riscv/insn32.decode
62
--- a/target/riscv/insn32.decode
177
+++ b/target/riscv/insn32.decode
63
+++ b/target/riscv/insn32.decode
178
@@ -XXX,XX +XXX,XX @@ binvi 01101. ........... 001 ..... 0010011 @sh
64
@@ -XXX,XX +XXX,XX @@ vfwcvtbf16_f_f_v 010010 . ..... 01101 001 ..... 1010111 @r2_vm
179
bset 0010100 .......... 001 ..... 0110011 @r
65
# *** Zvfbfwma Standard Extension ***
180
bseti 00101. ........... 001 ..... 0010011 @sh
66
vfwmaccbf16_vv 111011 . ..... ..... 001 ..... 1010111 @r_vm
181
67
vfwmaccbf16_vf 111011 . ..... ..... 101 ..... 1010111 @r_vm
182
+# *** Zfa Standard Extension ***
68
+
183
+fli_s 1111000 00001 ..... 000 ..... 1010011 @r2
69
+# *** Zvbc vector crypto extension ***
184
+fli_d 1111001 00001 ..... 000 ..... 1010011 @r2
70
+vclmul_vv 001100 . ..... ..... 010 ..... 1010111 @r_vm
185
+fli_h 1111010 00001 ..... 000 ..... 1010011 @r2
71
+vclmul_vx 001100 . ..... ..... 110 ..... 1010111 @r_vm
186
+fminm_s 0010100 ..... ..... 010 ..... 1010011 @r
72
+vclmulh_vv 001101 . ..... ..... 010 ..... 1010111 @r_vm
187
+fmaxm_s 0010100 ..... ..... 011 ..... 1010011 @r
73
+vclmulh_vx 001101 . ..... ..... 110 ..... 1010111 @r_vm
188
+fminm_d 0010101 ..... ..... 010 ..... 1010011 @r
189
+fmaxm_d 0010101 ..... ..... 011 ..... 1010011 @r
190
+fminm_h 0010110 ..... ..... 010 ..... 1010011 @r
191
+fmaxm_h 0010110 ..... ..... 011 ..... 1010011 @r
192
+fround_s 0100000 00100 ..... ... ..... 1010011 @r2_rm
193
+froundnx_s 0100000 00101 ..... ... ..... 1010011 @r2_rm
194
+fround_d 0100001 00100 ..... ... ..... 1010011 @r2_rm
195
+froundnx_d 0100001 00101 ..... ... ..... 1010011 @r2_rm
196
+fround_h 0100010 00100 ..... ... ..... 1010011 @r2_rm
197
+froundnx_h 0100010 00101 ..... ... ..... 1010011 @r2_rm
198
+fcvtmod_w_d 1100001 01000 ..... 001 ..... 1010011 @r2
199
+fmvh_x_d 1110001 00001 ..... 000 ..... 1010011 @r2
200
+fmvp_d_x 1011001 ..... ..... 000 ..... 1010011 @r
201
+fleq_s 1010000 ..... ..... 100 ..... 1010011 @r
202
+fltq_s 1010000 ..... ..... 101 ..... 1010011 @r
203
+fleq_d 1010001 ..... ..... 100 ..... 1010011 @r
204
+fltq_d 1010001 ..... ..... 101 ..... 1010011 @r
205
+fleq_h 1010010 ..... ..... 100 ..... 1010011 @r
206
+fltq_h 1010010 ..... ..... 101 ..... 1010011 @r
207
+
208
# *** RV32 Zfh Extension ***
209
flh ............ ..... 001 ..... 0000111 @i
210
fsh ....... ..... ..... 001 ..... 0100111 @s
211
diff --git a/disas/riscv.c b/disas/riscv.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/disas/riscv.c
214
+++ b/disas/riscv.c
215
@@ -XXX,XX +XXX,XX @@ typedef enum {
216
rv_op_fsh = 798,
217
rv_op_fmv_h_x = 799,
218
rv_op_fmv_x_h = 800,
219
+ rv_op_fli_s = 801,
220
+ rv_op_fli_d = 802,
221
+ rv_op_fli_q = 803,
222
+ rv_op_fli_h = 804,
223
+ rv_op_fminm_s = 805,
224
+ rv_op_fmaxm_s = 806,
225
+ rv_op_fminm_d = 807,
226
+ rv_op_fmaxm_d = 808,
227
+ rv_op_fminm_q = 809,
228
+ rv_op_fmaxm_q = 810,
229
+ rv_op_fminm_h = 811,
230
+ rv_op_fmaxm_h = 812,
231
+ rv_op_fround_s = 813,
232
+ rv_op_froundnx_s = 814,
233
+ rv_op_fround_d = 815,
234
+ rv_op_froundnx_d = 816,
235
+ rv_op_fround_q = 817,
236
+ rv_op_froundnx_q = 818,
237
+ rv_op_fround_h = 819,
238
+ rv_op_froundnx_h = 820,
239
+ rv_op_fcvtmod_w_d = 821,
240
+ rv_op_fmvh_x_d = 822,
241
+ rv_op_fmvp_d_x = 823,
242
+ rv_op_fmvh_x_q = 824,
243
+ rv_op_fmvp_q_x = 825,
244
+ rv_op_fleq_s = 826,
245
+ rv_op_fltq_s = 827,
246
+ rv_op_fleq_d = 828,
247
+ rv_op_fltq_d = 829,
248
+ rv_op_fleq_q = 830,
249
+ rv_op_fltq_q = 831,
250
+ rv_op_fleq_h = 832,
251
+ rv_op_fltq_h = 833,
252
} rv_op;
253
254
/* register names */
255
@@ -XXX,XX +XXX,XX @@ static const char rv_vreg_name_sym[32][4] = {
256
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
257
};
258
259
+/* The FLI.[HSDQ] numeric constants (0.0 for symbolic constants).
260
+ * The constants use the hex floating-point literal representation
261
+ * that is printed when using the printf %a format specifier,
262
+ * which matches the output that is generated by the disassembler.
263
+ */
264
+static const char rv_fli_name_const[32][9] =
265
+{
266
+ "0x1p+0", "min", "0x1p-16", "0x1p-15",
267
+ "0x1p-8", "0x1p-7", "0x1p-4", "0x1p-3",
268
+ "0x1p-2", "0x1.4p-2", "0x1.8p-2", "0x1.cp-2",
269
+ "0x1p-1", "0x1.4p-1", "0x1.8p-1", "0x1.cp-1",
270
+ "0x1p+0", "0x1.4p+0", "0x1.8p+0", "0x1.cp+0",
271
+ "0x1p+1", "0x1.4p+1", "0x1.8p+1", "0x1p+2",
272
+ "0x1p+3", "0x1p+4", "0x1p+7", "0x1p+8",
273
+ "0x1p+15", "0x1p+16", "inf", "nan"
274
+};
275
+
276
/* pseudo-instruction constraints */
277
278
static const rvc_constraint rvcc_jal[] = { rvc_rd_eq_ra, rvc_end };
279
@@ -XXX,XX +XXX,XX @@ const rv_opcode_data rvi_opcode_data[] = {
280
{ "fsh", rv_codec_s, rv_fmt_frs2_offset_rs1, NULL, 0, 0, 0 },
281
{ "fmv.h.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
282
{ "fmv.x.h", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
283
+ { "fli.s", rv_codec_fli, rv_fmt_fli, NULL, 0, 0, 0 },
284
+ { "fli.d", rv_codec_fli, rv_fmt_fli, NULL, 0, 0, 0 },
285
+ { "fli.q", rv_codec_fli, rv_fmt_fli, NULL, 0, 0, 0 },
286
+ { "fli.h", rv_codec_fli, rv_fmt_fli, NULL, 0, 0, 0 },
287
+ { "fminm.s", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
288
+ { "fmaxm.s", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
289
+ { "fminm.d", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
290
+ { "fmaxm.d", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
291
+ { "fminm.q", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
292
+ { "fmaxm.q", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
293
+ { "fminm.h", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
294
+ { "fmaxm.h", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
295
+ { "fround.s", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
296
+ { "froundnx.s", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
297
+ { "fround.d", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
298
+ { "froundnx.d", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
299
+ { "fround.q", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
300
+ { "froundnx.q", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
301
+ { "fround.h", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
302
+ { "froundnx.h", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
303
+ { "fcvtmod.w.d", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
304
+ { "fmvh.x.d", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
305
+ { "fmvp.d.x", rv_codec_r, rv_fmt_frd_rs1_rs2, NULL, 0, 0, 0 },
306
+ { "fmvh.x.q", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
307
+ { "fmvp.q.x", rv_codec_r, rv_fmt_frd_rs1_rs2, NULL, 0, 0, 0 },
308
+ { "fleq.s", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
309
+ { "fltq.s", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
310
+ { "fleq.d", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
311
+ { "fltq.d", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
312
+ { "fleq.q", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
313
+ { "fltq.q", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
314
+ { "fleq.h", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
315
+ { "fltq.h", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
316
};
317
318
/* CSR names */
319
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
320
switch ((inst >> 12) & 0b111) {
321
case 0: op = rv_op_fmin_s; break;
322
case 1: op = rv_op_fmax_s; break;
323
+ case 2: op = rv_op_fminm_s; break;
324
+ case 3: op = rv_op_fmaxm_s; break;
325
}
326
break;
327
case 21:
328
switch ((inst >> 12) & 0b111) {
329
case 0: op = rv_op_fmin_d; break;
330
case 1: op = rv_op_fmax_d; break;
331
+ case 2: op = rv_op_fminm_d; break;
332
+ case 3: op = rv_op_fmaxm_d; break;
333
+ }
334
+ break;
335
+ case 22:
336
+ switch (((inst >> 12) & 0b111)) {
337
+ case 2: op = rv_op_fminm_h; break;
338
+ case 3: op = rv_op_fmaxm_h; break;
339
}
340
break;
341
case 23:
342
switch ((inst >> 12) & 0b111) {
343
case 0: op = rv_op_fmin_q; break;
344
case 1: op = rv_op_fmax_q; break;
345
+ case 2: op = rv_op_fminm_q; break;
346
+ case 3: op = rv_op_fmaxm_q; break;
347
}
348
break;
349
case 32:
350
switch ((inst >> 20) & 0b11111) {
351
case 1: op = rv_op_fcvt_s_d; break;
352
case 3: op = rv_op_fcvt_s_q; break;
353
+ case 4: op = rv_op_fround_s; break;
354
+ case 5: op = rv_op_froundnx_s; break;
355
case 6: op = rv_op_fcvt_s_bf16; break;
356
}
357
break;
358
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
359
switch ((inst >> 20) & 0b11111) {
360
case 0: op = rv_op_fcvt_d_s; break;
361
case 3: op = rv_op_fcvt_d_q; break;
362
+ case 4: op = rv_op_fround_d; break;
363
+ case 5: op = rv_op_froundnx_d; break;
364
}
365
break;
366
case 34:
367
switch (((inst >> 20) & 0b11111)) {
368
+ case 4: op = rv_op_fround_h; break;
369
+ case 5: op = rv_op_froundnx_h; break;
370
case 8: op = rv_op_fcvt_bf16_s; break;
371
}
372
break;
373
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
374
switch ((inst >> 20) & 0b11111) {
375
case 0: op = rv_op_fcvt_q_s; break;
376
case 1: op = rv_op_fcvt_q_d; break;
377
+ case 4: op = rv_op_fround_q; break;
378
+ case 5: op = rv_op_froundnx_q; break;
379
}
380
break;
381
case 44:
382
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
383
case 0: op = rv_op_fle_s; break;
384
case 1: op = rv_op_flt_s; break;
385
case 2: op = rv_op_feq_s; break;
386
+ case 4: op = rv_op_fleq_s; break;
387
+ case 5: op = rv_op_fltq_s; break;
388
}
389
break;
390
case 81:
391
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
392
case 0: op = rv_op_fle_d; break;
393
case 1: op = rv_op_flt_d; break;
394
case 2: op = rv_op_feq_d; break;
395
+ case 4: op = rv_op_fleq_d; break;
396
+ case 5: op = rv_op_fltq_d; break;
397
+ }
398
+ break;
399
+ case 82:
400
+ switch (((inst >> 12) & 0b111)) {
401
+ case 4: op = rv_op_fleq_h; break;
402
+ case 5: op = rv_op_fltq_h; break;
403
}
404
break;
405
case 83:
406
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
407
case 0: op = rv_op_fle_q; break;
408
case 1: op = rv_op_flt_q; break;
409
case 2: op = rv_op_feq_q; break;
410
+ case 4: op = rv_op_fleq_q; break;
411
+ case 5: op = rv_op_fltq_q; break;
412
+ }
413
+ break;
414
+ case 89:
415
+        switch (((inst >> 12) & 0b111)) {
416
+ case 0: op = rv_op_fmvp_d_x; break;
417
+ }
418
+ break;
419
+ case 91:
420
+        switch (((inst >> 12) & 0b111)) {
421
+ case 0: op = rv_op_fmvp_q_x; break;
422
}
423
break;
424
case 96:
425
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
426
case 1: op = rv_op_fcvt_wu_d; break;
427
case 2: op = rv_op_fcvt_l_d; break;
428
case 3: op = rv_op_fcvt_lu_d; break;
429
+ case 8: op = rv_op_fcvtmod_w_d; break;
430
}
431
break;
432
case 99:
433
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
434
((inst >> 12) & 0b00000111)) {
435
case 0: op = rv_op_fmv_x_d; break;
436
case 1: op = rv_op_fclass_d; break;
437
+ case 8: op = rv_op_fmvh_x_d; break;
438
}
439
break;
440
case 114:
441
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
442
((inst >> 12) & 0b00000111)) {
443
case 0: op = rv_op_fmv_x_q; break;
444
case 1: op = rv_op_fclass_q; break;
445
+ case 8: op = rv_op_fmvh_x_q; break;
446
}
447
break;
448
case 120:
449
switch (((inst >> 17) & 0b11111000) |
450
((inst >> 12) & 0b00000111)) {
451
case 0: op = rv_op_fmv_s_x; break;
452
+ case 8: op = rv_op_fli_s; break;
453
}
454
break;
455
case 121:
456
switch (((inst >> 17) & 0b11111000) |
457
((inst >> 12) & 0b00000111)) {
458
case 0: op = rv_op_fmv_d_x; break;
459
+ case 8: op = rv_op_fli_d; break;
460
}
461
break;
462
case 122:
463
switch (((inst >> 17) & 0b11111000) |
464
((inst >> 12) & 0b00000111)) {
465
case 0: op = rv_op_fmv_h_x; break;
466
+ case 8: op = rv_op_fli_h; break;
467
}
468
break;
469
case 123:
470
switch (((inst >> 17) & 0b11111000) |
471
((inst >> 12) & 0b00000111)) {
472
case 0: op = rv_op_fmv_q_x; break;
473
+ case 8: op = rv_op_fli_q; break;
474
}
475
break;
476
}
477
@@ -XXX,XX +XXX,XX @@ static void decode_inst_operands(rv_decode *dec, rv_isa isa)
478
break;
479
case rv_codec_zcmt_jt:
480
dec->imm = operand_tbl_index(inst);
481
+    break;
482
+ case rv_codec_fli:
483
+ dec->rd = operand_rd(inst);
484
+ dec->imm = operand_rs1(inst);
485
break;
486
case rv_codec_r2_imm5:
487
dec->rd = operand_rd(inst);
488
@@ -XXX,XX +XXX,XX @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
489
append(buf, tmp, buflen);
490
break;
491
}
492
+ case 'h':
493
+ append(buf, rv_fli_name_const[dec->imm], buflen);
494
+ break;
495
default:
496
break;
497
}
498
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
499
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
500
--- a/target/riscv/cpu.c
76
--- a/target/riscv/cpu.c
501
+++ b/target/riscv/cpu.c
77
+++ b/target/riscv/cpu.c
502
@@ -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[] = {
503
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
79
ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
504
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
80
ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
505
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
81
ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
506
+ ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
82
+ ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
507
ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
83
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
508
ISA_EXT_DATA_ENTRY(zfh, PRIV_VERSION_1_11_0, ext_zfh),
84
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
509
ISA_EXT_DATA_ENTRY(zfhmin, PRIV_VERSION_1_11_0, ext_zfhmin),
85
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
510
@@ -XXX,XX +XXX,XX @@ static void rv64_thead_c906_cpu_init(Object *obj)
511
set_misa(env, MXL_RV64, RVG | RVC | RVS | RVU);
512
env->priv_ver = PRIV_VERSION_1_11_0;
513
514
+ cpu->cfg.ext_zfa = true;
515
cpu->cfg.ext_zfh = true;
516
cpu->cfg.mmu = true;
517
cpu->cfg.ext_xtheadba = true;
518
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
86
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
519
return;
87
return;
520
}
88
}
521
89
522
+ if (cpu->cfg.ext_zfa && !riscv_has_ext(env, RVF)) {
90
+ if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
523
+ error_setg(errp, "Zfa extension requires F extension");
91
+ error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
524
+ return;
92
+ return;
525
+ }
93
+ }
526
+
94
+
527
if (cpu->cfg.ext_zfh) {
95
if (cpu->cfg.ext_zk) {
528
cpu->cfg.ext_zfhmin = true;
96
cpu->cfg.ext_zkn = true;
529
}
97
cpu->cfg.ext_zkr = true;
530
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
98
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
531
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
99
DEFINE_PROP_BOOL("x-zvfbfmin", RISCVCPU, cfg.ext_zvfbfmin, false),
532
DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
100
DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
533
DEFINE_PROP_BOOL("Zawrs", RISCVCPU, cfg.ext_zawrs, true),
101
534
+ DEFINE_PROP_BOOL("Zfa", RISCVCPU, cfg.ext_zfa, true),
102
+ /* Vector cryptography extensions */
535
DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
103
+ DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
536
DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
104
+
537
DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false),
105
DEFINE_PROP_END_OF_LIST(),
538
diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
106
};
539
index XXXXXXX..XXXXXXX 100644
107
540
--- a/target/riscv/fpu_helper.c
541
+++ b/target/riscv/fpu_helper.c
542
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fmin_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
543
float32_minimum_number(frs1, frs2, &env->fp_status));
544
}
545
546
+uint64_t helper_fminm_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
547
+{
548
+ float32 frs1 = check_nanbox_s(env, rs1);
549
+ float32 frs2 = check_nanbox_s(env, rs2);
550
+ float32 ret = float32_min(frs1, frs2, &env->fp_status);
551
+ return nanbox_s(env, ret);
552
+}
553
+
554
uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
555
{
556
float32 frs1 = check_nanbox_s(env, rs1);
557
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fmax_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
558
float32_maximum_number(frs1, frs2, &env->fp_status));
559
}
560
561
+uint64_t helper_fmaxm_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
562
+{
563
+ float32 frs1 = check_nanbox_s(env, rs1);
564
+ float32 frs2 = check_nanbox_s(env, rs2);
565
+ float32 ret = float32_max(frs1, frs2, &env->fp_status);
566
+ return nanbox_s(env, ret);
567
+}
568
+
569
uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t rs1)
570
{
571
float32 frs1 = check_nanbox_s(env, rs1);
572
@@ -XXX,XX +XXX,XX @@ target_ulong helper_fle_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
573
return float32_le(frs1, frs2, &env->fp_status);
574
}
575
576
+target_ulong helper_fleq_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
577
+{
578
+ float32 frs1 = check_nanbox_s(env, rs1);
579
+ float32 frs2 = check_nanbox_s(env, rs2);
580
+ return float32_le_quiet(frs1, frs2, &env->fp_status);
581
+}
582
+
583
target_ulong helper_flt_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
584
{
585
float32 frs1 = check_nanbox_s(env, rs1);
586
@@ -XXX,XX +XXX,XX @@ target_ulong helper_flt_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
587
return float32_lt(frs1, frs2, &env->fp_status);
588
}
589
590
+target_ulong helper_fltq_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
591
+{
592
+ float32 frs1 = check_nanbox_s(env, rs1);
593
+ float32 frs2 = check_nanbox_s(env, rs2);
594
+ return float32_lt_quiet(frs1, frs2, &env->fp_status);
595
+}
596
+
597
target_ulong helper_feq_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
598
{
599
float32 frs1 = check_nanbox_s(env, rs1);
600
@@ -XXX,XX +XXX,XX @@ target_ulong helper_fclass_s(CPURISCVState *env, uint64_t rs1)
601
return fclass_s(frs1);
602
}
603
604
+uint64_t helper_fround_s(CPURISCVState *env, uint64_t rs1)
605
+{
606
+ float_status *fs = &env->fp_status;
607
+ uint16_t nx_old = get_float_exception_flags(fs) & float_flag_inexact;
608
+ float32 frs1 = check_nanbox_s(env, rs1);
609
+
610
+ frs1 = float32_round_to_int(frs1, fs);
611
+
612
+ /* Restore the original NX flag. */
613
+ uint16_t flags = get_float_exception_flags(fs);
614
+ flags &= ~float_flag_inexact;
615
+ flags |= nx_old;
616
+ set_float_exception_flags(flags, fs);
617
+
618
+ return nanbox_s(env, frs1);
619
+}
620
+
621
+uint64_t helper_froundnx_s(CPURISCVState *env, uint64_t rs1)
622
+{
623
+ float32 frs1 = check_nanbox_s(env, rs1);
624
+ frs1 = float32_round_to_int(frs1, &env->fp_status);
625
+ return nanbox_s(env, frs1);
626
+}
627
+
628
uint64_t helper_fadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
629
{
630
return float64_add(frs1, frs2, &env->fp_status);
631
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fmin_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
632
float64_minimum_number(frs1, frs2, &env->fp_status);
633
}
634
635
+uint64_t helper_fminm_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
636
+{
637
+ return float64_min(frs1, frs2, &env->fp_status);
638
+}
639
+
640
uint64_t helper_fmax_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
641
{
642
return env->priv_ver < PRIV_VERSION_1_11_0 ?
643
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fmax_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
644
float64_maximum_number(frs1, frs2, &env->fp_status);
645
}
646
647
+uint64_t helper_fmaxm_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
648
+{
649
+ return float64_max(frs1, frs2, &env->fp_status);
650
+}
651
+
652
uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1)
653
{
654
return nanbox_s(env, float64_to_float32(rs1, &env->fp_status));
655
@@ -XXX,XX +XXX,XX @@ target_ulong helper_fle_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
656
return float64_le(frs1, frs2, &env->fp_status);
657
}
658
659
+target_ulong helper_fleq_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
660
+{
661
+ return float64_le_quiet(frs1, frs2, &env->fp_status);
662
+}
663
+
664
target_ulong helper_flt_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
665
{
666
return float64_lt(frs1, frs2, &env->fp_status);
667
}
668
669
+target_ulong helper_fltq_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
670
+{
671
+ return float64_lt_quiet(frs1, frs2, &env->fp_status);
672
+}
673
+
674
target_ulong helper_feq_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
675
{
676
return float64_eq_quiet(frs1, frs2, &env->fp_status);
677
@@ -XXX,XX +XXX,XX @@ target_ulong helper_fcvt_w_d(CPURISCVState *env, uint64_t frs1)
678
return float64_to_int32(frs1, &env->fp_status);
679
}
680
681
+uint64_t helper_fcvtmod_w_d(CPURISCVState *env, uint64_t value)
682
+{
683
+ return float64_to_int32_modulo(value, float_round_to_zero, &env->fp_status);
684
+}
685
+
686
target_ulong helper_fcvt_wu_d(CPURISCVState *env, uint64_t frs1)
687
{
688
return (int32_t)float64_to_uint32(frs1, &env->fp_status);
689
@@ -XXX,XX +XXX,XX @@ target_ulong helper_fclass_d(uint64_t frs1)
690
return fclass_d(frs1);
691
}
692
693
+uint64_t helper_fround_d(CPURISCVState *env, uint64_t frs1)
694
+{
695
+ float_status *fs = &env->fp_status;
696
+ uint16_t nx_old = get_float_exception_flags(fs) & float_flag_inexact;
697
+
698
+ frs1 = float64_round_to_int(frs1, fs);
699
+
700
+ /* Restore the original NX flag. */
701
+ uint16_t flags = get_float_exception_flags(fs);
702
+ flags &= ~float_flag_inexact;
703
+ flags |= nx_old;
704
+ set_float_exception_flags(flags, fs);
705
+
706
+ return frs1;
707
+}
708
+
709
+uint64_t helper_froundnx_d(CPURISCVState *env, uint64_t frs1)
710
+{
711
+ return float64_round_to_int(frs1, &env->fp_status);
712
+}
713
+
714
uint64_t helper_fadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
715
{
716
float16 frs1 = check_nanbox_h(env, rs1);
717
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fmin_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
718
float16_minimum_number(frs1, frs2, &env->fp_status));
719
}
720
721
+uint64_t helper_fminm_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
722
+{
723
+ float16 frs1 = check_nanbox_h(env, rs1);
724
+ float16 frs2 = check_nanbox_h(env, rs2);
725
+ float16 ret = float16_min(frs1, frs2, &env->fp_status);
726
+ return nanbox_h(env, ret);
727
+}
728
+
729
uint64_t helper_fmax_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
730
{
731
float16 frs1 = check_nanbox_h(env, rs1);
732
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fmax_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
733
float16_maximum_number(frs1, frs2, &env->fp_status));
734
}
735
736
+uint64_t helper_fmaxm_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
737
+{
738
+ float16 frs1 = check_nanbox_h(env, rs1);
739
+ float16 frs2 = check_nanbox_h(env, rs2);
740
+ float16 ret = float16_max(frs1, frs2, &env->fp_status);
741
+ return nanbox_h(env, ret);
742
+}
743
+
744
uint64_t helper_fsqrt_h(CPURISCVState *env, uint64_t rs1)
745
{
746
float16 frs1 = check_nanbox_h(env, rs1);
747
@@ -XXX,XX +XXX,XX @@ target_ulong helper_fle_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
748
return float16_le(frs1, frs2, &env->fp_status);
749
}
750
751
+target_ulong helper_fleq_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
752
+{
753
+ float16 frs1 = check_nanbox_h(env, rs1);
754
+ float16 frs2 = check_nanbox_h(env, rs2);
755
+ return float16_le_quiet(frs1, frs2, &env->fp_status);
756
+}
757
+
758
target_ulong helper_flt_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
759
{
760
float16 frs1 = check_nanbox_h(env, rs1);
761
@@ -XXX,XX +XXX,XX @@ target_ulong helper_flt_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
762
return float16_lt(frs1, frs2, &env->fp_status);
763
}
764
765
+target_ulong helper_fltq_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
766
+{
767
+ float16 frs1 = check_nanbox_h(env, rs1);
768
+ float16 frs2 = check_nanbox_h(env, rs2);
769
+ return float16_lt_quiet(frs1, frs2, &env->fp_status);
770
+}
771
+
772
target_ulong helper_feq_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
773
{
774
float16 frs1 = check_nanbox_h(env, rs1);
775
@@ -XXX,XX +XXX,XX @@ target_ulong helper_fclass_h(CPURISCVState *env, uint64_t rs1)
776
return fclass_h(frs1);
777
}
778
779
+uint64_t helper_fround_h(CPURISCVState *env, uint64_t rs1)
780
+{
781
+ float_status *fs = &env->fp_status;
782
+ uint16_t nx_old = get_float_exception_flags(fs) & float_flag_inexact;
783
+ float16 frs1 = check_nanbox_h(env, rs1);
784
+
785
+ frs1 = float16_round_to_int(frs1, fs);
786
+
787
+ /* Restore the original NX flag. */
788
+ uint16_t flags = get_float_exception_flags(fs);
789
+ flags &= ~float_flag_inexact;
790
+ flags |= nx_old;
791
+ set_float_exception_flags(flags, fs);
792
+
793
+ return nanbox_h(env, frs1);
794
+}
795
+
796
+uint64_t helper_froundnx_h(CPURISCVState *env, uint64_t rs1)
797
+{
798
+ float16 frs1 = check_nanbox_s(env, rs1);
799
+ frs1 = float16_round_to_int(frs1, &env->fp_status);
800
+ return nanbox_h(env, frs1);
801
+}
802
+
803
target_ulong helper_fcvt_w_h(CPURISCVState *env, uint64_t rs1)
804
{
805
float16 frs1 = check_nanbox_h(env, rs1);
806
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
807
index XXXXXXX..XXXXXXX 100644
109
index XXXXXXX..XXXXXXX 100644
808
--- a/target/riscv/translate.c
110
--- a/target/riscv/translate.c
809
+++ b/target/riscv/translate.c
111
+++ b/target/riscv/translate.c
810
@@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
112
@@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
811
#include "insn_trans/trans_rvzicond.c.inc"
113
#include "insn_trans/trans_rvzfa.c.inc"
812
#include "insn_trans/trans_rvzawrs.c.inc"
813
#include "insn_trans/trans_rvzicbo.c.inc"
814
+#include "insn_trans/trans_rvzfa.c.inc"
815
#include "insn_trans/trans_rvzfh.c.inc"
114
#include "insn_trans/trans_rvzfh.c.inc"
816
#include "insn_trans/trans_rvk.c.inc"
115
#include "insn_trans/trans_rvk.c.inc"
116
+#include "insn_trans/trans_rvvk.c.inc"
817
#include "insn_trans/trans_privileged.c.inc"
117
#include "insn_trans/trans_privileged.c.inc"
818
diff --git a/tests/tcg/riscv64/test-fcvtmod.c b/tests/tcg/riscv64/test-fcvtmod.c
118
#include "insn_trans/trans_svinval.c.inc"
119
#include "insn_trans/trans_rvbf16.c.inc"
120
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
819
new file mode 100644
121
new file mode 100644
820
index XXXXXXX..XXXXXXX
122
index XXXXXXX..XXXXXXX
821
--- /dev/null
123
--- /dev/null
822
+++ b/tests/tcg/riscv64/test-fcvtmod.c
124
+++ b/target/riscv/vcrypto_helper.c
823
@@ -XXX,XX +XXX,XX @@
824
+#include <stdio.h>
825
+#include <stddef.h>
826
+#include <stdint.h>
827
+
828
+#define FFLAG_NX_SHIFT 0 /* inexact */
829
+#define FFLAG_UF_SHIFT 1 /* underflow */
830
+#define FFLAG_OF_SHIFT 2 /* overflow */
831
+#define FFLAG_DZ_SHIFT 3 /* divide by zero */
832
+#define FFLAG_NV_SHIFT 4 /* invalid operation */
833
+
834
+#define FFLAG_NV (1UL << FFLAG_NV_SHIFT)
835
+#define FFLAG_DZ (1UL << FFLAG_DZ_SHIFT)
836
+#define FFLAG_OF (1UL << FFLAG_OF_SHIFT)
837
+#define FFLAG_UF (1UL << FFLAG_UF_SHIFT)
838
+#define FFLAG_NX (1UL << FFLAG_NX_SHIFT)
839
+
840
+typedef struct fp64_fcvt_fcvtmod_testcase {
841
+ const char* name;
842
+ union {
843
+ uint64_t inp_lu;
844
+ double inp_lf;
845
+ };
846
+ uint64_t exp_fcvt;
847
+ uint8_t exp_fcvt_fflags;
848
+ uint64_t exp_fcvtmod;
849
+ uint8_t exp_fcvtmod_fflags;
850
+} fp64_fcvt_fcvtmod_testcase_t;
851
+
852
+void print_fflags(uint8_t fflags)
853
+{
854
+ int set = 0;
855
+
856
+ if (fflags == 0) {
857
+ printf("-");
858
+ return;
859
+ }
860
+
861
+ if (fflags & FFLAG_NV) {
862
+ printf("%sFFLAG_NV", set ? " | " : "");
863
+ set = 1;
864
+ }
865
+ if (fflags & FFLAG_DZ) {
866
+ printf("%sFFLAG_DZ", set ? " | " : "");
867
+ set = 1;
868
+ }
869
+ if (fflags & FFLAG_OF) {
870
+ printf("%sFFLAG_OF", set ? " | " : "");
871
+ set = 1;
872
+ }
873
+ if (fflags & FFLAG_UF) {
874
+ printf("%sFFLAG_UF", set ? " | " : "");
875
+ set = 1;
876
+ }
877
+ if (fflags & FFLAG_NX) {
878
+ printf("%sFFLAG_NX", set ? " | " : "");
879
+ set = 1;
880
+ }
881
+}
882
+
883
+/* Clear all FP flags. */
884
+static inline void clear_fflags()
885
+{
886
+ __asm__ __volatile__("fsflags zero");
887
+}
888
+
889
+/* Read all FP flags. */
890
+static inline uint8_t get_fflags()
891
+{
892
+ uint64_t v;
893
+ __asm__ __volatile__("frflags %0" : "=r"(v));
894
+ return (uint8_t)v;
895
+}
896
+
897
+/* Move input value (without conversations) into an FP register. */
898
+static inline double do_fmv_d_x(uint64_t inp)
899
+{
900
+ double fpr;
901
+ __asm__ __volatile__("fmv.d.x %0, %1" : "=f"(fpr) : "r"(inp));
902
+ return fpr;
903
+}
904
+
905
+static inline uint64_t do_fcvt_w_d(uint64_t inp, uint8_t *fflags)
906
+{
907
+ uint64_t ret;
908
+ double fpr = do_fmv_d_x(inp);
909
+
910
+ clear_fflags();
911
+
912
+ __asm__ __volatile__("fcvt.w.d %0, %1, rtz" : "=r"(ret) : "f"(fpr));
913
+
914
+ *fflags = get_fflags();
915
+
916
+ return ret;
917
+}
918
+
919
+static inline uint64_t do_fcvtmod_w_d(uint64_t inp, uint8_t *fflags)
920
+{
921
+ uint64_t ret;
922
+ double fpr = do_fmv_d_x(inp);
923
+
924
+ clear_fflags();
925
+
926
+ /* fcvtmod.w.d rd, rs1, rtz = 1100001 01000 rs1 001 rd 1010011 */
927
+ asm(".insn r 0x53, 0x1, 0x61, %0, %1, f8" : "=r"(ret) : "f"(fpr));
928
+
929
+ *fflags = get_fflags();
930
+
931
+ return ret;
932
+}
933
+
934
+static const fp64_fcvt_fcvtmod_testcase_t tests[] = {
935
+ /* Zero (exp=0, frac=0) */
936
+ { .name = "+0.0",
937
+ .inp_lf = 0x0p0,
938
+ .exp_fcvt = 0x0000000000000000,
939
+ .exp_fcvt_fflags = 0,
940
+ .exp_fcvtmod = 0x0000000000000000,
941
+ .exp_fcvtmod_fflags = 0 },
942
+ { .name = "-0.0",
943
+ .inp_lf = -0x0p0,
944
+ .exp_fcvt = 0x0000000000000000,
945
+ .exp_fcvt_fflags = 0,
946
+ .exp_fcvtmod = 0x0000000000000000,
947
+ .exp_fcvtmod_fflags = 0 },
948
+
949
+ /* Subnormal: exp=0 frac!=0 */
950
+ { .name = "Subnormal frac=1",
951
+ .inp_lu = 0x0000000000000001,
952
+ .exp_fcvt = 0x0000000000000000,
953
+ .exp_fcvt_fflags = FFLAG_NX,
954
+ .exp_fcvtmod = 0,
955
+ .exp_fcvtmod_fflags = FFLAG_NX },
956
+ { .name = "Subnormal frac=0xf..f",
957
+ .inp_lu = 0x0000ffffffffffff,
958
+ .exp_fcvt = 0x0000000000000000,
959
+ .exp_fcvt_fflags = FFLAG_NX,
960
+ .exp_fcvtmod = 0,
961
+ .exp_fcvtmod_fflags = FFLAG_NX },
962
+ { .name = "Neg subnormal frac=1",
963
+ .inp_lu = 0x0000000000000001,
964
+ .exp_fcvt = 0x0000000000000000,
965
+ .exp_fcvt_fflags = FFLAG_NX,
966
+ .exp_fcvtmod = 0,
967
+ .exp_fcvtmod_fflags = FFLAG_NX },
968
+ { .name = "Neg subnormal frac=0xf..f",
969
+ .inp_lu = 0x8000ffffffffffff,
970
+ .exp_fcvt = 0x0000000000000000,
971
+ .exp_fcvt_fflags = FFLAG_NX,
972
+ .exp_fcvtmod = 0,
973
+ .exp_fcvtmod_fflags = FFLAG_NX },
974
+
975
+ /* Infinity: exp=0x7ff, frac=0 */
976
+ { .name = "+INF",
977
+ .inp_lu = 0x7ff0000000000000,
978
+ .exp_fcvt = 0x000000007fffffff, /* int32 max */
979
+ .exp_fcvt_fflags = FFLAG_NV,
980
+ .exp_fcvtmod = 0,
981
+ .exp_fcvtmod_fflags = FFLAG_NV },
982
+ { .name = "-INF",
983
+ .inp_lu = 0xfff0000000000000,
984
+ .exp_fcvt = 0xffffffff80000000, /* int32 min */
985
+ .exp_fcvt_fflags = FFLAG_NV,
986
+ .exp_fcvtmod = 0,
987
+ .exp_fcvtmod_fflags = FFLAG_NV },
988
+
989
+ /* NaN: exp=7ff, frac!=0 */
990
+ { .name = "canonical NaN",
991
+ .inp_lu = 0x7ff8000000000000,
992
+ .exp_fcvt = 0x000000007fffffff, /* int32 max */
993
+ .exp_fcvt_fflags = FFLAG_NV,
994
+ .exp_fcvtmod = 0,
995
+ .exp_fcvtmod_fflags = FFLAG_NV },
996
+ { .name = "non-canonical NaN",
997
+ .inp_lu = 0x7ff8000000100000,
998
+ .exp_fcvt = 0x000000007fffffff, /* int32 min */
999
+ .exp_fcvt_fflags = FFLAG_NV,
1000
+ .exp_fcvtmod = 0,
1001
+ .exp_fcvtmod_fflags = FFLAG_NV },
1002
+
1003
+ /* Normal numbers: exp!=0, exp!=7ff */
1004
+ { .name = "+smallest normal value",
1005
+ .inp_lu = 0x0010000000000000,
1006
+ .exp_fcvt = 0,
1007
+ .exp_fcvt_fflags = FFLAG_NX,
1008
+ .exp_fcvtmod = 0,
1009
+ .exp_fcvtmod_fflags = FFLAG_NX },
1010
+ { .name = "-smallest normal value",
1011
+ .inp_lu = 0x8010000000000000,
1012
+ .exp_fcvt = 0,
1013
+ .exp_fcvt_fflags = FFLAG_NX,
1014
+ .exp_fcvtmod = 0,
1015
+ .exp_fcvtmod_fflags = FFLAG_NX },
1016
+
1017
+ { .name = "+0.5",
1018
+ .inp_lf = 0x1p-1,
1019
+ .exp_fcvt = 0,
1020
+ .exp_fcvt_fflags = FFLAG_NX,
1021
+ .exp_fcvtmod = 0,
1022
+ .exp_fcvtmod_fflags = FFLAG_NX },
1023
+ { .name = "-0.5",
1024
+ .inp_lf = -0x1p-1,
1025
+ .exp_fcvt = 0,
1026
+ .exp_fcvt_fflags = FFLAG_NX,
1027
+ .exp_fcvtmod = 0,
1028
+ .exp_fcvtmod_fflags = FFLAG_NX },
1029
+
1030
+ { .name = "+value just below 1.0",
1031
+ .inp_lu = 0x3fefffffffffffff,
1032
+ .exp_fcvt = 0,
1033
+ .exp_fcvt_fflags = FFLAG_NX,
1034
+ .exp_fcvtmod = 0,
1035
+ .exp_fcvtmod_fflags = FFLAG_NX },
1036
+ { .name = "-value just above -1.0",
1037
+ .inp_lu = 0xbfefffffffffffff,
1038
+ .exp_fcvt = 0,
1039
+ .exp_fcvt_fflags = FFLAG_NX,
1040
+ .exp_fcvtmod = 0,
1041
+ .exp_fcvtmod_fflags = FFLAG_NX },
1042
+
1043
+ { .name = "+1.0",
1044
+ .inp_lf = 0x1p0,
1045
+ .exp_fcvt = 0x0000000000000001,
1046
+ .exp_fcvt_fflags = 0,
1047
+ .exp_fcvtmod = 0x0000000000000001,
1048
+ .exp_fcvtmod_fflags = 0 },
1049
+ { .name = "-1.0",
1050
+ .inp_lf = -0x1p0,
1051
+ .exp_fcvt = 0xffffffffffffffff,
1052
+ .exp_fcvt_fflags = 0,
1053
+ .exp_fcvtmod = 0xffffffffffffffff,
1054
+ .exp_fcvtmod_fflags = 0 },
1055
+
1056
+ { .name = "+1.5",
1057
+ .inp_lu = 0x3ff8000000000000,
1058
+ .exp_fcvt = 1,
1059
+ .exp_fcvt_fflags = FFLAG_NX,
1060
+ .exp_fcvtmod = 1,
1061
+ .exp_fcvtmod_fflags = FFLAG_NX },
1062
+ { .name = "-1.5",
1063
+ .inp_lu = 0xbff8000000000000,
1064
+ .exp_fcvt = 0xffffffffffffffff,
1065
+ .exp_fcvt_fflags = FFLAG_NX,
1066
+ .exp_fcvtmod = 0xffffffffffffffff,
1067
+ .exp_fcvtmod_fflags = FFLAG_NX },
1068
+
1069
+ { .name = "+max int32 (2147483647)",
1070
+ .inp_lu = 0x41dfffffffc00000,
1071
+ .exp_fcvt = 0x000000007fffffff,
1072
+ .exp_fcvt_fflags = 0,
1073
+ .exp_fcvtmod = 0x000000007fffffff,
1074
+ .exp_fcvtmod_fflags = 0 },
1075
+ { .name = "+max int32 +1 (2147483648)",
1076
+ .inp_lf = 0x1p31,
1077
+ .exp_fcvt = 0x000000007fffffff,
1078
+ .exp_fcvt_fflags = FFLAG_NV,
1079
+ .exp_fcvtmod = (uint64_t)-2147483648l, /* int32 min */
1080
+ .exp_fcvtmod_fflags = FFLAG_NV },
1081
+ { .name = "+max int32 +2 (2147483649)",
1082
+ .inp_lu = 0x41e0000000200000,
1083
+ .exp_fcvt = 0x000000007fffffff,
1084
+ .exp_fcvt_fflags = FFLAG_NV,
1085
+ .exp_fcvtmod = (uint64_t)-2147483647l, /* int32 min +1 */
1086
+ .exp_fcvtmod_fflags = FFLAG_NV },
1087
+
1088
+ { .name = "-max int32 (-2147483648)",
1089
+ .inp_lf = -0x1p31,
1090
+ .exp_fcvt = 0xffffffff80000000,
1091
+ .exp_fcvt_fflags = 0,
1092
+ .exp_fcvtmod = 0xffffffff80000000,
1093
+ .exp_fcvtmod_fflags = 0 },
1094
+ { .name = "-max int32 -1 (-2147483649)",
1095
+ .inp_lf = -0x1.00000002p+31,
1096
+ .exp_fcvt = 0xffffffff80000000,
1097
+ .exp_fcvt_fflags = FFLAG_NV,
1098
+ .exp_fcvtmod = 2147483647, /* int32 max */
1099
+ .exp_fcvtmod_fflags = FFLAG_NV },
1100
+ { .name = "-max int32 -2 (-2147483650)",
1101
+ .inp_lf = -0x1.00000004p+31,
1102
+ .exp_fcvt = 0xffffffff80000000,
1103
+ .exp_fcvt_fflags = FFLAG_NV,
1104
+ .exp_fcvtmod = 2147483646, /* int32 max -1 */
1105
+ .exp_fcvtmod_fflags = FFLAG_NV },
1106
+};
1107
+
1108
+int run_fcvtmod_tests()
1109
+{
1110
+ uint64_t act_fcvt;
1111
+ uint8_t act_fcvt_fflags;
1112
+ uint64_t act_fcvtmod;
1113
+ uint8_t act_fcvtmod_fflags;
1114
+
1115
+ for (size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
1116
+ const fp64_fcvt_fcvtmod_testcase_t *t = &tests[i];
1117
+
1118
+ act_fcvt = do_fcvt_w_d(t->inp_lu, &act_fcvt_fflags);
1119
+ int fcvt_correct = act_fcvt == t->exp_fcvt &&
1120
+ act_fcvt_fflags == t->exp_fcvt_fflags;
1121
+ act_fcvtmod = do_fcvtmod_w_d(t->inp_lu, &act_fcvtmod_fflags);
1122
+ int fcvtmod_correct = act_fcvtmod == t->exp_fcvtmod &&
1123
+ act_fcvtmod_fflags == t->exp_fcvtmod_fflags;
1124
+
1125
+ if (fcvt_correct && fcvtmod_correct) {
1126
+ continue;
1127
+ }
1128
+
1129
+ printf("Test %zu (%s) failed!\n", i, t->name);
1130
+
1131
+ double fpr = do_fmv_d_x(t->inp_lu);
1132
+ printf("inp_lu: 0x%016lx == %lf\n", t->inp_lu, fpr);
1133
+ printf("inp_lf: %lf\n", t->inp_lf);
1134
+
1135
+ uint32_t sign = (t->inp_lu >> 63);
1136
+ uint32_t exp = (uint32_t)(t->inp_lu >> 52) & 0x7ff;
1137
+ uint64_t frac = t->inp_lu & 0xfffffffffffffull; /* significand */
1138
+ int true_exp = exp - 1023;
1139
+ int shift = true_exp - 52;
1140
+ uint64_t true_frac = frac | 1ull << 52;
1141
+
1142
+ printf("sign=%d, exp=0x%03x, frac=0x%012lx\n", sign, exp, frac);
1143
+ printf("true_exp=%d, shift=%d, true_frac=0x%016lx\n", true_exp, shift, true_frac);
1144
+
1145
+ if (!fcvt_correct) {
1146
+ printf("act_fcvt: 0x%016lx == %li\n", act_fcvt, act_fcvt);
1147
+ printf("exp_fcvt: 0x%016lx == %li\n", t->exp_fcvt, t->exp_fcvt);
1148
+ printf("act_fcvt_fflags: "); print_fflags(act_fcvt_fflags); printf("\n");
1149
+ printf("exp_fcvt_fflags: "); print_fflags(t->exp_fcvt_fflags); printf("\n");
1150
+ }
1151
+
1152
+ if (!fcvtmod_correct) {
1153
+ printf("act_fcvtmod: 0x%016lx == %li\n", act_fcvtmod, act_fcvtmod);
1154
+ printf("exp_fcvtmod: 0x%016lx == %li\n", t->exp_fcvtmod, t->exp_fcvtmod);
1155
+ printf("act_fcvtmod_fflags: "); print_fflags(act_fcvtmod_fflags); printf("\n");
1156
+ printf("exp_fcvtmod_fflags: "); print_fflags(t->exp_fcvtmod_fflags); printf("\n");
1157
+ }
1158
+
1159
+ return 1;
1160
+ }
1161
+
1162
+ return 0;
1163
+}
1164
+
1165
+int main()
1166
+{
1167
+ return run_fcvtmod_tests();
1168
+}
1169
diff --git a/target/riscv/insn_trans/trans_rvzfa.c.inc b/target/riscv/insn_trans/trans_rvzfa.c.inc
1170
new file mode 100644
1171
index XXXXXXX..XXXXXXX
1172
--- /dev/null
1173
+++ b/target/riscv/insn_trans/trans_rvzfa.c.inc
1174
@@ -XXX,XX +XXX,XX @@
125
@@ -XXX,XX +XXX,XX @@
1175
+/*
126
+/*
1176
+ * RISC-V translation routines for the Zfa Standard Extension.
127
+ * RISC-V Vector Crypto Extension Helpers for QEMU.
1177
+ *
128
+ *
1178
+ * Copyright (c) 2023 Christoph Müllner, christoph.muellner@vrull.eu
129
+ * Copyright (C) 2023 SiFive, Inc.
130
+ * Written by Codethink Ltd and SiFive.
1179
+ *
131
+ *
1180
+ * This program is free software; you can redistribute it and/or modify it
132
+ * This program is free software; you can redistribute it and/or modify it
1181
+ * under the terms and conditions of the GNU General Public License,
133
+ * under the terms and conditions of the GNU General Public License,
1182
+ * version 2 or later, as published by the Free Software Foundation.
134
+ * version 2 or later, as published by the Free Software Foundation.
1183
+ *
135
+ *
...
...
1188
+ *
140
+ *
1189
+ * You should have received a copy of the GNU General Public License along with
141
+ * You should have received a copy of the GNU General Public License along with
1190
+ * this program. If not, see <http://www.gnu.org/licenses/>.
142
+ * this program. If not, see <http://www.gnu.org/licenses/>.
1191
+ */
143
+ */
1192
+
144
+
1193
+#define REQUIRE_ZFA(ctx) do { \
145
+#include "qemu/osdep.h"
1194
+ if (!ctx->cfg_ptr->ext_zfa) { \
146
+#include "qemu/host-utils.h"
1195
+ return false; \
147
+#include "qemu/bitops.h"
1196
+ } \
148
+#include "cpu.h"
1197
+} while (0)
149
+#include "exec/memop.h"
1198
+
150
+#include "exec/exec-all.h"
1199
+#define REQUIRE_ZFH(ctx) do { \
151
+#include "exec/helper-proto.h"
1200
+ if (!ctx->cfg_ptr->ext_zfh) { \
152
+#include "internals.h"
1201
+ return false; \
153
+#include "vector_internals.h"
1202
+ } \
154
+
1203
+} while (0)
155
+static uint64_t clmul64(uint64_t y, uint64_t x)
1204
+
156
+{
1205
+static bool trans_fli_s(DisasContext *ctx, arg_fli_s *a)
157
+ uint64_t result = 0;
1206
+{
158
+ for (int j = 63; j >= 0; j--) {
1207
+ REQUIRE_FPU;
159
+ if ((y >> j) & 1) {
1208
+ REQUIRE_ZFA(ctx);
160
+ result ^= (x << j);
1209
+ REQUIRE_EXT(ctx, RVF);
161
+ }
1210
+
162
+ }
1211
+ /* Values below are NaN-boxed to avoid a gen_nanbox_s(). */
163
+ return result;
1212
+ static const uint64_t fli_s_table[] = {
164
+}
1213
+ 0xffffffffbf800000, /* -1.0 */
165
+
1214
+ 0xffffffff00800000, /* minimum positive normal */
166
+static uint64_t clmulh64(uint64_t y, uint64_t x)
1215
+ 0xffffffff37800000, /* 1.0 * 2^-16 */
167
+{
1216
+ 0xffffffff38000000, /* 1.0 * 2^-15 */
168
+ uint64_t result = 0;
1217
+ 0xffffffff3b800000, /* 1.0 * 2^-8 */
169
+ for (int j = 63; j >= 1; j--) {
1218
+ 0xffffffff3c000000, /* 1.0 * 2^-7 */
170
+ if ((y >> j) & 1) {
1219
+ 0xffffffff3d800000, /* 1.0 * 2^-4 */
171
+ result ^= (x >> (64 - j));
1220
+ 0xffffffff3e000000, /* 1.0 * 2^-3 */
172
+ }
1221
+ 0xffffffff3e800000, /* 0.25 */
173
+ }
1222
+ 0xffffffff3ea00000, /* 0.3125 */
174
+ return result;
1223
+ 0xffffffff3ec00000, /* 0.375 */
175
+}
1224
+ 0xffffffff3ee00000, /* 0.4375 */
176
+
1225
+ 0xffffffff3f000000, /* 0.5 */
177
+RVVCALL(OPIVV2, vclmul_vv, OP_UUU_D, H8, H8, H8, clmul64)
1226
+ 0xffffffff3f200000, /* 0.625 */
178
+GEN_VEXT_VV(vclmul_vv, 8)
1227
+ 0xffffffff3f400000, /* 0.75 */
179
+RVVCALL(OPIVX2, vclmul_vx, OP_UUU_D, H8, H8, clmul64)
1228
+ 0xffffffff3f600000, /* 0.875 */
180
+GEN_VEXT_VX(vclmul_vx, 8)
1229
+ 0xffffffff3f800000, /* 1.0 */
181
+RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64)
1230
+ 0xffffffff3fa00000, /* 1.25 */
182
+GEN_VEXT_VV(vclmulh_vv, 8)
1231
+ 0xffffffff3fc00000, /* 1.5 */
183
+RVVCALL(OPIVX2, vclmulh_vx, OP_UUU_D, H8, H8, clmulh64)
1232
+ 0xffffffff3fe00000, /* 1.75 */
184
+GEN_VEXT_VX(vclmulh_vx, 8)
1233
+ 0xffffffff40000000, /* 2.0 */
185
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
1234
+ 0xffffffff40200000, /* 2.5 */
186
new file mode 100644
1235
+ 0xffffffff40400000, /* 3 */
187
index XXXXXXX..XXXXXXX
1236
+ 0xffffffff40800000, /* 4 */
188
--- /dev/null
1237
+ 0xffffffff41000000, /* 8 */
189
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
1238
+ 0xffffffff41800000, /* 16 */
190
@@ -XXX,XX +XXX,XX @@
1239
+ 0xffffffff43000000, /* 2^7 */
191
+/*
1240
+ 0xffffffff43800000, /* 2^8 */
192
+ * RISC-V translation routines for the vector crypto extension.
1241
+ 0xffffffff47000000, /* 2^15 */
193
+ *
1242
+ 0xffffffff47800000, /* 2^16 */
194
+ * Copyright (C) 2023 SiFive, Inc.
1243
+ 0xffffffff7f800000, /* +inf */
195
+ * Written by Codethink Ltd and SiFive.
1244
+ 0xffffffff7fc00000, /* Canonical NaN */
196
+ *
1245
+ };
197
+ * This program is free software; you can redistribute it and/or modify it
1246
+
198
+ * under the terms and conditions of the GNU General Public License,
1247
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
199
+ * version 2 or later, as published by the Free Software Foundation.
1248
+ tcg_gen_movi_i64(dest, fli_s_table[a->rs1]);
200
+ *
1249
+ gen_set_fpr_hs(ctx, a->rd, dest);
201
+ * This program is distributed in the hope it will be useful, but WITHOUT
1250
+
202
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1251
+ mark_fs_dirty(ctx);
203
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
1252
+ return true;
204
+ * more details.
1253
+}
205
+ *
1254
+
206
+ * You should have received a copy of the GNU General Public License along with
1255
+static bool trans_fli_d(DisasContext *ctx, arg_fli_d *a)
207
+ * this program. If not, see <http://www.gnu.org/licenses/>.
1256
+{
208
+ */
1257
+ REQUIRE_FPU;
209
+
1258
+ REQUIRE_ZFA(ctx);
210
+/*
1259
+ REQUIRE_EXT(ctx, RVD);
211
+ * Zvbc
1260
+
212
+ */
1261
+ static const uint64_t fli_d_table[] = {
213
+
1262
+ 0xbff0000000000000, /* -1.0 */
214
+#define GEN_VV_MASKED_TRANS(NAME, CHECK) \
1263
+ 0x0010000000000000, /* minimum positive normal */
215
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
1264
+ 0x3ef0000000000000, /* 1.0 * 2^-16 */
216
+ { \
1265
+ 0x3f00000000000000, /* 1.0 * 2^-15 */
217
+ if (CHECK(s, a)) { \
1266
+ 0x3f70000000000000, /* 1.0 * 2^-8 */
218
+ return opivv_trans(a->rd, a->rs1, a->rs2, a->vm, \
1267
+ 0x3f80000000000000, /* 1.0 * 2^-7 */
219
+ gen_helper_##NAME, s); \
1268
+ 0x3fb0000000000000, /* 1.0 * 2^-4 */
220
+ } \
1269
+ 0x3fc0000000000000, /* 1.0 * 2^-3 */
221
+ return false; \
1270
+ 0x3fd0000000000000, /* 0.25 */
222
+ }
1271
+ 0x3fd4000000000000, /* 0.3125 */
223
+
1272
+ 0x3fd8000000000000, /* 0.375 */
224
+static bool vclmul_vv_check(DisasContext *s, arg_rmrr *a)
1273
+ 0x3fdc000000000000, /* 0.4375 */
225
+{
1274
+ 0x3fe0000000000000, /* 0.5 */
226
+ return opivv_check(s, a) &&
1275
+ 0x3fe4000000000000, /* 0.625 */
227
+ s->cfg_ptr->ext_zvbc == true &&
1276
+ 0x3fe8000000000000, /* 0.75 */
228
+ s->sew == MO_64;
1277
+ 0x3fec000000000000, /* 0.875 */
229
+}
1278
+ 0x3ff0000000000000, /* 1.0 */
230
+
1279
+ 0x3ff4000000000000, /* 1.25 */
231
+GEN_VV_MASKED_TRANS(vclmul_vv, vclmul_vv_check)
1280
+ 0x3ff8000000000000, /* 1.5 */
232
+GEN_VV_MASKED_TRANS(vclmulh_vv, vclmul_vv_check)
1281
+ 0x3ffc000000000000, /* 1.75 */
233
+
1282
+ 0x4000000000000000, /* 2.0 */
234
+#define GEN_VX_MASKED_TRANS(NAME, CHECK) \
1283
+ 0x4004000000000000, /* 2.5 */
235
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
1284
+ 0x4008000000000000, /* 3 */
236
+ { \
1285
+ 0x4010000000000000, /* 4 */
237
+ if (CHECK(s, a)) { \
1286
+ 0x4020000000000000, /* 8 */
238
+ return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, \
1287
+ 0x4030000000000000, /* 16 */
239
+ gen_helper_##NAME, s); \
1288
+ 0x4060000000000000, /* 2^7 */
240
+ } \
1289
+ 0x4070000000000000, /* 2^8 */
241
+ return false; \
1290
+ 0x40e0000000000000, /* 2^15 */
242
+ }
1291
+ 0x40f0000000000000, /* 2^16 */
243
+
1292
+ 0x7ff0000000000000, /* +inf */
244
+static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a)
1293
+ 0x7ff8000000000000, /* Canonical NaN */
245
+{
1294
+ };
246
+ return opivx_check(s, a) &&
1295
+
247
+ s->cfg_ptr->ext_zvbc == true &&
1296
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
248
+ s->sew == MO_64;
1297
+ tcg_gen_movi_i64(dest, fli_d_table[a->rs1]);
249
+}
1298
+ gen_set_fpr_d(ctx, a->rd, dest);
250
+
1299
+
251
+GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check)
1300
+ mark_fs_dirty(ctx);
252
+GEN_VX_MASKED_TRANS(vclmulh_vx, vclmul_vx_check)
1301
+ return true;
253
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
1302
+}
254
index XXXXXXX..XXXXXXX 100644
1303
+
255
--- a/target/riscv/meson.build
1304
+static bool trans_fli_h(DisasContext *ctx, arg_fli_h *a)
256
+++ b/target/riscv/meson.build
1305
+{
257
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(files(
1306
+ REQUIRE_FPU;
258
'translate.c',
1307
+ REQUIRE_ZFA(ctx);
259
'm128_helper.c',
1308
+ REQUIRE_ZFH(ctx);
260
'crypto_helper.c',
1309
+
261
- 'zce_helper.c'
1310
+ /* Values below are NaN-boxed to avoid a gen_nanbox_h(). */
262
+ 'zce_helper.c',
1311
+ static const uint64_t fli_h_table[] = {
263
+ 'vcrypto_helper.c'
1312
+ 0xffffffffffffbc00, /* -1.0 */
264
))
1313
+ 0xffffffffffff0400, /* minimum positive normal */
265
riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c'))
1314
+ 0xffffffffffff0100, /* 1.0 * 2^-16 */
266
1315
+ 0xffffffffffff0200, /* 1.0 * 2^-15 */
1316
+ 0xffffffffffff1c00, /* 1.0 * 2^-8 */
1317
+ 0xffffffffffff2000, /* 1.0 * 2^-7 */
1318
+ 0xffffffffffff2c00, /* 1.0 * 2^-4 */
1319
+ 0xffffffffffff3000, /* 1.0 * 2^-3 */
1320
+ 0xffffffffffff3400, /* 0.25 */
1321
+ 0xffffffffffff3500, /* 0.3125 */
1322
+ 0xffffffffffff3600, /* 0.375 */
1323
+ 0xffffffffffff3700, /* 0.4375 */
1324
+ 0xffffffffffff3800, /* 0.5 */
1325
+ 0xffffffffffff3900, /* 0.625 */
1326
+ 0xffffffffffff3a00, /* 0.75 */
1327
+ 0xffffffffffff3b00, /* 0.875 */
1328
+ 0xffffffffffff3c00, /* 1.0 */
1329
+ 0xffffffffffff3d00, /* 1.25 */
1330
+ 0xffffffffffff3e00, /* 1.5 */
1331
+ 0xffffffffffff3f00, /* 1.75 */
1332
+ 0xffffffffffff4000, /* 2.0 */
1333
+ 0xffffffffffff4100, /* 2.5 */
1334
+ 0xffffffffffff4200, /* 3 */
1335
+ 0xffffffffffff4400, /* 4 */
1336
+ 0xffffffffffff4800, /* 8 */
1337
+ 0xffffffffffff4c00, /* 16 */
1338
+ 0xffffffffffff5800, /* 2^7 */
1339
+ 0xffffffffffff5c00, /* 2^8 */
1340
+ 0xffffffffffff7800, /* 2^15 */
1341
+ 0xffffffffffff7c00, /* 2^16 */
1342
+ 0xffffffffffff7c00, /* +inf */
1343
+ 0xffffffffffff7e00, /* Canonical NaN */
1344
+ };
1345
+
1346
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
1347
+ tcg_gen_movi_i64(dest, fli_h_table[a->rs1]);
1348
+ gen_set_fpr_hs(ctx, a->rd, dest);
1349
+
1350
+ mark_fs_dirty(ctx);
1351
+ return true;
1352
+}
1353
+
1354
+static bool trans_fminm_s(DisasContext *ctx, arg_fminm_s *a)
1355
+{
1356
+ REQUIRE_FPU;
1357
+ REQUIRE_ZFA(ctx);
1358
+ REQUIRE_EXT(ctx, RVF);
1359
+
1360
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
1361
+ TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
1362
+ TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
1363
+
1364
+ gen_helper_fminm_s(dest, cpu_env, src1, src2);
1365
+ gen_set_fpr_hs(ctx, a->rd, dest);
1366
+
1367
+ mark_fs_dirty(ctx);
1368
+ return true;
1369
+}
1370
+
1371
+static bool trans_fmaxm_s(DisasContext *ctx, arg_fmaxm_s *a)
1372
+{
1373
+ REQUIRE_FPU;
1374
+ REQUIRE_ZFA(ctx);
1375
+ REQUIRE_EXT(ctx, RVF);
1376
+
1377
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
1378
+ TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
1379
+ TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
1380
+
1381
+ gen_helper_fmaxm_s(dest, cpu_env, src1, src2);
1382
+ gen_set_fpr_hs(ctx, a->rd, dest);
1383
+
1384
+ mark_fs_dirty(ctx);
1385
+ return true;
1386
+}
1387
+
1388
+static bool trans_fminm_d(DisasContext *ctx, arg_fminm_d *a)
1389
+{
1390
+ REQUIRE_FPU;
1391
+ REQUIRE_ZFA(ctx);
1392
+ REQUIRE_EXT(ctx, RVD);
1393
+
1394
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
1395
+ TCGv_i64 src1 = get_fpr_d(ctx, a->rs1);
1396
+ TCGv_i64 src2 = get_fpr_d(ctx, a->rs2);
1397
+
1398
+ gen_helper_fminm_d(dest, cpu_env, src1, src2);
1399
+ gen_set_fpr_d(ctx, a->rd, dest);
1400
+
1401
+ mark_fs_dirty(ctx);
1402
+ return true;
1403
+}
1404
+
1405
+static bool trans_fmaxm_d(DisasContext *ctx, arg_fmaxm_d *a)
1406
+{
1407
+ REQUIRE_FPU;
1408
+ REQUIRE_ZFA(ctx);
1409
+ REQUIRE_EXT(ctx, RVD);
1410
+
1411
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
1412
+ TCGv_i64 src1 = get_fpr_d(ctx, a->rs1);
1413
+ TCGv_i64 src2 = get_fpr_d(ctx, a->rs2);
1414
+
1415
+ gen_helper_fmaxm_d(dest, cpu_env, src1, src2);
1416
+ gen_set_fpr_d(ctx, a->rd, dest);
1417
+
1418
+ mark_fs_dirty(ctx);
1419
+ return true;
1420
+}
1421
+
1422
+static bool trans_fminm_h(DisasContext *ctx, arg_fminm_h *a)
1423
+{
1424
+ REQUIRE_FPU;
1425
+ REQUIRE_ZFA(ctx);
1426
+ REQUIRE_ZFH(ctx);
1427
+
1428
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
1429
+ TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
1430
+ TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
1431
+
1432
+ gen_helper_fminm_h(dest, cpu_env, src1, src2);
1433
+ gen_set_fpr_hs(ctx, a->rd, dest);
1434
+
1435
+ mark_fs_dirty(ctx);
1436
+ return true;
1437
+}
1438
+
1439
+static bool trans_fmaxm_h(DisasContext *ctx, arg_fmaxm_h *a)
1440
+{
1441
+ REQUIRE_FPU;
1442
+ REQUIRE_ZFA(ctx);
1443
+ REQUIRE_ZFH(ctx);
1444
+
1445
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
1446
+ TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
1447
+ TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
1448
+
1449
+ gen_helper_fmaxm_h(dest, cpu_env, src1, src2);
1450
+ gen_set_fpr_hs(ctx, a->rd, dest);
1451
+
1452
+ mark_fs_dirty(ctx);
1453
+ return true;
1454
+}
1455
+
1456
+static bool trans_fround_s(DisasContext *ctx, arg_fround_s *a)
1457
+{
1458
+ REQUIRE_FPU;
1459
+ REQUIRE_ZFA(ctx);
1460
+ REQUIRE_EXT(ctx, RVF);
1461
+
1462
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
1463
+ TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
1464
+
1465
+ gen_set_rm(ctx, a->rm);
1466
+ gen_helper_fround_s(dest, cpu_env, src1);
1467
+ gen_set_fpr_hs(ctx, a->rd, dest);
1468
+
1469
+ mark_fs_dirty(ctx);
1470
+ return true;
1471
+}
1472
+
1473
+static bool trans_froundnx_s(DisasContext *ctx, arg_froundnx_s *a)
1474
+{
1475
+ REQUIRE_FPU;
1476
+ REQUIRE_ZFA(ctx);
1477
+ REQUIRE_EXT(ctx, RVF);
1478
+
1479
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
1480
+ TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
1481
+
1482
+ gen_set_rm(ctx, a->rm);
1483
+ gen_helper_froundnx_s(dest, cpu_env, src1);
1484
+ gen_set_fpr_hs(ctx, a->rd, dest);
1485
+
1486
+ mark_fs_dirty(ctx);
1487
+ return true;
1488
+}
1489
+
1490
+static bool trans_fround_d(DisasContext *ctx, arg_fround_d *a)
1491
+{
1492
+ REQUIRE_FPU;
1493
+ REQUIRE_ZFA(ctx);
1494
+ REQUIRE_EXT(ctx, RVD);
1495
+
1496
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
1497
+ TCGv_i64 src1 = get_fpr_d(ctx, a->rs1);
1498
+
1499
+ gen_set_rm(ctx, a->rm);
1500
+ gen_helper_fround_d(dest, cpu_env, src1);
1501
+ gen_set_fpr_hs(ctx, a->rd, dest);
1502
+
1503
+ mark_fs_dirty(ctx);
1504
+ return true;
1505
+}
1506
+
1507
+static bool trans_froundnx_d(DisasContext *ctx, arg_froundnx_d *a)
1508
+{
1509
+ REQUIRE_FPU;
1510
+ REQUIRE_ZFA(ctx);
1511
+ REQUIRE_EXT(ctx, RVD);
1512
+
1513
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
1514
+ TCGv_i64 src1 = get_fpr_d(ctx, a->rs1);
1515
+
1516
+ gen_set_rm(ctx, a->rm);
1517
+ gen_helper_froundnx_d(dest, cpu_env, src1);
1518
+ gen_set_fpr_hs(ctx, a->rd, dest);
1519
+
1520
+ mark_fs_dirty(ctx);
1521
+ return true;
1522
+}
1523
+
1524
+static bool trans_fround_h(DisasContext *ctx, arg_fround_h *a)
1525
+{
1526
+ REQUIRE_FPU;
1527
+ REQUIRE_ZFA(ctx);
1528
+ REQUIRE_ZFH(ctx);
1529
+
1530
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
1531
+ TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
1532
+
1533
+ gen_set_rm(ctx, a->rm);
1534
+ gen_helper_fround_h(dest, cpu_env, src1);
1535
+ gen_set_fpr_hs(ctx, a->rd, dest);
1536
+
1537
+ mark_fs_dirty(ctx);
1538
+ return true;
1539
+}
1540
+
1541
+static bool trans_froundnx_h(DisasContext *ctx, arg_froundnx_h *a)
1542
+{
1543
+ REQUIRE_FPU;
1544
+ REQUIRE_ZFA(ctx);
1545
+ REQUIRE_ZFH(ctx);
1546
+
1547
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
1548
+ TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
1549
+
1550
+ gen_set_rm(ctx, a->rm);
1551
+ gen_helper_froundnx_h(dest, cpu_env, src1);
1552
+ gen_set_fpr_hs(ctx, a->rd, dest);
1553
+
1554
+ mark_fs_dirty(ctx);
1555
+ return true;
1556
+}
1557
+
1558
+bool trans_fcvtmod_w_d(DisasContext *ctx, arg_fcvtmod_w_d *a)
1559
+{
1560
+ REQUIRE_FPU;
1561
+ REQUIRE_ZFA(ctx);
1562
+ REQUIRE_EXT(ctx, RVD);
1563
+
1564
+ TCGv dst = dest_gpr(ctx, a->rd);
1565
+ TCGv_i64 src1 = get_fpr_d(ctx, a->rs1);
1566
+ TCGv_i64 t1 = tcg_temp_new_i64();
1567
+
1568
+ /* Rounding mode is RTZ. */
1569
+ gen_set_rm(ctx, RISCV_FRM_RTZ);
1570
+ gen_helper_fcvtmod_w_d(t1, cpu_env, src1);
1571
+ tcg_gen_trunc_i64_tl(dst, t1);
1572
+ gen_set_gpr(ctx, a->rd, dst);
1573
+
1574
+ return true;
1575
+}
1576
+
1577
+bool trans_fmvh_x_d(DisasContext *ctx, arg_fmvh_x_d *a)
1578
+{
1579
+ REQUIRE_FPU;
1580
+ REQUIRE_ZFA(ctx);
1581
+ REQUIRE_EXT(ctx, RVD);
1582
+ REQUIRE_32BIT(ctx);
1583
+
1584
+ TCGv dst = dest_gpr(ctx, a->rd);
1585
+ TCGv_i64 t1 = tcg_temp_new_i64();
1586
+ tcg_gen_sari_i64(t1, cpu_fpr[a->rs1], 32);
1587
+ tcg_gen_trunc_i64_tl(dst, t1);
1588
+ gen_set_gpr(ctx, a->rd, dst);
1589
+ return true;
1590
+}
1591
+
1592
+bool trans_fmvp_d_x(DisasContext *ctx, arg_fmvp_d_x *a)
1593
+{
1594
+ REQUIRE_FPU;
1595
+ REQUIRE_ZFA(ctx);
1596
+ REQUIRE_EXT(ctx, RVD);
1597
+ REQUIRE_32BIT(ctx);
1598
+
1599
+ TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
1600
+ TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
1601
+ tcg_gen_concat_tl_i64(cpu_fpr[a->rd], src1, src2);
1602
+
1603
+ mark_fs_dirty(ctx);
1604
+ return true;
1605
+}
1606
+
1607
+bool trans_fleq_s(DisasContext *ctx, arg_fleq_s *a)
1608
+{
1609
+ REQUIRE_FPU;
1610
+ REQUIRE_ZFA(ctx);
1611
+ REQUIRE_EXT(ctx, RVF);
1612
+
1613
+ TCGv dest = dest_gpr(ctx, a->rd);
1614
+ TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
1615
+ TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
1616
+
1617
+ gen_helper_fleq_s(dest, cpu_env, src1, src2);
1618
+ gen_set_gpr(ctx, a->rd, dest);
1619
+ return true;
1620
+}
1621
+
1622
+bool trans_fltq_s(DisasContext *ctx, arg_fltq_s *a)
1623
+{
1624
+ REQUIRE_FPU;
1625
+ REQUIRE_ZFA(ctx);
1626
+ REQUIRE_EXT(ctx, RVF);
1627
+
1628
+ TCGv dest = dest_gpr(ctx, a->rd);
1629
+ TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
1630
+ TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
1631
+
1632
+ gen_helper_fltq_s(dest, cpu_env, src1, src2);
1633
+ gen_set_gpr(ctx, a->rd, dest);
1634
+ return true;
1635
+}
1636
+
1637
+bool trans_fleq_d(DisasContext *ctx, arg_fleq_d *a)
1638
+{
1639
+ REQUIRE_FPU;
1640
+ REQUIRE_ZFA(ctx);
1641
+ REQUIRE_EXT(ctx, RVD);
1642
+
1643
+ TCGv dest = dest_gpr(ctx, a->rd);
1644
+ TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
1645
+ TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
1646
+
1647
+ gen_helper_fltq_s(dest, cpu_env, src1, src2);
1648
+ gen_set_gpr(ctx, a->rd, dest);
1649
+ return true;
1650
+}
1651
+
1652
+bool trans_fltq_d(DisasContext *ctx, arg_fltq_d *a)
1653
+{
1654
+ REQUIRE_FPU;
1655
+ REQUIRE_ZFA(ctx);
1656
+ REQUIRE_EXT(ctx, RVD);
1657
+
1658
+ TCGv dest = dest_gpr(ctx, a->rd);
1659
+ TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
1660
+ TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
1661
+
1662
+ gen_helper_fltq_s(dest, cpu_env, src1, src2);
1663
+ gen_set_gpr(ctx, a->rd, dest);
1664
+ return true;
1665
+}
1666
+
1667
+bool trans_fleq_h(DisasContext *ctx, arg_fleq_h *a)
1668
+{
1669
+ REQUIRE_FPU;
1670
+ REQUIRE_ZFA(ctx);
1671
+ REQUIRE_ZFH(ctx);
1672
+
1673
+ TCGv dest = dest_gpr(ctx, a->rd);
1674
+ TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
1675
+ TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
1676
+
1677
+ gen_helper_fleq_h(dest, cpu_env, src1, src2);
1678
+ gen_set_gpr(ctx, a->rd, dest);
1679
+ return true;
1680
+}
1681
+
1682
+bool trans_fltq_h(DisasContext *ctx, arg_fltq_h *a)
1683
+{
1684
+ REQUIRE_FPU;
1685
+ REQUIRE_ZFA(ctx);
1686
+ REQUIRE_ZFH(ctx);
1687
+
1688
+ TCGv dest = dest_gpr(ctx, a->rd);
1689
+ TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
1690
+ TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
1691
+
1692
+ gen_helper_fltq_h(dest, cpu_env, src1, src2);
1693
+ gen_set_gpr(ctx, a->rd, dest);
1694
+ return true;
1695
+}
1696
diff --git a/tests/tcg/riscv64/Makefile.target b/tests/tcg/riscv64/Makefile.target
1697
index XXXXXXX..XXXXXXX 100644
1698
--- a/tests/tcg/riscv64/Makefile.target
1699
+++ b/tests/tcg/riscv64/Makefile.target
1700
@@ -XXX,XX +XXX,XX @@ run-test-noc: QEMU_OPTS += -cpu rv64,c=false
1701
1702
TESTS += test-aes
1703
run-test-aes: QEMU_OPTS += -cpu rv64,zk=on
1704
+
1705
+# Test for fcvtmod
1706
+TESTS += test-fcvtmod
1707
+test-fcvtmod: CFLAGS += -march=rv64imafdc
1708
+test-fcvtmod: LDFLAGS += -static
1709
+run-test-fcvtmod: QEMU_OPTS += -cpu rv64,d=true,Zfa=true
1710
--
267
--
1711
2.40.1
268
2.41.0
1712
1713
diff view generated by jsdifflib
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
As specified in privilege spec:"When MPRV=1, load and store memory
3
Move the checks out of `do_opiv{v,x,i}_gvec{,_shift}` functions
4
addresses are treated as though the current XLEN were set to MPP’s
4
and into the corresponding macros. This enables the functions to be
5
XLEN". So the xlen for address may be different from current xlen.
5
reused in proceeding commits without check duplication.
6
6
7
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
7
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
8
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
10
Message-Id: <20230614032547.35895-2-liweiwei@iscas.ac.cn>
10
Signed-off-by: Max Chou <max.chou@sifive.com>
11
Message-ID: <20230711165917.2629866-6-max.chou@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
---
13
target/riscv/cpu.h | 49 +++++++++++++++++++++++++++++++++------
14
target/riscv/insn_trans/trans_rvv.c.inc | 28 +++++++++++--------------
14
target/riscv/cpu_helper.c | 1 +
15
1 file changed, 12 insertions(+), 16 deletions(-)
15
target/riscv/translate.c | 13 ++++++++++-
16
3 files changed, 55 insertions(+), 8 deletions(-)
17
16
18
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
17
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
18
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/cpu.h
19
--- a/target/riscv/insn_trans/trans_rvv.c.inc
21
+++ b/target/riscv/cpu.h
20
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
22
@@ -XXX,XX +XXX,XX @@ FIELD(TB_FLAGS, ITRIGGER, 22, 1)
21
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
23
/* Virtual mode enabled */
22
gen_helper_gvec_4_ptr *fn)
24
FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
23
{
25
FIELD(TB_FLAGS, PRIV, 24, 2)
24
TCGLabel *over = gen_new_label();
26
+FIELD(TB_FLAGS, AXL, 26, 2)
25
- if (!opivv_check(s, a)) {
27
26
- return false;
28
#ifdef TARGET_RISCV32
27
- }
29
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
28
30
@@ -XXX,XX +XXX,XX @@ static inline const RISCVCPUConfig *riscv_cpu_cfg(CPURISCVState *env)
29
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
31
return &env_archcpu(env)->cfg;
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]); \
32
}
39
}
33
40
34
-#if defined(TARGET_RISCV32)
41
@@ -XXX,XX +XXX,XX @@ static inline bool
35
-#define cpu_recompute_xl(env) ((void)(env), MXL_RV32)
42
do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
36
-#else
43
gen_helper_opivx *fn)
37
-static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
38
+#if !defined(CONFIG_USER_ONLY)
39
+static inline int cpu_address_mode(CPURISCVState *env)
40
+{
41
+ int mode = env->priv;
42
+
43
+ if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) {
44
+ mode = get_field(env->mstatus, MSTATUS_MPP);
45
+ }
46
+ return mode;
47
+}
48
+
49
+static inline RISCVMXL cpu_get_xl(CPURISCVState *env, target_ulong mode)
50
{
44
{
51
RISCVMXL xl = env->misa_mxl;
45
- if (!opivx_check(s, a)) {
52
-#if !defined(CONFIG_USER_ONLY)
46
- return false;
53
/*
47
- }
54
* When emulating a 32-bit-only cpu, use RV32.
48
-
55
* When emulating a 64-bit cpu, and MXL has been reduced to RV32,
49
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
56
@@ -XXX,XX +XXX,XX @@ static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
50
TCGv_i64 src1 = tcg_temp_new_i64();
57
* back to RV64 for lower privs.
51
58
*/
52
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
59
if (xl != MXL_RV32) {
53
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
60
- switch (env->priv) {
54
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
61
+ switch (mode) {
55
}; \
62
case PRV_M:
56
+ if (!opivx_check(s, a)) { \
63
break;
57
+ return false; \
64
case PRV_U:
58
+ } \
65
@@ -XXX,XX +XXX,XX @@ static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
59
return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
66
break;
67
}
68
}
69
-#endif
70
return xl;
71
}
60
}
72
#endif
61
73
62
@@ -XXX,XX +XXX,XX @@ static inline bool
74
+#if defined(TARGET_RISCV32)
63
do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn,
75
+#define cpu_recompute_xl(env) ((void)(env), MXL_RV32)
64
gen_helper_opivx *fn, imm_mode_t imm_mode)
76
+#else
77
+static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
78
+{
79
+#if !defined(CONFIG_USER_ONLY)
80
+ return cpu_get_xl(env, env->priv);
81
+#else
82
+ return env->misa_mxl;
83
+#endif
84
+}
85
+#endif
86
+
87
+#if defined(TARGET_RISCV32)
88
+#define cpu_address_xl(env) ((void)(env), MXL_RV32)
89
+#else
90
+static inline RISCVMXL cpu_address_xl(CPURISCVState *env)
91
+{
92
+#ifdef CONFIG_USER_ONLY
93
+ return env->xl;
94
+#else
95
+ int mode = cpu_address_mode(env);
96
+
97
+ return cpu_get_xl(env, mode);
98
+#endif
99
+}
100
+#endif
101
+
102
static inline int riscv_cpu_xlen(CPURISCVState *env)
103
{
65
{
104
return 16 << env->xl;
66
- if (!opivx_check(s, a)) {
105
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
67
- return false;
106
index XXXXXXX..XXXXXXX 100644
68
- }
107
--- a/target/riscv/cpu_helper.c
69
-
108
+++ b/target/riscv/cpu_helper.c
70
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
109
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
71
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
110
flags = FIELD_DP32(flags, TB_FLAGS, FS, fs);
72
extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s));
111
flags = FIELD_DP32(flags, TB_FLAGS, VS, vs);
73
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
112
flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
74
gen_helper_##OPIVX##_b, gen_helper_##OPIVX##_h, \
113
+ flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env));
75
gen_helper_##OPIVX##_w, gen_helper_##OPIVX##_d, \
114
if (env->cur_pmmask != 0) {
76
}; \
115
flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1);
77
+ if (!opivx_check(s, a)) { \
116
}
78
+ return false; \
117
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
79
+ } \
118
index XXXXXXX..XXXXXXX 100644
80
return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, \
119
--- a/target/riscv/translate.c
81
fns[s->sew], IMM_MODE); \
120
+++ b/target/riscv/translate.c
82
}
121
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
83
@@ -XXX,XX +XXX,XX @@ static inline bool
122
target_ulong priv_ver;
84
do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
123
RISCVMXL misa_mxl_max;
85
gen_helper_opivx *fn)
124
RISCVMXL xl;
125
+ RISCVMXL address_xl;
126
uint32_t misa_ext;
127
uint32_t opcode;
128
RISCVExtStatus mstatus_fs;
129
@@ -XXX,XX +XXX,XX @@ static inline bool has_ext(DisasContext *ctx, uint32_t ext)
130
#define get_xl(ctx) ((ctx)->xl)
131
#endif
132
133
+#ifdef TARGET_RISCV32
134
+#define get_address_xl(ctx) MXL_RV32
135
+#elif defined(CONFIG_USER_ONLY)
136
+#define get_address_xl(ctx) MXL_RV64
137
+#else
138
+#define get_address_xl(ctx) ((ctx)->address_xl)
139
+#endif
140
+
141
/* The word size for this machine mode. */
142
static inline int __attribute__((unused)) get_xlen(DisasContext *ctx)
143
{
86
{
144
@@ -XXX,XX +XXX,XX @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm)
87
- if (!opivx_check(s, a)) {
145
tcg_gen_addi_tl(addr, src1, imm);
88
- return false;
146
if (ctx->pm_mask_enabled) {
89
- }
147
tcg_gen_andc_tl(addr, addr, pm_mask);
90
-
148
- } else if (get_xl(ctx) == MXL_RV32) {
91
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
149
+ } else if (get_address_xl(ctx) == MXL_RV32) {
92
TCGv_i32 src1 = tcg_temp_new_i32();
150
tcg_gen_ext32u_tl(addr, addr);
93
151
}
94
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
152
if (ctx->pm_base_enabled) {
95
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
153
tcg_gen_or_tl(addr, addr, pm_base);
96
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
154
}
97
}; \
155
+
98
- \
156
return addr;
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]); \
157
}
103
}
158
104
159
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
160
ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
161
ctx->misa_mxl_max = env->misa_mxl_max;
162
ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
163
+ ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL);
164
ctx->cs = cs;
165
ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
166
ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
167
--
105
--
168
2.40.1
106
2.41.0
169
170
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Dickon Hood <dickon.hood@codethink.co.uk>
2
2
3
After changing user validation for mvendorid/marchid/mimpid to guarantee
3
Zvbb (implemented in later commit) has a widening instruction, which
4
that the value is validated on user input time, coupled with the work in
4
requires an extra check on the enabled extensions. Refactor
5
fetching KVM default values for them by using a scratch CPU, we're
5
GEN_OPIVX_WIDEN_TRANS() to take a check function to avoid reimplementing
6
certain that the values in cpu->cfg.(mvendorid|marchid|mimpid) are
6
it.
7
already good to be written back to KVM.
8
7
9
There's no need to write the values back for 'host' type CPUs since the
8
Signed-off-by: Dickon Hood <dickon.hood@codethink.co.uk>
10
values can't be changed, so let's do that just for generic CPUs.
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
12
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
13
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
12
Message-ID: <20230711165917.2629866-7-max.chou@sifive.com>
14
Acked-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-Id: <20230706101738.460804-9-dbarboza@ventanamicro.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
14
---
18
target/riscv/kvm.c | 31 +++++++++++++++++++++++++++++++
15
target/riscv/insn_trans/trans_rvv.c.inc | 52 +++++++++++--------------
19
1 file changed, 31 insertions(+)
16
1 file changed, 23 insertions(+), 29 deletions(-)
20
17
21
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
18
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
22
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/kvm.c
20
--- a/target/riscv/insn_trans/trans_rvv.c.inc
24
+++ b/target/riscv/kvm.c
21
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
25
@@ -XXX,XX +XXX,XX @@ void kvm_arch_init_irq_routing(KVMState *s)
22
@@ -XXX,XX +XXX,XX @@ static bool opivx_widen_check(DisasContext *s, arg_rmrr *a)
26
{
23
vext_check_ds(s, a->rd, a->rs2, a->vm);
27
}
24
}
28
25
29
+static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, CPUState *cs)
26
-static bool do_opivx_widen(DisasContext *s, arg_rmrr *a,
30
+{
27
- gen_helper_opivx *fn)
31
+ CPURISCVState *env = &cpu->env;
28
-{
32
+ uint64_t id;
29
- if (opivx_widen_check(s, a)) {
33
+ int ret;
30
- return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
34
+
31
- }
35
+ id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
32
- return false;
36
+ KVM_REG_RISCV_CONFIG_REG(mvendorid));
33
-}
37
+ ret = kvm_set_one_reg(cs, id, &cpu->cfg.mvendorid);
34
-
38
+ if (ret != 0) {
35
-#define GEN_OPIVX_WIDEN_TRANS(NAME) \
39
+ return ret;
36
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
40
+ }
37
-{ \
41
+
38
- static gen_helper_opivx * const fns[3] = { \
42
+ id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
39
- gen_helper_##NAME##_b, \
43
+ KVM_REG_RISCV_CONFIG_REG(marchid));
40
- gen_helper_##NAME##_h, \
44
+ ret = kvm_set_one_reg(cs, id, &cpu->cfg.marchid);
41
- gen_helper_##NAME##_w \
45
+ if (ret != 0) {
42
- }; \
46
+ return ret;
43
- return do_opivx_widen(s, a, fns[s->sew]); \
47
+ }
44
+#define GEN_OPIVX_WIDEN_TRANS(NAME, CHECK) \
48
+
45
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
49
+ id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
46
+{ \
50
+ KVM_REG_RISCV_CONFIG_REG(mimpid));
47
+ if (CHECK(s, a)) { \
51
+ ret = kvm_set_one_reg(cs, id, &cpu->cfg.mimpid);
48
+ static gen_helper_opivx * const fns[3] = { \
52
+
49
+ gen_helper_##NAME##_b, \
53
+ return ret;
50
+ gen_helper_##NAME##_h, \
54
+}
51
+ gen_helper_##NAME##_w \
55
+
52
+ }; \
56
int kvm_arch_init_vcpu(CPUState *cs)
53
+ return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s); \
57
{
54
+ } \
58
int ret = 0;
55
+ return false; \
59
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
60
}
61
env->misa_ext = isa;
62
63
+ if (!object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST)) {
64
+ ret = kvm_vcpu_set_machine_ids(cpu, cs);
65
+ }
66
+
67
return ret;
68
}
56
}
69
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)
70
--
97
--
71
2.40.1
98
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 moves the extension test functions that are used
3
Move some macros out of `vector_helper` and into `vector_internals`.
4
to gate vendor extension decoders, into cpu_cfg.h.
4
This ensures they can be used by both vector and vector-crypto helpers
5
This allows to reuse them in the disassembler.
5
(latter implemented in proceeding commits).
6
6
7
This patch does not introduce new functionality.
7
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
8
However, the patch includes a small change:
9
The parameter for the extension test functions has been changed
10
from 'DisasContext*' to 'const RISCVCPUConfig*' to keep
11
the code in cpu_cfg.h self-contained.
12
13
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
16
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
17
Message-Id: <20230612111034.3955227-3-christoph.muellner@vrull.eu>
9
Signed-off-by: Max Chou <max.chou@sifive.com>
10
Message-ID: <20230711165917.2629866-8-max.chou@sifive.com>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
12
---
20
target/riscv/cpu_cfg.h | 26 ++++++++++++++++++++++++++
13
target/riscv/vector_internals.h | 46 +++++++++++++++++++++++++++++++++
21
target/riscv/translate.c | 27 ++-------------------------
14
target/riscv/vector_helper.c | 42 ------------------------------
22
2 files changed, 28 insertions(+), 25 deletions(-)
15
2 files changed, 46 insertions(+), 42 deletions(-)
23
16
24
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
17
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
25
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu_cfg.h
19
--- a/target/riscv/vector_internals.h
27
+++ b/target/riscv/cpu_cfg.h
20
+++ b/target/riscv/vector_internals.h
28
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
21
@@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
29
};
22
/* expand macro args before macro */
30
23
#define RVVCALL(macro, ...) macro(__VA_ARGS__)
31
typedef struct RISCVCPUConfig RISCVCPUConfig;
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
32
+
30
+
33
+/* Helper functions to test for extensions. */
31
/* (TD, T1, T2, TX1, TX2) */
34
+
32
#define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
35
+static inline bool always_true_p(const RISCVCPUConfig *cfg __attribute__((__unused__)))
33
#define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t
36
+{
34
#define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t
37
+ return true;
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); \
38
+}
42
+}
39
+
43
+
40
+static inline bool has_xthead_p(const RISCVCPUConfig *cfg)
44
+#define GEN_VEXT_V(NAME, ESZ) \
41
+{
45
+void HELPER(NAME)(void *vd, void *v0, void *vs2, \
42
+ return cfg->ext_xtheadba || cfg->ext_xtheadbb ||
46
+ CPURISCVState *env, uint32_t desc) \
43
+ cfg->ext_xtheadbs || cfg->ext_xtheadcmo ||
47
+{ \
44
+ cfg->ext_xtheadcondmov ||
48
+ uint32_t vm = vext_vm(desc); \
45
+ cfg->ext_xtheadfmemidx || cfg->ext_xtheadfmv ||
49
+ uint32_t vl = env->vl; \
46
+ cfg->ext_xtheadmac || cfg->ext_xtheadmemidx ||
50
+ uint32_t total_elems = \
47
+ cfg->ext_xtheadmempair || cfg->ext_xtheadsync;
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); \
48
+}
69
+}
49
+
70
+
50
+#define MATERIALISE_EXT_PREDICATE(ext) \
71
/* operation of two vector elements */
51
+ static inline bool has_ ## ext ## _p(const RISCVCPUConfig *cfg) \
72
typedef void opivv2_fn(void *vd, void *vs1, void *vs2, int i);
52
+ { \
73
53
+ return cfg->ext_ ## ext ; \
74
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
54
+ }
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
55
+
83
+
56
+MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
84
#endif /* TARGET_RISCV_VECTOR_INTERNALS_H */
57
+
85
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
58
#endif
59
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
60
index XXXXXXX..XXXXXXX 100644
86
index XXXXXXX..XXXXXXX 100644
61
--- a/target/riscv/translate.c
87
--- a/target/riscv/vector_helper.c
62
+++ b/target/riscv/translate.c
88
+++ b/target/riscv/vector_helper.c
63
@@ -XXX,XX +XXX,XX @@ static inline bool has_ext(DisasContext *ctx, uint32_t ext)
89
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
64
return ctx->misa_ext & ext;
90
#define OP_SUS_H int16_t, uint16_t, int16_t, uint16_t, int16_t
65
}
91
#define OP_SUS_W int32_t, uint32_t, int32_t, uint32_t, int32_t
66
92
#define OP_SUS_D int64_t, uint64_t, int64_t, uint64_t, int64_t
67
-static bool always_true_p(DisasContext *ctx __attribute__((__unused__)))
93
-#define WOP_UUU_B uint16_t, uint8_t, uint8_t, uint16_t, uint16_t
68
-{
94
-#define WOP_UUU_H uint32_t, uint16_t, uint16_t, uint32_t, uint32_t
69
- return true;
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); \
70
-}
120
-}
71
-
121
-
72
-static bool has_xthead_p(DisasContext *ctx __attribute__((__unused__)))
122
-#define GEN_VEXT_V(NAME, ESZ) \
73
-{
123
-void HELPER(NAME)(void *vd, void *v0, void *vs2, \
74
- return ctx->cfg_ptr->ext_xtheadba || ctx->cfg_ptr->ext_xtheadbb ||
124
- CPURISCVState *env, uint32_t desc) \
75
- ctx->cfg_ptr->ext_xtheadbs || ctx->cfg_ptr->ext_xtheadcmo ||
125
-{ \
76
- ctx->cfg_ptr->ext_xtheadcondmov ||
126
- uint32_t vm = vext_vm(desc); \
77
- ctx->cfg_ptr->ext_xtheadfmemidx || ctx->cfg_ptr->ext_xtheadfmv ||
127
- uint32_t vl = env->vl; \
78
- ctx->cfg_ptr->ext_xtheadmac || ctx->cfg_ptr->ext_xtheadmemidx ||
128
- uint32_t total_elems = \
79
- ctx->cfg_ptr->ext_xtheadmempair || ctx->cfg_ptr->ext_xtheadsync;
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); \
80
-}
147
-}
81
-
148
-
82
-#define MATERIALISE_EXT_PREDICATE(ext) \
149
target_ulong fclass_h(uint64_t frs1)
83
- static bool has_ ## ext ## _p(DisasContext *ctx) \
150
{
84
- { \
151
float16 f = frs1;
85
- return ctx->cfg_ptr->ext_ ## ext ; \
86
- }
87
-
88
-MATERIALISE_EXT_PREDICATE(XVentanaCondOps);
89
-
90
#ifdef TARGET_RISCV32
91
#define get_xl(ctx) MXL_RV32
92
#elif defined(CONFIG_USER_ONLY)
93
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
94
* that are tested in-order until a decoder matches onto the opcode.
95
*/
96
static const struct {
97
- bool (*guard_func)(DisasContext *);
98
+ bool (*guard_func)(const RISCVCPUConfig *);
99
bool (*decode_func)(DisasContext *, uint32_t);
100
} decoders[] = {
101
{ always_true_p, decode_insn32 },
102
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
103
ctx->opcode = opcode32;
104
105
for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) {
106
- if (decoders[i].guard_func(ctx) &&
107
+ if (decoders[i].guard_func(ctx->cfg_ptr) &&
108
decoders[i].decode_func(ctx, opcode32)) {
109
return;
110
}
111
--
152
--
112
2.40.1
153
2.41.0
113
114
diff view generated by jsdifflib
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
From: Dickon Hood <dickon.hood@codethink.co.uk>
2
2
3
Add ext_zfbfmin/zvfbfmin/zvfbfwma properties.
3
This commit adds support for the Zvbb vector-crypto extension, which
4
Add require check for BF16 extensions.
4
consists of the following instructions:
5
5
6
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
* vrol.[vv,vx]
7
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
7
* vror.[vv,vx,vi]
8
* vbrev8.v
9
* vrev8.v
10
* vandn.[vv,vx]
11
* vbrev.v
12
* vclz.v
13
* vctz.v
14
* vcpop.v
15
* vwsll.[vv,vx,vi]
16
17
Translation functions are defined in
18
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
19
`target/riscv/vcrypto_helper.c`.
20
21
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
22
Co-authored-by: William Salmon <will.salmon@codethink.co.uk>
23
Co-authored-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
24
[max.chou@sifive.com: Fix imm mode of vror.vi]
25
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
26
Signed-off-by: William Salmon <will.salmon@codethink.co.uk>
27
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
28
Signed-off-by: Dickon Hood <dickon.hood@codethink.co.uk>
29
Signed-off-by: Max Chou <max.chou@sifive.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
30
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Message-Id: <20230615063302.102409-2-liweiwei@iscas.ac.cn>
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_cfg.h | 3 +++
35
target/riscv/cpu_cfg.h | 1 +
13
target/riscv/cpu.c | 20 ++++++++++++++++++++
36
target/riscv/helper.h | 62 +++++++++
14
2 files changed, 23 insertions(+)
37
target/riscv/insn32.decode | 20 +++
38
target/riscv/cpu.c | 12 ++
39
target/riscv/vcrypto_helper.c | 138 +++++++++++++++++++
40
target/riscv/insn_trans/trans_rvvk.c.inc | 164 +++++++++++++++++++++++
41
6 files changed, 397 insertions(+)
15
42
16
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
43
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
17
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/cpu_cfg.h
45
--- a/target/riscv/cpu_cfg.h
19
+++ b/target/riscv/cpu_cfg.h
46
+++ b/target/riscv/cpu_cfg.h
20
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
47
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
21
bool ext_svpbmt;
48
bool ext_zve32f;
22
bool ext_zdinx;
23
bool ext_zawrs;
24
+ bool ext_zfbfmin;
25
bool ext_zfh;
26
bool ext_zfhmin;
27
bool ext_zfinx;
28
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
29
bool ext_zve64f;
49
bool ext_zve64f;
30
bool ext_zve64d;
50
bool ext_zve64d;
51
+ bool ext_zvbb;
52
bool ext_zvbc;
31
bool ext_zmmul;
53
bool ext_zmmul;
32
+ bool ext_zvfbfmin;
54
bool ext_zvfbfmin;
33
+ bool ext_zvfbfwma;
55
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
34
bool ext_zvfh;
56
index XXXXXXX..XXXXXXX 100644
35
bool ext_zvfhmin;
57
--- a/target/riscv/helper.h
36
bool ext_smaia;
58
+++ b/target/riscv/helper.h
59
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
60
DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
61
DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
62
DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
63
+
64
+DEF_HELPER_6(vror_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
65
+DEF_HELPER_6(vror_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
66
+DEF_HELPER_6(vror_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
67
+DEF_HELPER_6(vror_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
68
+
69
+DEF_HELPER_6(vror_vx_b, void, ptr, ptr, tl, ptr, env, i32)
70
+DEF_HELPER_6(vror_vx_h, void, ptr, ptr, tl, ptr, env, i32)
71
+DEF_HELPER_6(vror_vx_w, void, ptr, ptr, tl, ptr, env, i32)
72
+DEF_HELPER_6(vror_vx_d, void, ptr, ptr, tl, ptr, env, i32)
73
+
74
+DEF_HELPER_6(vrol_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
75
+DEF_HELPER_6(vrol_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
76
+DEF_HELPER_6(vrol_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
77
+DEF_HELPER_6(vrol_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
78
+
79
+DEF_HELPER_6(vrol_vx_b, void, ptr, ptr, tl, ptr, env, i32)
80
+DEF_HELPER_6(vrol_vx_h, void, ptr, ptr, tl, ptr, env, i32)
81
+DEF_HELPER_6(vrol_vx_w, void, ptr, ptr, tl, ptr, env, i32)
82
+DEF_HELPER_6(vrol_vx_d, void, ptr, ptr, tl, ptr, env, i32)
83
+
84
+DEF_HELPER_5(vrev8_v_b, void, ptr, ptr, ptr, env, i32)
85
+DEF_HELPER_5(vrev8_v_h, void, ptr, ptr, ptr, env, i32)
86
+DEF_HELPER_5(vrev8_v_w, void, ptr, ptr, ptr, env, i32)
87
+DEF_HELPER_5(vrev8_v_d, void, ptr, ptr, ptr, env, i32)
88
+DEF_HELPER_5(vbrev8_v_b, void, ptr, ptr, ptr, env, i32)
89
+DEF_HELPER_5(vbrev8_v_h, void, ptr, ptr, ptr, env, i32)
90
+DEF_HELPER_5(vbrev8_v_w, void, ptr, ptr, ptr, env, i32)
91
+DEF_HELPER_5(vbrev8_v_d, void, ptr, ptr, ptr, env, i32)
92
+DEF_HELPER_5(vbrev_v_b, void, ptr, ptr, ptr, env, i32)
93
+DEF_HELPER_5(vbrev_v_h, void, ptr, ptr, ptr, env, i32)
94
+DEF_HELPER_5(vbrev_v_w, void, ptr, ptr, ptr, env, i32)
95
+DEF_HELPER_5(vbrev_v_d, void, ptr, ptr, ptr, env, i32)
96
+
97
+DEF_HELPER_5(vclz_v_b, void, ptr, ptr, ptr, env, i32)
98
+DEF_HELPER_5(vclz_v_h, void, ptr, ptr, ptr, env, i32)
99
+DEF_HELPER_5(vclz_v_w, void, ptr, ptr, ptr, env, i32)
100
+DEF_HELPER_5(vclz_v_d, void, ptr, ptr, ptr, env, i32)
101
+DEF_HELPER_5(vctz_v_b, void, ptr, ptr, ptr, env, i32)
102
+DEF_HELPER_5(vctz_v_h, void, ptr, ptr, ptr, env, i32)
103
+DEF_HELPER_5(vctz_v_w, void, ptr, ptr, ptr, env, i32)
104
+DEF_HELPER_5(vctz_v_d, void, ptr, ptr, ptr, env, i32)
105
+DEF_HELPER_5(vcpop_v_b, void, ptr, ptr, ptr, env, i32)
106
+DEF_HELPER_5(vcpop_v_h, void, ptr, ptr, ptr, env, i32)
107
+DEF_HELPER_5(vcpop_v_w, void, ptr, ptr, ptr, env, i32)
108
+DEF_HELPER_5(vcpop_v_d, void, ptr, ptr, ptr, env, i32)
109
+
110
+DEF_HELPER_6(vwsll_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
111
+DEF_HELPER_6(vwsll_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
112
+DEF_HELPER_6(vwsll_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
113
+DEF_HELPER_6(vwsll_vx_b, void, ptr, ptr, tl, ptr, env, i32)
114
+DEF_HELPER_6(vwsll_vx_h, void, ptr, ptr, tl, ptr, env, i32)
115
+DEF_HELPER_6(vwsll_vx_w, void, ptr, ptr, tl, ptr, env, i32)
116
+
117
+DEF_HELPER_6(vandn_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
118
+DEF_HELPER_6(vandn_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
119
+DEF_HELPER_6(vandn_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
120
+DEF_HELPER_6(vandn_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
121
+DEF_HELPER_6(vandn_vx_b, void, ptr, ptr, tl, ptr, env, i32)
122
+DEF_HELPER_6(vandn_vx_h, void, ptr, ptr, tl, ptr, env, i32)
123
+DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, i32)
124
+DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32)
125
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
126
index XXXXXXX..XXXXXXX 100644
127
--- a/target/riscv/insn32.decode
128
+++ b/target/riscv/insn32.decode
129
@@ -XXX,XX +XXX,XX @@
130
%imm_u 12:s20 !function=ex_shift_12
131
%imm_bs 30:2 !function=ex_shift_3
132
%imm_rnum 20:4
133
+%imm_z6 26:1 15:5
134
135
# Argument sets:
136
&empty
137
@@ -XXX,XX +XXX,XX @@
138
@r_vm ...... vm:1 ..... ..... ... ..... ....... &rmrr %rs2 %rs1 %rd
139
@r_vm_1 ...... . ..... ..... ... ..... ....... &rmrr vm=1 %rs2 %rs1 %rd
140
@r_vm_0 ...... . ..... ..... ... ..... ....... &rmrr vm=0 %rs2 %rs1 %rd
141
+@r2_zimm6 ..... . vm:1 ..... ..... ... ..... ....... &rmrr %rs2 rs1=%imm_z6 %rd
142
@r2_zimm11 . zimm:11 ..... ... ..... ....... %rs1 %rd
143
@r2_zimm10 .. zimm:10 ..... ... ..... ....... %rs1 %rd
144
@r2_s ....... ..... ..... ... ..... ....... %rs2 %rs1
145
@@ -XXX,XX +XXX,XX @@ vclmul_vv 001100 . ..... ..... 010 ..... 1010111 @r_vm
146
vclmul_vx 001100 . ..... ..... 110 ..... 1010111 @r_vm
147
vclmulh_vv 001101 . ..... ..... 010 ..... 1010111 @r_vm
148
vclmulh_vx 001101 . ..... ..... 110 ..... 1010111 @r_vm
149
+
150
+# *** Zvbb vector crypto extension ***
151
+vrol_vv 010101 . ..... ..... 000 ..... 1010111 @r_vm
152
+vrol_vx 010101 . ..... ..... 100 ..... 1010111 @r_vm
153
+vror_vv 010100 . ..... ..... 000 ..... 1010111 @r_vm
154
+vror_vx 010100 . ..... ..... 100 ..... 1010111 @r_vm
155
+vror_vi 01010. . ..... ..... 011 ..... 1010111 @r2_zimm6
156
+vbrev8_v 010010 . ..... 01000 010 ..... 1010111 @r2_vm
157
+vrev8_v 010010 . ..... 01001 010 ..... 1010111 @r2_vm
158
+vandn_vv 000001 . ..... ..... 000 ..... 1010111 @r_vm
159
+vandn_vx 000001 . ..... ..... 100 ..... 1010111 @r_vm
160
+vbrev_v 010010 . ..... 01010 010 ..... 1010111 @r2_vm
161
+vclz_v 010010 . ..... 01100 010 ..... 1010111 @r2_vm
162
+vctz_v 010010 . ..... 01101 010 ..... 1010111 @r2_vm
163
+vcpop_v 010010 . ..... 01110 010 ..... 1010111 @r2_vm
164
+vwsll_vv 110101 . ..... ..... 000 ..... 1010111 @r_vm
165
+vwsll_vx 110101 . ..... ..... 100 ..... 1010111 @r_vm
166
+vwsll_vi 110101 . ..... ..... 011 ..... 1010111 @r_vm
37
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
38
index XXXXXXX..XXXXXXX 100644
168
index XXXXXXX..XXXXXXX 100644
39
--- a/target/riscv/cpu.c
169
--- a/target/riscv/cpu.c
40
+++ b/target/riscv/cpu.c
170
+++ b/target/riscv/cpu.c
171
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
172
ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
173
ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
174
ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
175
+ ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
176
ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
177
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
178
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
41
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
179
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
42
return;
180
return;
43
}
181
}
44
182
45
+ if (cpu->cfg.ext_zfbfmin && !riscv_has_ext(env, RVF)) {
183
+ /*
46
+ error_setg(errp, "Zfbfmin extension depends on F extension");
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");
47
+ return;
190
+ return;
48
+ }
191
+ }
49
+
192
+
50
if (riscv_has_ext(env, RVD) && !riscv_has_ext(env, RVF)) {
193
if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
51
error_setg(errp, "D extension requires F extension");
194
error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
52
return;
195
return;
53
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
196
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
54
return;
197
DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
55
}
198
56
199
/* Vector cryptography extensions */
57
+ if (cpu->cfg.ext_zvfbfmin && !cpu->cfg.ext_zfbfmin) {
200
+ DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
58
+ error_setg(errp, "Zvfbfmin extension depends on Zfbfmin extension");
201
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
59
+ return;
202
60
+ }
203
DEFINE_PROP_END_OF_LIST(),
61
+
204
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
62
+ if (cpu->cfg.ext_zvfbfmin && !cpu->cfg.ext_zve32f) {
205
index XXXXXXX..XXXXXXX 100644
63
+ error_setg(errp, "Zvfbfmin extension depends on Zve32f extension");
206
--- a/target/riscv/vcrypto_helper.c
64
+ return;
207
+++ b/target/riscv/vcrypto_helper.c
65
+ }
208
@@ -XXX,XX +XXX,XX @@
66
+
209
#include "qemu/osdep.h"
67
+ if (cpu->cfg.ext_zvfbfwma && !cpu->cfg.ext_zvfbfmin) {
210
#include "qemu/host-utils.h"
68
+ error_setg(errp, "Zvfbfwma extension depends on Zvfbfmin extension");
211
#include "qemu/bitops.h"
69
+ return;
212
+#include "qemu/bswap.h"
70
+ }
213
#include "cpu.h"
71
+
214
#include "exec/memop.h"
72
/* Set the ISA extensions, checks should have happened above */
215
#include "exec/exec-all.h"
73
if (cpu->cfg.ext_zhinx) {
216
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64)
74
cpu->cfg.ext_zhinxmin = true;
217
GEN_VEXT_VV(vclmulh_vv, 8)
218
RVVCALL(OPIVX2, vclmulh_vx, OP_UUU_D, H8, H8, clmulh64)
219
GEN_VEXT_VX(vclmulh_vx, 8)
220
+
221
+RVVCALL(OPIVV2, vror_vv_b, OP_UUU_B, H1, H1, H1, ror8)
222
+RVVCALL(OPIVV2, vror_vv_h, OP_UUU_H, H2, H2, H2, ror16)
223
+RVVCALL(OPIVV2, vror_vv_w, OP_UUU_W, H4, H4, H4, ror32)
224
+RVVCALL(OPIVV2, vror_vv_d, OP_UUU_D, H8, H8, H8, ror64)
225
+GEN_VEXT_VV(vror_vv_b, 1)
226
+GEN_VEXT_VV(vror_vv_h, 2)
227
+GEN_VEXT_VV(vror_vv_w, 4)
228
+GEN_VEXT_VV(vror_vv_d, 8)
229
+
230
+RVVCALL(OPIVX2, vror_vx_b, OP_UUU_B, H1, H1, ror8)
231
+RVVCALL(OPIVX2, vror_vx_h, OP_UUU_H, H2, H2, ror16)
232
+RVVCALL(OPIVX2, vror_vx_w, OP_UUU_W, H4, H4, ror32)
233
+RVVCALL(OPIVX2, vror_vx_d, OP_UUU_D, H8, H8, ror64)
234
+GEN_VEXT_VX(vror_vx_b, 1)
235
+GEN_VEXT_VX(vror_vx_h, 2)
236
+GEN_VEXT_VX(vror_vx_w, 4)
237
+GEN_VEXT_VX(vror_vx_d, 8)
238
+
239
+RVVCALL(OPIVV2, vrol_vv_b, OP_UUU_B, H1, H1, H1, rol8)
240
+RVVCALL(OPIVV2, vrol_vv_h, OP_UUU_H, H2, H2, H2, rol16)
241
+RVVCALL(OPIVV2, vrol_vv_w, OP_UUU_W, H4, H4, H4, rol32)
242
+RVVCALL(OPIVV2, vrol_vv_d, OP_UUU_D, H8, H8, H8, rol64)
243
+GEN_VEXT_VV(vrol_vv_b, 1)
244
+GEN_VEXT_VV(vrol_vv_h, 2)
245
+GEN_VEXT_VV(vrol_vv_w, 4)
246
+GEN_VEXT_VV(vrol_vv_d, 8)
247
+
248
+RVVCALL(OPIVX2, vrol_vx_b, OP_UUU_B, H1, H1, rol8)
249
+RVVCALL(OPIVX2, vrol_vx_h, OP_UUU_H, H2, H2, rol16)
250
+RVVCALL(OPIVX2, vrol_vx_w, OP_UUU_W, H4, H4, rol32)
251
+RVVCALL(OPIVX2, vrol_vx_d, OP_UUU_D, H8, H8, rol64)
252
+GEN_VEXT_VX(vrol_vx_b, 1)
253
+GEN_VEXT_VX(vrol_vx_h, 2)
254
+GEN_VEXT_VX(vrol_vx_w, 4)
255
+GEN_VEXT_VX(vrol_vx_d, 8)
256
+
257
+static uint64_t brev8(uint64_t val)
258
+{
259
+ val = ((val & 0x5555555555555555ull) << 1) |
260
+ ((val & 0xAAAAAAAAAAAAAAAAull) >> 1);
261
+ val = ((val & 0x3333333333333333ull) << 2) |
262
+ ((val & 0xCCCCCCCCCCCCCCCCull) >> 2);
263
+ val = ((val & 0x0F0F0F0F0F0F0F0Full) << 4) |
264
+ ((val & 0xF0F0F0F0F0F0F0F0ull) >> 4);
265
+
266
+ return val;
267
+}
268
+
269
+RVVCALL(OPIVV1, vbrev8_v_b, OP_UU_B, H1, H1, brev8)
270
+RVVCALL(OPIVV1, vbrev8_v_h, OP_UU_H, H2, H2, brev8)
271
+RVVCALL(OPIVV1, vbrev8_v_w, OP_UU_W, H4, H4, brev8)
272
+RVVCALL(OPIVV1, vbrev8_v_d, OP_UU_D, H8, H8, brev8)
273
+GEN_VEXT_V(vbrev8_v_b, 1)
274
+GEN_VEXT_V(vbrev8_v_h, 2)
275
+GEN_VEXT_V(vbrev8_v_w, 4)
276
+GEN_VEXT_V(vbrev8_v_d, 8)
277
+
278
+#define DO_IDENTITY(a) (a)
279
+RVVCALL(OPIVV1, vrev8_v_b, OP_UU_B, H1, H1, DO_IDENTITY)
280
+RVVCALL(OPIVV1, vrev8_v_h, OP_UU_H, H2, H2, bswap16)
281
+RVVCALL(OPIVV1, vrev8_v_w, OP_UU_W, H4, H4, bswap32)
282
+RVVCALL(OPIVV1, vrev8_v_d, OP_UU_D, H8, H8, bswap64)
283
+GEN_VEXT_V(vrev8_v_b, 1)
284
+GEN_VEXT_V(vrev8_v_h, 2)
285
+GEN_VEXT_V(vrev8_v_w, 4)
286
+GEN_VEXT_V(vrev8_v_d, 8)
287
+
288
+#define DO_ANDN(a, b) ((a) & ~(b))
289
+RVVCALL(OPIVV2, vandn_vv_b, OP_UUU_B, H1, H1, H1, DO_ANDN)
290
+RVVCALL(OPIVV2, vandn_vv_h, OP_UUU_H, H2, H2, H2, DO_ANDN)
291
+RVVCALL(OPIVV2, vandn_vv_w, OP_UUU_W, H4, H4, H4, DO_ANDN)
292
+RVVCALL(OPIVV2, vandn_vv_d, OP_UUU_D, H8, H8, H8, DO_ANDN)
293
+GEN_VEXT_VV(vandn_vv_b, 1)
294
+GEN_VEXT_VV(vandn_vv_h, 2)
295
+GEN_VEXT_VV(vandn_vv_w, 4)
296
+GEN_VEXT_VV(vandn_vv_d, 8)
297
+
298
+RVVCALL(OPIVX2, vandn_vx_b, OP_UUU_B, H1, H1, DO_ANDN)
299
+RVVCALL(OPIVX2, vandn_vx_h, OP_UUU_H, H2, H2, DO_ANDN)
300
+RVVCALL(OPIVX2, vandn_vx_w, OP_UUU_W, H4, H4, DO_ANDN)
301
+RVVCALL(OPIVX2, vandn_vx_d, OP_UUU_D, H8, H8, DO_ANDN)
302
+GEN_VEXT_VX(vandn_vx_b, 1)
303
+GEN_VEXT_VX(vandn_vx_h, 2)
304
+GEN_VEXT_VX(vandn_vx_w, 4)
305
+GEN_VEXT_VX(vandn_vx_d, 8)
306
+
307
+RVVCALL(OPIVV1, vbrev_v_b, OP_UU_B, H1, H1, revbit8)
308
+RVVCALL(OPIVV1, vbrev_v_h, OP_UU_H, H2, H2, revbit16)
309
+RVVCALL(OPIVV1, vbrev_v_w, OP_UU_W, H4, H4, revbit32)
310
+RVVCALL(OPIVV1, vbrev_v_d, OP_UU_D, H8, H8, revbit64)
311
+GEN_VEXT_V(vbrev_v_b, 1)
312
+GEN_VEXT_V(vbrev_v_h, 2)
313
+GEN_VEXT_V(vbrev_v_w, 4)
314
+GEN_VEXT_V(vbrev_v_d, 8)
315
+
316
+RVVCALL(OPIVV1, vclz_v_b, OP_UU_B, H1, H1, clz8)
317
+RVVCALL(OPIVV1, vclz_v_h, OP_UU_H, H2, H2, clz16)
318
+RVVCALL(OPIVV1, vclz_v_w, OP_UU_W, H4, H4, clz32)
319
+RVVCALL(OPIVV1, vclz_v_d, OP_UU_D, H8, H8, clz64)
320
+GEN_VEXT_V(vclz_v_b, 1)
321
+GEN_VEXT_V(vclz_v_h, 2)
322
+GEN_VEXT_V(vclz_v_w, 4)
323
+GEN_VEXT_V(vclz_v_d, 8)
324
+
325
+RVVCALL(OPIVV1, vctz_v_b, OP_UU_B, H1, H1, ctz8)
326
+RVVCALL(OPIVV1, vctz_v_h, OP_UU_H, H2, H2, ctz16)
327
+RVVCALL(OPIVV1, vctz_v_w, OP_UU_W, H4, H4, ctz32)
328
+RVVCALL(OPIVV1, vctz_v_d, OP_UU_D, H8, H8, ctz64)
329
+GEN_VEXT_V(vctz_v_b, 1)
330
+GEN_VEXT_V(vctz_v_h, 2)
331
+GEN_VEXT_V(vctz_v_w, 4)
332
+GEN_VEXT_V(vctz_v_d, 8)
333
+
334
+RVVCALL(OPIVV1, vcpop_v_b, OP_UU_B, H1, H1, ctpop8)
335
+RVVCALL(OPIVV1, vcpop_v_h, OP_UU_H, H2, H2, ctpop16)
336
+RVVCALL(OPIVV1, vcpop_v_w, OP_UU_W, H4, H4, ctpop32)
337
+RVVCALL(OPIVV1, vcpop_v_d, OP_UU_D, H8, H8, ctpop64)
338
+GEN_VEXT_V(vcpop_v_b, 1)
339
+GEN_VEXT_V(vcpop_v_h, 2)
340
+GEN_VEXT_V(vcpop_v_w, 4)
341
+GEN_VEXT_V(vcpop_v_d, 8)
342
+
343
+#define DO_SLL(N, M) (N << (M & (sizeof(N) * 8 - 1)))
344
+RVVCALL(OPIVV2, vwsll_vv_b, WOP_UUU_B, H2, H1, H1, DO_SLL)
345
+RVVCALL(OPIVV2, vwsll_vv_h, WOP_UUU_H, H4, H2, H2, DO_SLL)
346
+RVVCALL(OPIVV2, vwsll_vv_w, WOP_UUU_W, H8, H4, H4, DO_SLL)
347
+GEN_VEXT_VV(vwsll_vv_b, 2)
348
+GEN_VEXT_VV(vwsll_vv_h, 4)
349
+GEN_VEXT_VV(vwsll_vv_w, 8)
350
+
351
+RVVCALL(OPIVX2, vwsll_vx_b, WOP_UUU_B, H2, H1, DO_SLL)
352
+RVVCALL(OPIVX2, vwsll_vx_h, WOP_UUU_H, H4, H2, DO_SLL)
353
+RVVCALL(OPIVX2, vwsll_vx_w, WOP_UUU_W, H8, H4, DO_SLL)
354
+GEN_VEXT_VX(vwsll_vx_b, 2)
355
+GEN_VEXT_VX(vwsll_vx_h, 4)
356
+GEN_VEXT_VX(vwsll_vx_w, 8)
357
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
358
index XXXXXXX..XXXXXXX 100644
359
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
360
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
361
@@ -XXX,XX +XXX,XX @@ static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a)
362
363
GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check)
364
GEN_VX_MASKED_TRANS(vclmulh_vx, vclmul_vx_check)
365
+
366
+/*
367
+ * Zvbb
368
+ */
369
+
370
+#define GEN_OPIVI_GVEC_TRANS_CHECK(NAME, IMM_MODE, OPIVX, SUF, CHECK) \
371
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
372
+ { \
373
+ if (CHECK(s, a)) { \
374
+ static gen_helper_opivx *const fns[4] = { \
375
+ gen_helper_##OPIVX##_b, \
376
+ gen_helper_##OPIVX##_h, \
377
+ gen_helper_##OPIVX##_w, \
378
+ gen_helper_##OPIVX##_d, \
379
+ }; \
380
+ return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew], \
381
+ IMM_MODE); \
382
+ } \
383
+ return false; \
384
+ }
385
+
386
+#define GEN_OPIVV_GVEC_TRANS_CHECK(NAME, SUF, CHECK) \
387
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
388
+ { \
389
+ if (CHECK(s, a)) { \
390
+ static gen_helper_gvec_4_ptr *const fns[4] = { \
391
+ gen_helper_##NAME##_b, \
392
+ gen_helper_##NAME##_h, \
393
+ gen_helper_##NAME##_w, \
394
+ gen_helper_##NAME##_d, \
395
+ }; \
396
+ return do_opivv_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
397
+ } \
398
+ return false; \
399
+ }
400
+
401
+#define GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(NAME, SUF, CHECK) \
402
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
403
+ { \
404
+ if (CHECK(s, a)) { \
405
+ static gen_helper_opivx *const fns[4] = { \
406
+ gen_helper_##NAME##_b, \
407
+ gen_helper_##NAME##_h, \
408
+ gen_helper_##NAME##_w, \
409
+ gen_helper_##NAME##_d, \
410
+ }; \
411
+ return do_opivx_gvec_shift(s, a, tcg_gen_gvec_##SUF, \
412
+ fns[s->sew]); \
413
+ } \
414
+ return false; \
415
+ }
416
+
417
+static bool zvbb_vv_check(DisasContext *s, arg_rmrr *a)
418
+{
419
+ return opivv_check(s, a) && s->cfg_ptr->ext_zvbb == true;
420
+}
421
+
422
+static bool zvbb_vx_check(DisasContext *s, arg_rmrr *a)
423
+{
424
+ return opivx_check(s, a) && s->cfg_ptr->ext_zvbb == true;
425
+}
426
+
427
+/* vrol.v[vx] */
428
+GEN_OPIVV_GVEC_TRANS_CHECK(vrol_vv, rotlv, zvbb_vv_check)
429
+GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vrol_vx, rotls, zvbb_vx_check)
430
+
431
+/* vror.v[vxi] */
432
+GEN_OPIVV_GVEC_TRANS_CHECK(vror_vv, rotrv, zvbb_vv_check)
433
+GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(vror_vx, rotrs, zvbb_vx_check)
434
+GEN_OPIVI_GVEC_TRANS_CHECK(vror_vi, IMM_TRUNC_SEW, vror_vx, rotri, zvbb_vx_check)
435
+
436
+#define GEN_OPIVX_GVEC_TRANS_CHECK(NAME, SUF, CHECK) \
437
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
438
+ { \
439
+ if (CHECK(s, a)) { \
440
+ static gen_helper_opivx *const fns[4] = { \
441
+ gen_helper_##NAME##_b, \
442
+ gen_helper_##NAME##_h, \
443
+ gen_helper_##NAME##_w, \
444
+ gen_helper_##NAME##_d, \
445
+ }; \
446
+ return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
447
+ } \
448
+ return false; \
449
+ }
450
+
451
+/* vandn.v[vx] */
452
+GEN_OPIVV_GVEC_TRANS_CHECK(vandn_vv, andc, zvbb_vv_check)
453
+GEN_OPIVX_GVEC_TRANS_CHECK(vandn_vx, andcs, zvbb_vx_check)
454
+
455
+#define GEN_OPIV_TRANS(NAME, CHECK) \
456
+ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
457
+ { \
458
+ if (CHECK(s, a)) { \
459
+ uint32_t data = 0; \
460
+ static gen_helper_gvec_3_ptr *const fns[4] = { \
461
+ gen_helper_##NAME##_b, \
462
+ gen_helper_##NAME##_h, \
463
+ gen_helper_##NAME##_w, \
464
+ gen_helper_##NAME##_d, \
465
+ }; \
466
+ TCGLabel *over = gen_new_label(); \
467
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
468
+ \
469
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
470
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
471
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
472
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
473
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
474
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
475
+ vreg_ofs(s, a->rs2), cpu_env, \
476
+ s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, \
477
+ data, fns[s->sew]); \
478
+ mark_vs_dirty(s); \
479
+ gen_set_label(over); \
480
+ return true; \
481
+ } \
482
+ return false; \
483
+ }
484
+
485
+static bool zvbb_opiv_check(DisasContext *s, arg_rmr *a)
486
+{
487
+ return s->cfg_ptr->ext_zvbb == true &&
488
+ require_rvv(s) &&
489
+ vext_check_isa_ill(s) &&
490
+ vext_check_ss(s, a->rd, a->rs2, a->vm);
491
+}
492
+
493
+GEN_OPIV_TRANS(vbrev8_v, zvbb_opiv_check)
494
+GEN_OPIV_TRANS(vrev8_v, zvbb_opiv_check)
495
+GEN_OPIV_TRANS(vbrev_v, zvbb_opiv_check)
496
+GEN_OPIV_TRANS(vclz_v, zvbb_opiv_check)
497
+GEN_OPIV_TRANS(vctz_v, zvbb_opiv_check)
498
+GEN_OPIV_TRANS(vcpop_v, zvbb_opiv_check)
499
+
500
+static bool vwsll_vv_check(DisasContext *s, arg_rmrr *a)
501
+{
502
+ return s->cfg_ptr->ext_zvbb && opivv_widen_check(s, a);
503
+}
504
+
505
+static bool vwsll_vx_check(DisasContext *s, arg_rmrr *a)
506
+{
507
+ return s->cfg_ptr->ext_zvbb && opivx_widen_check(s, a);
508
+}
509
+
510
+/* OPIVI without GVEC IR */
511
+#define GEN_OPIVI_WIDEN_TRANS(NAME, IMM_MODE, OPIVX, CHECK) \
512
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
513
+ { \
514
+ if (CHECK(s, a)) { \
515
+ static gen_helper_opivx *const fns[3] = { \
516
+ gen_helper_##OPIVX##_b, \
517
+ gen_helper_##OPIVX##_h, \
518
+ gen_helper_##OPIVX##_w, \
519
+ }; \
520
+ return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s, \
521
+ IMM_MODE); \
522
+ } \
523
+ return false; \
524
+ }
525
+
526
+GEN_OPIVV_WIDEN_TRANS(vwsll_vv, vwsll_vv_check)
527
+GEN_OPIVX_WIDEN_TRANS(vwsll_vx, vwsll_vx_check)
528
+GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
75
--
529
--
76
2.40.1
530
2.41.0
diff view generated by jsdifflib
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
3
This commit adds support for the Zvkned vector-crypto extension, which
4
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
4
consists of the following instructions:
5
6
* vaesef.[vv,vs]
7
* vaesdf.[vv,vs]
8
* vaesdm.[vv,vs]
9
* vaesz.vs
10
* vaesem.[vv,vs]
11
* vaeskf1.vi
12
* vaeskf2.vi
13
14
Translation functions are defined in
15
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
16
`target/riscv/vcrypto_helper.c`.
17
18
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
19
Co-authored-by: William Salmon <will.salmon@codethink.co.uk>
20
[max.chou@sifive.com: Replaced vstart checking by TCG op]
21
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
22
Signed-off-by: William Salmon <will.salmon@codethink.co.uk>
23
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
24
Signed-off-by: Max Chou <max.chou@sifive.com>
5
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
25
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
6
Message-Id: <20230615063302.102409-6-liweiwei@iscas.ac.cn>
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>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
32
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
---
33
---
9
target/riscv/cpu.c | 7 +++++++
34
target/riscv/cpu_cfg.h | 1 +
10
1 file changed, 7 insertions(+)
35
target/riscv/helper.h | 14 ++
36
target/riscv/insn32.decode | 14 ++
37
target/riscv/cpu.c | 4 +-
38
target/riscv/vcrypto_helper.c | 202 +++++++++++++++++++++++
39
target/riscv/insn_trans/trans_rvvk.c.inc | 147 +++++++++++++++++
40
6 files changed, 381 insertions(+), 1 deletion(-)
11
41
42
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/riscv/cpu_cfg.h
45
+++ b/target/riscv/cpu_cfg.h
46
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
47
bool ext_zve64d;
48
bool ext_zvbb;
49
bool ext_zvbc;
50
+ bool ext_zvkned;
51
bool ext_zmmul;
52
bool ext_zvfbfmin;
53
bool ext_zvfbfwma;
54
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/riscv/helper.h
57
+++ b/target/riscv/helper.h
58
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vandn_vx_b, void, ptr, ptr, tl, ptr, env, i32)
59
DEF_HELPER_6(vandn_vx_h, void, ptr, ptr, tl, ptr, env, i32)
60
DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, i32)
61
DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32)
62
+
63
+DEF_HELPER_2(egs_check, void, i32, env)
64
+
65
+DEF_HELPER_4(vaesef_vv, void, ptr, ptr, env, i32)
66
+DEF_HELPER_4(vaesef_vs, void, ptr, ptr, env, i32)
67
+DEF_HELPER_4(vaesdf_vv, void, ptr, ptr, env, i32)
68
+DEF_HELPER_4(vaesdf_vs, void, ptr, ptr, env, i32)
69
+DEF_HELPER_4(vaesem_vv, void, ptr, ptr, env, i32)
70
+DEF_HELPER_4(vaesem_vs, void, ptr, ptr, env, i32)
71
+DEF_HELPER_4(vaesdm_vv, void, ptr, ptr, env, i32)
72
+DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
73
+DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
74
+DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
75
+DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
76
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
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
12
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
13
index XXXXXXX..XXXXXXX 100644
106
index XXXXXXX..XXXXXXX 100644
14
--- a/target/riscv/cpu.c
107
--- a/target/riscv/cpu.c
15
+++ b/target/riscv/cpu.c
108
+++ b/target/riscv/cpu.c
16
@@ -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[] = {
17
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
110
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
18
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
19
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
20
+ ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
21
ISA_EXT_DATA_ENTRY(zfh, PRIV_VERSION_1_11_0, ext_zfh),
22
ISA_EXT_DATA_ENTRY(zfhmin, PRIV_VERSION_1_11_0, ext_zfhmin),
23
ISA_EXT_DATA_ENTRY(zfinx, PRIV_VERSION_1_12_0, ext_zfinx),
24
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
25
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
26
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
27
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
28
+ ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
29
+ ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
30
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
111
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
31
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
112
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
113
+ ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
32
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
114
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
115
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
116
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
117
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
118
* In principle Zve*x would also suffice here, were they supported
119
* in qemu
120
*/
121
- if (cpu->cfg.ext_zvbb && !cpu->cfg.ext_zve32f) {
122
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) && !cpu->cfg.ext_zve32f) {
123
error_setg(errp,
124
"Vector crypto extensions require V or Zve* extensions");
125
return;
33
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
126
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
34
DEFINE_PROP_BOOL("x-zvfh", RISCVCPU, cfg.ext_zvfh, false),
127
/* Vector cryptography extensions */
35
DEFINE_PROP_BOOL("x-zvfhmin", RISCVCPU, cfg.ext_zvfhmin, false),
128
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
36
129
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
37
+ DEFINE_PROP_BOOL("x-zfbfmin", RISCVCPU, cfg.ext_zfbfmin, false),
130
+ DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
38
+ DEFINE_PROP_BOOL("x-zvfbfmin", RISCVCPU, cfg.ext_zvfbfmin, false),
131
39
+ DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
40
+
41
DEFINE_PROP_END_OF_LIST(),
132
DEFINE_PROP_END_OF_LIST(),
42
};
133
};
43
134
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
135
index XXXXXXX..XXXXXXX 100644
136
--- a/target/riscv/vcrypto_helper.c
137
+++ b/target/riscv/vcrypto_helper.c
138
@@ -XXX,XX +XXX,XX @@
139
#include "qemu/bitops.h"
140
#include "qemu/bswap.h"
141
#include "cpu.h"
142
+#include "crypto/aes.h"
143
+#include "crypto/aes-round.h"
144
#include "exec/memop.h"
145
#include "exec/exec-all.h"
146
#include "exec/helper-proto.h"
147
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vwsll_vx_w, WOP_UUU_W, H8, H4, DO_SLL)
148
GEN_VEXT_VX(vwsll_vx_b, 2)
149
GEN_VEXT_VX(vwsll_vx_h, 4)
150
GEN_VEXT_VX(vwsll_vx_w, 8)
151
+
152
+void HELPER(egs_check)(uint32_t egs, CPURISCVState *env)
153
+{
154
+ uint32_t vl = env->vl;
155
+ uint32_t vstart = env->vstart;
156
+
157
+ if (vl % egs != 0 || vstart % egs != 0) {
158
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
159
+ }
160
+}
161
+
162
+static inline void xor_round_key(AESState *round_state, AESState *round_key)
163
+{
164
+ round_state->v = round_state->v ^ round_key->v;
165
+}
166
+
167
+#define GEN_ZVKNED_HELPER_VV(NAME, ...) \
168
+ void HELPER(NAME)(void *vd, void *vs2, CPURISCVState *env, \
169
+ uint32_t desc) \
170
+ { \
171
+ uint32_t vl = env->vl; \
172
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4); \
173
+ uint32_t vta = vext_vta(desc); \
174
+ \
175
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \
176
+ AESState round_key; \
177
+ round_key.d[0] = *((uint64_t *)vs2 + H8(i * 2 + 0)); \
178
+ round_key.d[1] = *((uint64_t *)vs2 + H8(i * 2 + 1)); \
179
+ AESState round_state; \
180
+ round_state.d[0] = *((uint64_t *)vd + H8(i * 2 + 0)); \
181
+ round_state.d[1] = *((uint64_t *)vd + H8(i * 2 + 1)); \
182
+ __VA_ARGS__; \
183
+ *((uint64_t *)vd + H8(i * 2 + 0)) = round_state.d[0]; \
184
+ *((uint64_t *)vd + H8(i * 2 + 1)) = round_state.d[1]; \
185
+ } \
186
+ env->vstart = 0; \
187
+ /* set tail elements to 1s */ \
188
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4); \
189
+ }
190
+
191
+#define GEN_ZVKNED_HELPER_VS(NAME, ...) \
192
+ void HELPER(NAME)(void *vd, void *vs2, CPURISCVState *env, \
193
+ uint32_t desc) \
194
+ { \
195
+ uint32_t vl = env->vl; \
196
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4); \
197
+ uint32_t vta = vext_vta(desc); \
198
+ \
199
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \
200
+ AESState round_key; \
201
+ round_key.d[0] = *((uint64_t *)vs2 + H8(0)); \
202
+ round_key.d[1] = *((uint64_t *)vs2 + H8(1)); \
203
+ AESState round_state; \
204
+ round_state.d[0] = *((uint64_t *)vd + H8(i * 2 + 0)); \
205
+ round_state.d[1] = *((uint64_t *)vd + H8(i * 2 + 1)); \
206
+ __VA_ARGS__; \
207
+ *((uint64_t *)vd + H8(i * 2 + 0)) = round_state.d[0]; \
208
+ *((uint64_t *)vd + H8(i * 2 + 1)) = round_state.d[1]; \
209
+ } \
210
+ env->vstart = 0; \
211
+ /* set tail elements to 1s */ \
212
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4); \
213
+ }
214
+
215
+GEN_ZVKNED_HELPER_VV(vaesef_vv, aesenc_SB_SR_AK(&round_state,
216
+ &round_state,
217
+ &round_key,
218
+ false);)
219
+GEN_ZVKNED_HELPER_VS(vaesef_vs, aesenc_SB_SR_AK(&round_state,
220
+ &round_state,
221
+ &round_key,
222
+ false);)
223
+GEN_ZVKNED_HELPER_VV(vaesdf_vv, aesdec_ISB_ISR_AK(&round_state,
224
+ &round_state,
225
+ &round_key,
226
+ false);)
227
+GEN_ZVKNED_HELPER_VS(vaesdf_vs, aesdec_ISB_ISR_AK(&round_state,
228
+ &round_state,
229
+ &round_key,
230
+ false);)
231
+GEN_ZVKNED_HELPER_VV(vaesem_vv, aesenc_SB_SR_MC_AK(&round_state,
232
+ &round_state,
233
+ &round_key,
234
+ false);)
235
+GEN_ZVKNED_HELPER_VS(vaesem_vs, aesenc_SB_SR_MC_AK(&round_state,
236
+ &round_state,
237
+ &round_key,
238
+ false);)
239
+GEN_ZVKNED_HELPER_VV(vaesdm_vv, aesdec_ISB_ISR_AK_IMC(&round_state,
240
+ &round_state,
241
+ &round_key,
242
+ false);)
243
+GEN_ZVKNED_HELPER_VS(vaesdm_vs, aesdec_ISB_ISR_AK_IMC(&round_state,
244
+ &round_state,
245
+ &round_key,
246
+ false);)
247
+GEN_ZVKNED_HELPER_VS(vaesz_vs, xor_round_key(&round_state, &round_key);)
248
+
249
+void HELPER(vaeskf1_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
250
+ CPURISCVState *env, uint32_t desc)
251
+{
252
+ uint32_t *vd = vd_vptr;
253
+ uint32_t *vs2 = vs2_vptr;
254
+ uint32_t vl = env->vl;
255
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
256
+ uint32_t vta = vext_vta(desc);
257
+
258
+ uimm &= 0b1111;
259
+ if (uimm > 10 || uimm == 0) {
260
+ uimm ^= 0b1000;
261
+ }
262
+
263
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
264
+ uint32_t rk[8], tmp;
265
+ static const uint32_t rcon[] = {
266
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
267
+ 0x00000020, 0x00000040, 0x00000080, 0x0000001B, 0x00000036,
268
+ };
269
+
270
+ rk[0] = vs2[i * 4 + H4(0)];
271
+ rk[1] = vs2[i * 4 + H4(1)];
272
+ rk[2] = vs2[i * 4 + H4(2)];
273
+ rk[3] = vs2[i * 4 + H4(3)];
274
+ tmp = ror32(rk[3], 8);
275
+
276
+ rk[4] = rk[0] ^ (((uint32_t)AES_sbox[(tmp >> 24) & 0xff] << 24) |
277
+ ((uint32_t)AES_sbox[(tmp >> 16) & 0xff] << 16) |
278
+ ((uint32_t)AES_sbox[(tmp >> 8) & 0xff] << 8) |
279
+ ((uint32_t)AES_sbox[(tmp >> 0) & 0xff] << 0))
280
+ ^ rcon[uimm - 1];
281
+ rk[5] = rk[1] ^ rk[4];
282
+ rk[6] = rk[2] ^ rk[5];
283
+ rk[7] = rk[3] ^ rk[6];
284
+
285
+ vd[i * 4 + H4(0)] = rk[4];
286
+ vd[i * 4 + H4(1)] = rk[5];
287
+ vd[i * 4 + H4(2)] = rk[6];
288
+ vd[i * 4 + H4(3)] = rk[7];
289
+ }
290
+ env->vstart = 0;
291
+ /* set tail elements to 1s */
292
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
293
+}
294
+
295
+void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
296
+ CPURISCVState *env, uint32_t desc)
297
+{
298
+ uint32_t *vd = vd_vptr;
299
+ uint32_t *vs2 = vs2_vptr;
300
+ uint32_t vl = env->vl;
301
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
302
+ uint32_t vta = vext_vta(desc);
303
+
304
+ uimm &= 0b1111;
305
+ if (uimm > 14 || uimm < 2) {
306
+ uimm ^= 0b1000;
307
+ }
308
+
309
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
310
+ uint32_t rk[12], tmp;
311
+ static const uint32_t rcon[] = {
312
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
313
+ 0x00000020, 0x00000040, 0x00000080, 0x0000001B, 0x00000036,
314
+ };
315
+
316
+ rk[0] = vd[i * 4 + H4(0)];
317
+ rk[1] = vd[i * 4 + H4(1)];
318
+ rk[2] = vd[i * 4 + H4(2)];
319
+ rk[3] = vd[i * 4 + H4(3)];
320
+ rk[4] = vs2[i * 4 + H4(0)];
321
+ rk[5] = vs2[i * 4 + H4(1)];
322
+ rk[6] = vs2[i * 4 + H4(2)];
323
+ rk[7] = vs2[i * 4 + H4(3)];
324
+
325
+ if (uimm % 2 == 0) {
326
+ tmp = ror32(rk[7], 8);
327
+ rk[8] = rk[0] ^ (((uint32_t)AES_sbox[(tmp >> 24) & 0xff] << 24) |
328
+ ((uint32_t)AES_sbox[(tmp >> 16) & 0xff] << 16) |
329
+ ((uint32_t)AES_sbox[(tmp >> 8) & 0xff] << 8) |
330
+ ((uint32_t)AES_sbox[(tmp >> 0) & 0xff] << 0))
331
+ ^ rcon[(uimm - 1) / 2];
332
+ } else {
333
+ rk[8] = rk[0] ^ (((uint32_t)AES_sbox[(rk[7] >> 24) & 0xff] << 24) |
334
+ ((uint32_t)AES_sbox[(rk[7] >> 16) & 0xff] << 16) |
335
+ ((uint32_t)AES_sbox[(rk[7] >> 8) & 0xff] << 8) |
336
+ ((uint32_t)AES_sbox[(rk[7] >> 0) & 0xff] << 0));
337
+ }
338
+ rk[9] = rk[1] ^ rk[8];
339
+ rk[10] = rk[2] ^ rk[9];
340
+ rk[11] = rk[3] ^ rk[10];
341
+
342
+ vd[i * 4 + H4(0)] = rk[8];
343
+ vd[i * 4 + H4(1)] = rk[9];
344
+ vd[i * 4 + H4(2)] = rk[10];
345
+ vd[i * 4 + H4(3)] = rk[11];
346
+ }
347
+ env->vstart = 0;
348
+ /* set tail elements to 1s */
349
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
350
+}
351
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
352
index XXXXXXX..XXXXXXX 100644
353
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
354
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
355
@@ -XXX,XX +XXX,XX @@ static bool vwsll_vx_check(DisasContext *s, arg_rmrr *a)
356
GEN_OPIVV_WIDEN_TRANS(vwsll_vv, vwsll_vv_check)
357
GEN_OPIVX_WIDEN_TRANS(vwsll_vx, vwsll_vx_check)
358
GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
359
+
360
+/*
361
+ * Zvkned
362
+ */
363
+
364
+#define ZVKNED_EGS 4
365
+
366
+#define GEN_V_UNMASKED_TRANS(NAME, CHECK, EGS) \
367
+ static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
368
+ { \
369
+ if (CHECK(s, a)) { \
370
+ TCGv_ptr rd_v, rs2_v; \
371
+ TCGv_i32 desc, egs; \
372
+ uint32_t data = 0; \
373
+ TCGLabel *over = gen_new_label(); \
374
+ \
375
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
376
+ /* save opcode for unwinding in case we throw an exception */ \
377
+ decode_save_opc(s); \
378
+ egs = tcg_constant_i32(EGS); \
379
+ gen_helper_egs_check(egs, cpu_env); \
380
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
381
+ } \
382
+ \
383
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
384
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
385
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
386
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
387
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
388
+ rd_v = tcg_temp_new_ptr(); \
389
+ rs2_v = tcg_temp_new_ptr(); \
390
+ desc = tcg_constant_i32( \
391
+ simd_desc(s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, data)); \
392
+ tcg_gen_addi_ptr(rd_v, cpu_env, vreg_ofs(s, a->rd)); \
393
+ tcg_gen_addi_ptr(rs2_v, cpu_env, vreg_ofs(s, a->rs2)); \
394
+ gen_helper_##NAME(rd_v, rs2_v, cpu_env, desc); \
395
+ mark_vs_dirty(s); \
396
+ gen_set_label(over); \
397
+ return true; \
398
+ } \
399
+ return false; \
400
+ }
401
+
402
+static bool vaes_check_vv(DisasContext *s, arg_rmr *a)
403
+{
404
+ int egw_bytes = ZVKNED_EGS << s->sew;
405
+ return s->cfg_ptr->ext_zvkned == true &&
406
+ require_rvv(s) &&
407
+ vext_check_isa_ill(s) &&
408
+ MAXSZ(s) >= egw_bytes &&
409
+ require_align(a->rd, s->lmul) &&
410
+ require_align(a->rs2, s->lmul) &&
411
+ s->sew == MO_32;
412
+}
413
+
414
+static bool vaes_check_overlap(DisasContext *s, int vd, int vs2)
415
+{
416
+ int8_t op_size = s->lmul <= 0 ? 1 : 1 << s->lmul;
417
+ return !is_overlapped(vd, op_size, vs2, 1);
418
+}
419
+
420
+static bool vaes_check_vs(DisasContext *s, arg_rmr *a)
421
+{
422
+ int egw_bytes = ZVKNED_EGS << s->sew;
423
+ return vaes_check_overlap(s, a->rd, a->rs2) &&
424
+ MAXSZ(s) >= egw_bytes &&
425
+ s->cfg_ptr->ext_zvkned == true &&
426
+ require_rvv(s) &&
427
+ vext_check_isa_ill(s) &&
428
+ require_align(a->rd, s->lmul) &&
429
+ s->sew == MO_32;
430
+}
431
+
432
+GEN_V_UNMASKED_TRANS(vaesef_vv, vaes_check_vv, ZVKNED_EGS)
433
+GEN_V_UNMASKED_TRANS(vaesef_vs, vaes_check_vs, ZVKNED_EGS)
434
+GEN_V_UNMASKED_TRANS(vaesdf_vv, vaes_check_vv, ZVKNED_EGS)
435
+GEN_V_UNMASKED_TRANS(vaesdf_vs, vaes_check_vs, ZVKNED_EGS)
436
+GEN_V_UNMASKED_TRANS(vaesdm_vv, vaes_check_vv, ZVKNED_EGS)
437
+GEN_V_UNMASKED_TRANS(vaesdm_vs, vaes_check_vs, ZVKNED_EGS)
438
+GEN_V_UNMASKED_TRANS(vaesz_vs, vaes_check_vs, ZVKNED_EGS)
439
+GEN_V_UNMASKED_TRANS(vaesem_vv, vaes_check_vv, ZVKNED_EGS)
440
+GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS)
441
+
442
+#define GEN_VI_UNMASKED_TRANS(NAME, CHECK, EGS) \
443
+ static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
444
+ { \
445
+ if (CHECK(s, a)) { \
446
+ TCGv_ptr rd_v, rs2_v; \
447
+ TCGv_i32 uimm_v, desc, egs; \
448
+ uint32_t data = 0; \
449
+ TCGLabel *over = gen_new_label(); \
450
+ \
451
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
452
+ /* save opcode for unwinding in case we throw an exception */ \
453
+ decode_save_opc(s); \
454
+ egs = tcg_constant_i32(EGS); \
455
+ gen_helper_egs_check(egs, cpu_env); \
456
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
457
+ } \
458
+ \
459
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
460
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
461
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
462
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
463
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
464
+ \
465
+ rd_v = tcg_temp_new_ptr(); \
466
+ rs2_v = tcg_temp_new_ptr(); \
467
+ uimm_v = tcg_constant_i32(a->rs1); \
468
+ desc = tcg_constant_i32( \
469
+ simd_desc(s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, data)); \
470
+ tcg_gen_addi_ptr(rd_v, cpu_env, vreg_ofs(s, a->rd)); \
471
+ tcg_gen_addi_ptr(rs2_v, cpu_env, vreg_ofs(s, a->rs2)); \
472
+ gen_helper_##NAME(rd_v, rs2_v, uimm_v, cpu_env, desc); \
473
+ mark_vs_dirty(s); \
474
+ gen_set_label(over); \
475
+ return true; \
476
+ } \
477
+ return false; \
478
+ }
479
+
480
+static bool vaeskf1_check(DisasContext *s, arg_vaeskf1_vi *a)
481
+{
482
+ int egw_bytes = ZVKNED_EGS << s->sew;
483
+ return s->cfg_ptr->ext_zvkned == true &&
484
+ require_rvv(s) &&
485
+ vext_check_isa_ill(s) &&
486
+ MAXSZ(s) >= egw_bytes &&
487
+ s->sew == MO_32 &&
488
+ require_align(a->rd, s->lmul) &&
489
+ require_align(a->rs2, s->lmul);
490
+}
491
+
492
+static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi *a)
493
+{
494
+ int egw_bytes = ZVKNED_EGS << s->sew;
495
+ return s->cfg_ptr->ext_zvkned == true &&
496
+ require_rvv(s) &&
497
+ vext_check_isa_ill(s) &&
498
+ MAXSZ(s) >= egw_bytes &&
499
+ s->sew == MO_32 &&
500
+ require_align(a->rd, s->lmul) &&
501
+ require_align(a->rs2, s->lmul);
502
+}
503
+
504
+GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, ZVKNED_EGS)
505
+GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
44
--
506
--
45
2.40.1
507
2.41.0
diff view generated by jsdifflib
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
Add trans_* and helper function for Zvfbfmin instructions.
3
This commit adds support for the Zvknh vector-crypto extension, which
4
consists of the following instructions:
4
5
5
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
* vsha2ms.vv
6
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
7
* vsha2c[hl].vv
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
8
Message-Id: <20230615063302.102409-4-liweiwei@iscas.ac.cn>
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
14
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
15
[max.chou@sifive.com: Replaced vstart checking by TCG op]
16
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
17
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
18
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
19
Signed-off-by: Max Chou <max.chou@sifive.com>
20
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
21
[max.chou@sifive.com: Exposed x-zvknha & x-zvknhb properties]
22
[max.chou@sifive.com: Replaced SEW selection to happened during
23
translation]
24
Message-ID: <20230711165917.2629866-11-max.chou@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
26
---
11
target/riscv/helper.h | 3 +
27
target/riscv/cpu_cfg.h | 2 +
12
target/riscv/insn32.decode | 4 ++
28
target/riscv/helper.h | 6 +
13
target/riscv/vector_helper.c | 6 ++
29
target/riscv/insn32.decode | 5 +
14
target/riscv/insn_trans/trans_rvbf16.c.inc | 64 ++++++++++++++++++++++
30
target/riscv/cpu.c | 13 +-
15
4 files changed, 77 insertions(+)
31
target/riscv/vcrypto_helper.c | 238 +++++++++++++++++++++++
32
target/riscv/insn_trans/trans_rvvk.c.inc | 129 ++++++++++++
33
6 files changed, 390 insertions(+), 3 deletions(-)
16
34
35
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/cpu_cfg.h
38
+++ b/target/riscv/cpu_cfg.h
39
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
40
bool ext_zvbb;
41
bool ext_zvbc;
42
bool ext_zvkned;
43
+ bool ext_zvknha;
44
+ bool ext_zvknhb;
45
bool ext_zmmul;
46
bool ext_zvfbfmin;
47
bool ext_zvfbfwma;
17
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
18
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/helper.h
50
--- a/target/riscv/helper.h
20
+++ b/target/riscv/helper.h
51
+++ b/target/riscv/helper.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(cm_jalt, TCG_CALL_NO_WG, tl, env, i32)
52
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
22
/* BF16 functions */
53
DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
23
DEF_HELPER_FLAGS_2(fcvt_bf16_s, TCG_CALL_NO_RWG, i64, env, i64)
54
DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
24
DEF_HELPER_FLAGS_2(fcvt_s_bf16, TCG_CALL_NO_RWG, i64, env, i64)
55
DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
25
+
56
+
26
+DEF_HELPER_5(vfncvtbf16_f_f_w, void, ptr, ptr, ptr, env, i32)
57
+DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32)
27
+DEF_HELPER_5(vfwcvtbf16_f_f_v, void, ptr, ptr, ptr, env, i32)
58
+DEF_HELPER_5(vsha2ch32_vv, void, ptr, ptr, ptr, env, i32)
59
+DEF_HELPER_5(vsha2ch64_vv, void, ptr, ptr, ptr, env, i32)
60
+DEF_HELPER_5(vsha2cl32_vv, void, ptr, ptr, ptr, env, i32)
61
+DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
28
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
62
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
29
index XXXXXXX..XXXXXXX 100644
63
index XXXXXXX..XXXXXXX 100644
30
--- a/target/riscv/insn32.decode
64
--- a/target/riscv/insn32.decode
31
+++ b/target/riscv/insn32.decode
65
+++ b/target/riscv/insn32.decode
32
@@ -XXX,XX +XXX,XX @@ czero_nez 0000111 ..... ..... 111 ..... 0110011 @r
66
@@ -XXX,XX +XXX,XX @@ vaesdm_vs 101001 1 ..... 00000 010 ..... 1110111 @r2_vm_1
33
# *** Zfbfmin Standard Extension ***
67
vaesz_vs 101001 1 ..... 00111 010 ..... 1110111 @r2_vm_1
34
fcvt_bf16_s 0100010 01000 ..... ... ..... 1010011 @r2_rm
68
vaeskf1_vi 100010 1 ..... ..... 010 ..... 1110111 @r_vm_1
35
fcvt_s_bf16 0100000 00110 ..... ... ..... 1010011 @r2_rm
69
vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1
36
+
70
+
37
+# *** Zvfbfmin Standard Extension ***
71
+# *** Zvknh vector crypto extension ***
38
+vfncvtbf16_f_f_w 010010 . ..... 11101 001 ..... 1010111 @r2_vm
72
+vsha2ms_vv 101101 1 ..... ..... 010 ..... 1110111 @r_vm_1
39
+vfwcvtbf16_f_f_v 010010 . ..... 01101 001 ..... 1010111 @r2_vm
73
+vsha2ch_vv 101110 1 ..... ..... 010 ..... 1110111 @r_vm_1
40
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
74
+vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
75
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
41
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
42
--- a/target/riscv/vector_helper.c
77
--- a/target/riscv/cpu.c
43
+++ b/target/riscv/vector_helper.c
78
+++ b/target/riscv/cpu.c
44
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPFVV1, vfwcvt_f_f_v_w, WOP_UU_W, H8, H4, float32_to_float64)
79
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
45
GEN_VEXT_V_ENV(vfwcvt_f_f_v_h, 4)
80
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
46
GEN_VEXT_V_ENV(vfwcvt_f_f_v_w, 8)
81
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
47
82
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
48
+RVVCALL(OPFVV1, vfwcvtbf16_f_f_v, WOP_UU_H, H4, H2, bfloat16_to_float32)
83
+ ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
49
+GEN_VEXT_V_ENV(vfwcvtbf16_f_f_v, 4)
84
+ ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
50
+
85
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
51
/* Narrowing Floating-Point/Integer Type-Convert Instructions */
86
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
52
/* (TD, T2, TX2) */
87
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
53
#define NOP_UU_B uint8_t, uint16_t, uint32_t
88
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
54
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPFVV1, vfncvt_f_f_w_w, NOP_UU_W, H4, H8, float64_to_float32)
89
* In principle Zve*x would also suffice here, were they supported
55
GEN_VEXT_V_ENV(vfncvt_f_f_w_h, 2)
90
* in qemu
56
GEN_VEXT_V_ENV(vfncvt_f_f_w_w, 4)
91
*/
57
92
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) && !cpu->cfg.ext_zve32f) {
58
+RVVCALL(OPFVV1, vfncvtbf16_f_f_w, NOP_UU_H, H2, H4, float32_to_bfloat16)
93
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
59
+GEN_VEXT_V_ENV(vfncvtbf16_f_f_w, 2)
94
+ !cpu->cfg.ext_zve32f) {
60
+
95
error_setg(errp,
61
/*
96
"Vector crypto extensions require V or Zve* extensions");
62
* Vector Reduction Operations
97
return;
63
*/
98
}
64
diff --git a/target/riscv/insn_trans/trans_rvbf16.c.inc b/target/riscv/insn_trans/trans_rvbf16.c.inc
99
100
- if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
101
- error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
102
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
103
+ error_setg(
104
+ errp,
105
+ "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
106
return;
107
}
108
109
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
110
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
111
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
112
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
113
+ DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
114
+ DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
115
116
DEFINE_PROP_END_OF_LIST(),
117
};
118
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
65
index XXXXXXX..XXXXXXX 100644
119
index XXXXXXX..XXXXXXX 100644
66
--- a/target/riscv/insn_trans/trans_rvbf16.c.inc
120
--- a/target/riscv/vcrypto_helper.c
67
+++ b/target/riscv/insn_trans/trans_rvbf16.c.inc
121
+++ b/target/riscv/vcrypto_helper.c
68
@@ -XXX,XX +XXX,XX @@
122
@@ -XXX,XX +XXX,XX @@ void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
69
} \
123
/* set tail elements to 1s */
70
} while (0)
124
vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
71
72
+#define REQUIRE_ZVFBFMIN(ctx) do { \
73
+ if (!ctx->cfg_ptr->ext_zvfbfmin) { \
74
+ return false; \
75
+ } \
76
+} while (0)
77
+
78
static bool trans_fcvt_bf16_s(DisasContext *ctx, arg_fcvt_bf16_s *a)
79
{
80
REQUIRE_FPU;
81
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_s_bf16(DisasContext *ctx, arg_fcvt_s_bf16 *a)
82
mark_fs_dirty(ctx);
83
return true;
84
}
125
}
85
+
126
+
86
+static bool trans_vfncvtbf16_f_f_w(DisasContext *ctx, arg_vfncvtbf16_f_f_w *a)
127
+static inline uint32_t sig0_sha256(uint32_t x)
87
+{
128
+{
88
+ REQUIRE_FPU;
129
+ return ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3);
89
+ REQUIRE_ZVFBFMIN(ctx);
130
+}
90
+
131
+
91
+ if (opfv_narrow_check(ctx, a) && (ctx->sew == MO_16)) {
132
+static inline uint32_t sig1_sha256(uint32_t x)
133
+{
134
+ return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
135
+}
136
+
137
+static inline uint64_t sig0_sha512(uint64_t x)
138
+{
139
+ return ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7);
140
+}
141
+
142
+static inline uint64_t sig1_sha512(uint64_t x)
143
+{
144
+ return ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6);
145
+}
146
+
147
+static inline void vsha2ms_e32(uint32_t *vd, uint32_t *vs1, uint32_t *vs2)
148
+{
149
+ uint32_t res[4];
150
+ res[0] = sig1_sha256(vs1[H4(2)]) + vs2[H4(1)] + sig0_sha256(vd[H4(1)]) +
151
+ vd[H4(0)];
152
+ res[1] = sig1_sha256(vs1[H4(3)]) + vs2[H4(2)] + sig0_sha256(vd[H4(2)]) +
153
+ vd[H4(1)];
154
+ res[2] =
155
+ sig1_sha256(res[0]) + vs2[H4(3)] + sig0_sha256(vd[H4(3)]) + vd[H4(2)];
156
+ res[3] =
157
+ sig1_sha256(res[1]) + vs1[H4(0)] + sig0_sha256(vs2[H4(0)]) + vd[H4(3)];
158
+ vd[H4(3)] = res[3];
159
+ vd[H4(2)] = res[2];
160
+ vd[H4(1)] = res[1];
161
+ vd[H4(0)] = res[0];
162
+}
163
+
164
+static inline void vsha2ms_e64(uint64_t *vd, uint64_t *vs1, uint64_t *vs2)
165
+{
166
+ uint64_t res[4];
167
+ res[0] = sig1_sha512(vs1[2]) + vs2[1] + sig0_sha512(vd[1]) + vd[0];
168
+ res[1] = sig1_sha512(vs1[3]) + vs2[2] + sig0_sha512(vd[2]) + vd[1];
169
+ res[2] = sig1_sha512(res[0]) + vs2[3] + sig0_sha512(vd[3]) + vd[2];
170
+ res[3] = sig1_sha512(res[1]) + vs1[0] + sig0_sha512(vs2[0]) + vd[3];
171
+ vd[3] = res[3];
172
+ vd[2] = res[2];
173
+ vd[1] = res[1];
174
+ vd[0] = res[0];
175
+}
176
+
177
+void HELPER(vsha2ms_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
178
+ uint32_t desc)
179
+{
180
+ uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
181
+ uint32_t esz = sew == MO_32 ? 4 : 8;
182
+ uint32_t total_elems;
183
+ uint32_t vta = vext_vta(desc);
184
+
185
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
186
+ if (sew == MO_32) {
187
+ vsha2ms_e32(((uint32_t *)vd) + i * 4, ((uint32_t *)vs1) + i * 4,
188
+ ((uint32_t *)vs2) + i * 4);
189
+ } else {
190
+ /* If not 32 then SEW should be 64 */
191
+ vsha2ms_e64(((uint64_t *)vd) + i * 4, ((uint64_t *)vs1) + i * 4,
192
+ ((uint64_t *)vs2) + i * 4);
193
+ }
194
+ }
195
+ /* set tail elements to 1s */
196
+ total_elems = vext_get_total_elems(env, desc, esz);
197
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
198
+ env->vstart = 0;
199
+}
200
+
201
+static inline uint64_t sum0_64(uint64_t x)
202
+{
203
+ return ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39);
204
+}
205
+
206
+static inline uint32_t sum0_32(uint32_t x)
207
+{
208
+ return ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22);
209
+}
210
+
211
+static inline uint64_t sum1_64(uint64_t x)
212
+{
213
+ return ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41);
214
+}
215
+
216
+static inline uint32_t sum1_32(uint32_t x)
217
+{
218
+ return ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25);
219
+}
220
+
221
+#define ch(x, y, z) ((x & y) ^ ((~x) & z))
222
+
223
+#define maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
224
+
225
+static void vsha2c_64(uint64_t *vs2, uint64_t *vd, uint64_t *vs1)
226
+{
227
+ uint64_t a = vs2[3], b = vs2[2], e = vs2[1], f = vs2[0];
228
+ uint64_t c = vd[3], d = vd[2], g = vd[1], h = vd[0];
229
+ uint64_t W0 = vs1[0], W1 = vs1[1];
230
+ uint64_t T1 = h + sum1_64(e) + ch(e, f, g) + W0;
231
+ uint64_t T2 = sum0_64(a) + maj(a, b, c);
232
+
233
+ h = g;
234
+ g = f;
235
+ f = e;
236
+ e = d + T1;
237
+ d = c;
238
+ c = b;
239
+ b = a;
240
+ a = T1 + T2;
241
+
242
+ T1 = h + sum1_64(e) + ch(e, f, g) + W1;
243
+ T2 = sum0_64(a) + maj(a, b, c);
244
+ h = g;
245
+ g = f;
246
+ f = e;
247
+ e = d + T1;
248
+ d = c;
249
+ c = b;
250
+ b = a;
251
+ a = T1 + T2;
252
+
253
+ vd[0] = f;
254
+ vd[1] = e;
255
+ vd[2] = b;
256
+ vd[3] = a;
257
+}
258
+
259
+static void vsha2c_32(uint32_t *vs2, uint32_t *vd, uint32_t *vs1)
260
+{
261
+ uint32_t a = vs2[H4(3)], b = vs2[H4(2)], e = vs2[H4(1)], f = vs2[H4(0)];
262
+ uint32_t c = vd[H4(3)], d = vd[H4(2)], g = vd[H4(1)], h = vd[H4(0)];
263
+ uint32_t W0 = vs1[H4(0)], W1 = vs1[H4(1)];
264
+ uint32_t T1 = h + sum1_32(e) + ch(e, f, g) + W0;
265
+ uint32_t T2 = sum0_32(a) + maj(a, b, c);
266
+
267
+ h = g;
268
+ g = f;
269
+ f = e;
270
+ e = d + T1;
271
+ d = c;
272
+ c = b;
273
+ b = a;
274
+ a = T1 + T2;
275
+
276
+ T1 = h + sum1_32(e) + ch(e, f, g) + W1;
277
+ T2 = sum0_32(a) + maj(a, b, c);
278
+ h = g;
279
+ g = f;
280
+ f = e;
281
+ e = d + T1;
282
+ d = c;
283
+ c = b;
284
+ b = a;
285
+ a = T1 + T2;
286
+
287
+ vd[H4(0)] = f;
288
+ vd[H4(1)] = e;
289
+ vd[H4(2)] = b;
290
+ vd[H4(3)] = a;
291
+}
292
+
293
+void HELPER(vsha2ch32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
294
+ uint32_t desc)
295
+{
296
+ const uint32_t esz = 4;
297
+ uint32_t total_elems;
298
+ uint32_t vta = vext_vta(desc);
299
+
300
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
301
+ vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i,
302
+ ((uint32_t *)vs1) + 4 * i + 2);
303
+ }
304
+
305
+ /* set tail elements to 1s */
306
+ total_elems = vext_get_total_elems(env, desc, esz);
307
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
308
+ env->vstart = 0;
309
+}
310
+
311
+void HELPER(vsha2ch64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
312
+ uint32_t desc)
313
+{
314
+ const uint32_t esz = 8;
315
+ uint32_t total_elems;
316
+ uint32_t vta = vext_vta(desc);
317
+
318
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
319
+ vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i,
320
+ ((uint64_t *)vs1) + 4 * i + 2);
321
+ }
322
+
323
+ /* set tail elements to 1s */
324
+ total_elems = vext_get_total_elems(env, desc, esz);
325
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
326
+ env->vstart = 0;
327
+}
328
+
329
+void HELPER(vsha2cl32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
330
+ uint32_t desc)
331
+{
332
+ const uint32_t esz = 4;
333
+ uint32_t total_elems;
334
+ uint32_t vta = vext_vta(desc);
335
+
336
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
337
+ vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i,
338
+ (((uint32_t *)vs1) + 4 * i));
339
+ }
340
+
341
+ /* set tail elements to 1s */
342
+ total_elems = vext_get_total_elems(env, desc, esz);
343
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
344
+ env->vstart = 0;
345
+}
346
+
347
+void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
348
+ uint32_t desc)
349
+{
350
+ uint32_t esz = 8;
351
+ uint32_t total_elems;
352
+ uint32_t vta = vext_vta(desc);
353
+
354
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
355
+ vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i,
356
+ (((uint64_t *)vs1) + 4 * i));
357
+ }
358
+
359
+ /* set tail elements to 1s */
360
+ total_elems = vext_get_total_elems(env, desc, esz);
361
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
362
+ env->vstart = 0;
363
+}
364
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
365
index XXXXXXX..XXXXXXX 100644
366
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
367
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
368
@@ -XXX,XX +XXX,XX @@ static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi *a)
369
370
GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, ZVKNED_EGS)
371
GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
372
+
373
+/*
374
+ * Zvknh
375
+ */
376
+
377
+#define ZVKNH_EGS 4
378
+
379
+#define GEN_VV_UNMASKED_TRANS(NAME, CHECK, EGS) \
380
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
381
+ { \
382
+ if (CHECK(s, a)) { \
383
+ uint32_t data = 0; \
384
+ TCGLabel *over = gen_new_label(); \
385
+ TCGv_i32 egs; \
386
+ \
387
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
388
+ /* save opcode for unwinding in case we throw an exception */ \
389
+ decode_save_opc(s); \
390
+ egs = tcg_constant_i32(EGS); \
391
+ gen_helper_egs_check(egs, cpu_env); \
392
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
393
+ } \
394
+ \
395
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
396
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
397
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
398
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
399
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
400
+ \
401
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1), \
402
+ vreg_ofs(s, a->rs2), cpu_env, \
403
+ s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, \
404
+ data, gen_helper_##NAME); \
405
+ \
406
+ mark_vs_dirty(s); \
407
+ gen_set_label(over); \
408
+ return true; \
409
+ } \
410
+ return false; \
411
+ }
412
+
413
+static bool vsha_check_sew(DisasContext *s)
414
+{
415
+ return (s->cfg_ptr->ext_zvknha == true && s->sew == MO_32) ||
416
+ (s->cfg_ptr->ext_zvknhb == true &&
417
+ (s->sew == MO_32 || s->sew == MO_64));
418
+}
419
+
420
+static bool vsha_check(DisasContext *s, arg_rmrr *a)
421
+{
422
+ int egw_bytes = ZVKNH_EGS << s->sew;
423
+ int mult = 1 << MAX(s->lmul, 0);
424
+ return opivv_check(s, a) &&
425
+ vsha_check_sew(s) &&
426
+ MAXSZ(s) >= egw_bytes &&
427
+ !is_overlapped(a->rd, mult, a->rs1, mult) &&
428
+ !is_overlapped(a->rd, mult, a->rs2, mult) &&
429
+ s->lmul >= 0;
430
+}
431
+
432
+GEN_VV_UNMASKED_TRANS(vsha2ms_vv, vsha_check, ZVKNH_EGS)
433
+
434
+static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
435
+{
436
+ if (vsha_check(s, a)) {
92
+ uint32_t data = 0;
437
+ uint32_t data = 0;
93
+ TCGLabel *over = gen_new_label();
438
+ TCGLabel *over = gen_new_label();
94
+
439
+ TCGv_i32 egs;
95
+ gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);
440
+
96
+ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
441
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
97
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
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
+ }
98
+
448
+
99
+ data = FIELD_DP32(data, VDATA, VM, a->vm);
449
+ data = FIELD_DP32(data, VDATA, VM, a->vm);
100
+ data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
450
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
101
+ data = FIELD_DP32(data, VDATA, VTA, ctx->vta);
451
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
102
+ data = FIELD_DP32(data, VDATA, VMA, ctx->vma);
452
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
103
+ tcg_gen_gvec_3_ptr(vreg_ofs(ctx, a->rd), vreg_ofs(ctx, 0),
453
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
104
+ vreg_ofs(ctx, a->rs2), cpu_env,
454
+
105
+ ctx->cfg_ptr->vlen / 8,
455
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
106
+ ctx->cfg_ptr->vlen / 8, data,
456
+ vreg_ofs(s, a->rs2), cpu_env, s->cfg_ptr->vlen / 8,
107
+ gen_helper_vfncvtbf16_f_f_w);
457
+ s->cfg_ptr->vlen / 8, data,
108
+ mark_vs_dirty(ctx);
458
+ s->sew == MO_32 ?
459
+ gen_helper_vsha2cl32_vv : gen_helper_vsha2cl64_vv);
460
+
461
+ mark_vs_dirty(s);
109
+ gen_set_label(over);
462
+ gen_set_label(over);
110
+ return true;
463
+ return true;
111
+ }
464
+ }
112
+ return false;
465
+ return false;
113
+}
466
+}
114
+
467
+
115
+static bool trans_vfwcvtbf16_f_f_v(DisasContext *ctx, arg_vfwcvtbf16_f_f_v *a)
468
+static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
116
+{
469
+{
117
+ REQUIRE_FPU;
470
+ if (vsha_check(s, a)) {
118
+ REQUIRE_ZVFBFMIN(ctx);
119
+
120
+ if (opfv_widen_check(ctx, a) && (ctx->sew == MO_16)) {
121
+ uint32_t data = 0;
471
+ uint32_t data = 0;
122
+ TCGLabel *over = gen_new_label();
472
+ TCGLabel *over = gen_new_label();
123
+
473
+ TCGv_i32 egs;
124
+ gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);
474
+
125
+ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
475
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
126
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
476
+ /* save opcode for unwinding in case we throw an exception */
477
+ decode_save_opc(s);
478
+ egs = tcg_constant_i32(ZVKNH_EGS);
479
+ gen_helper_egs_check(egs, cpu_env);
480
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
481
+ }
127
+
482
+
128
+ data = FIELD_DP32(data, VDATA, VM, a->vm);
483
+ data = FIELD_DP32(data, VDATA, VM, a->vm);
129
+ data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
484
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
130
+ data = FIELD_DP32(data, VDATA, VTA, ctx->vta);
485
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
131
+ data = FIELD_DP32(data, VDATA, VMA, ctx->vma);
486
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
132
+ tcg_gen_gvec_3_ptr(vreg_ofs(ctx, a->rd), vreg_ofs(ctx, 0),
487
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
133
+ vreg_ofs(ctx, a->rs2), cpu_env,
488
+
134
+ ctx->cfg_ptr->vlen / 8,
489
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
135
+ ctx->cfg_ptr->vlen / 8, data,
490
+ vreg_ofs(s, a->rs2), cpu_env, s->cfg_ptr->vlen / 8,
136
+ gen_helper_vfwcvtbf16_f_f_v);
491
+ s->cfg_ptr->vlen / 8, data,
137
+ mark_vs_dirty(ctx);
492
+ s->sew == MO_32 ?
493
+ gen_helper_vsha2ch32_vv : gen_helper_vsha2ch64_vv);
494
+
495
+ mark_vs_dirty(s);
138
+ gen_set_label(over);
496
+ gen_set_label(over);
139
+ return true;
497
+ return true;
140
+ }
498
+ }
141
+ return false;
499
+ return false;
142
+}
500
+}
143
--
501
--
144
2.40.1
502
2.41.0
diff view generated by jsdifflib
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
From: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
2
2
3
Add trans_* and helper function for Zvfbfwma instructions.
3
This commit adds support for the Zvksh vector-crypto extension, which
4
4
consists of the following instructions:
5
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
5
6
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
6
* vsm3me.vv
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
* vsm3c.vi
8
Message-Id: <20230615063302.102409-5-liweiwei@iscas.ac.cn>
8
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Co-authored-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
14
[max.chou@sifive.com: Replaced vstart checking by TCG op]
15
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
16
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
17
Signed-off-by: Max Chou <max.chou@sifive.com>
18
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
19
[max.chou@sifive.com: Exposed x-zvksh property]
20
Message-ID: <20230711165917.2629866-12-max.chou@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
22
---
11
target/riscv/helper.h | 3 ++
23
target/riscv/cpu_cfg.h | 1 +
12
target/riscv/insn32.decode | 4 ++
24
target/riscv/helper.h | 3 +
13
target/riscv/vector_helper.c | 11 ++++
25
target/riscv/insn32.decode | 4 +
14
target/riscv/insn_trans/trans_rvbf16.c.inc | 58 ++++++++++++++++++++++
26
target/riscv/cpu.c | 6 +-
15
4 files changed, 76 insertions(+)
27
target/riscv/vcrypto_helper.c | 134 +++++++++++++++++++++++
16
28
target/riscv/insn_trans/trans_rvvk.c.inc | 31 ++++++
29
6 files changed, 177 insertions(+), 2 deletions(-)
30
31
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/cpu_cfg.h
34
+++ b/target/riscv/cpu_cfg.h
35
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
36
bool ext_zvkned;
37
bool ext_zvknha;
38
bool ext_zvknhb;
39
+ bool ext_zvksh;
40
bool ext_zmmul;
41
bool ext_zvfbfmin;
42
bool ext_zvfbfwma;
17
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
43
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
18
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/helper.h
45
--- a/target/riscv/helper.h
20
+++ b/target/riscv/helper.h
46
+++ b/target/riscv/helper.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(fcvt_s_bf16, TCG_CALL_NO_RWG, i64, env, i64)
47
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsha2ch32_vv, void, ptr, ptr, ptr, env, i32)
22
48
DEF_HELPER_5(vsha2ch64_vv, void, ptr, ptr, ptr, env, i32)
23
DEF_HELPER_5(vfncvtbf16_f_f_w, void, ptr, ptr, ptr, env, i32)
49
DEF_HELPER_5(vsha2cl32_vv, void, ptr, ptr, ptr, env, i32)
24
DEF_HELPER_5(vfwcvtbf16_f_f_v, void, ptr, ptr, ptr, env, i32)
50
DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
25
+
51
+
26
+DEF_HELPER_6(vfwmaccbf16_vv, void, ptr, ptr, ptr, ptr, env, i32)
52
+DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
27
+DEF_HELPER_6(vfwmaccbf16_vf, void, ptr, ptr, i64, ptr, env, i32)
53
+DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
28
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
54
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
29
index XXXXXXX..XXXXXXX 100644
55
index XXXXXXX..XXXXXXX 100644
30
--- a/target/riscv/insn32.decode
56
--- a/target/riscv/insn32.decode
31
+++ b/target/riscv/insn32.decode
57
+++ b/target/riscv/insn32.decode
32
@@ -XXX,XX +XXX,XX @@ fcvt_s_bf16 0100000 00110 ..... ... ..... 1010011 @r2_rm
58
@@ -XXX,XX +XXX,XX @@ vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1
33
# *** Zvfbfmin Standard Extension ***
59
vsha2ms_vv 101101 1 ..... ..... 010 ..... 1110111 @r_vm_1
34
vfncvtbf16_f_f_w 010010 . ..... 11101 001 ..... 1010111 @r2_vm
60
vsha2ch_vv 101110 1 ..... ..... 010 ..... 1110111 @r_vm_1
35
vfwcvtbf16_f_f_v 010010 . ..... 01101 001 ..... 1010111 @r2_vm
61
vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
36
+
62
+
37
+# *** Zvfbfwma Standard Extension ***
63
+# *** Zvksh vector crypto extension ***
38
+vfwmaccbf16_vv 111011 . ..... ..... 001 ..... 1010111 @r_vm
64
+vsm3me_vv 100000 1 ..... ..... 010 ..... 1110111 @r_vm_1
39
+vfwmaccbf16_vf 111011 . ..... ..... 101 ..... 1010111 @r_vm
65
+vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
40
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
66
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
41
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
42
--- a/target/riscv/vector_helper.c
68
--- a/target/riscv/cpu.c
43
+++ b/target/riscv/vector_helper.c
69
+++ b/target/riscv/cpu.c
44
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPFVF3, vfwmacc_vf_w, WOP_UUU_W, H8, H4, fwmacc32)
70
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
45
GEN_VEXT_VF(vfwmacc_vf_h, 4)
71
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
46
GEN_VEXT_VF(vfwmacc_vf_w, 8)
72
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
47
73
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
48
+static uint32_t fwmaccbf16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
74
+ ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh),
49
+{
75
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
50
+ return float32_muladd(bfloat16_to_float32(a, s),
76
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
51
+ bfloat16_to_float32(b, s), d, 0, s);
77
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
52
+}
78
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
53
+
79
* In principle Zve*x would also suffice here, were they supported
54
+RVVCALL(OPFVV3, vfwmaccbf16_vv, WOP_UUU_H, H4, H2, H2, fwmaccbf16)
80
* in qemu
55
+GEN_VEXT_VV_ENV(vfwmaccbf16_vv, 4)
81
*/
56
+RVVCALL(OPFVF3, vfwmaccbf16_vf, WOP_UUU_H, H4, H2, fwmacc16)
82
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
57
+GEN_VEXT_VF(vfwmaccbf16_vf, 4)
83
- !cpu->cfg.ext_zve32f) {
58
+
84
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
59
static uint32_t fwnmacc16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
85
+ cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
60
{
86
error_setg(errp,
61
return float32_muladd(float16_to_float32(a, true, s),
87
"Vector crypto extensions require V or Zve* extensions");
62
diff --git a/target/riscv/insn_trans/trans_rvbf16.c.inc b/target/riscv/insn_trans/trans_rvbf16.c.inc
88
return;
63
index XXXXXXX..XXXXXXX 100644
89
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
64
--- a/target/riscv/insn_trans/trans_rvbf16.c.inc
90
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
65
+++ b/target/riscv/insn_trans/trans_rvbf16.c.inc
91
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
66
@@ -XXX,XX +XXX,XX @@
92
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
67
} \
93
+ DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
68
} while (0)
94
69
95
DEFINE_PROP_END_OF_LIST(),
70
+#define REQUIRE_ZVFBFWMA(ctx) do { \
96
};
71
+ if (!ctx->cfg_ptr->ext_zvfbfwma) { \
97
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
72
+ return false; \
98
index XXXXXXX..XXXXXXX 100644
73
+ } \
99
--- a/target/riscv/vcrypto_helper.c
74
+} while (0)
100
+++ b/target/riscv/vcrypto_helper.c
75
+
101
@@ -XXX,XX +XXX,XX @@ void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
76
static bool trans_fcvt_bf16_s(DisasContext *ctx, arg_fcvt_bf16_s *a)
102
vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
77
{
103
env->vstart = 0;
78
REQUIRE_FPU;
104
}
79
@@ -XXX,XX +XXX,XX @@ static bool trans_vfwcvtbf16_f_f_v(DisasContext *ctx, arg_vfwcvtbf16_f_f_v *a)
105
+
106
+static inline uint32_t p1(uint32_t x)
107
+{
108
+ return x ^ rol32(x, 15) ^ rol32(x, 23);
109
+}
110
+
111
+static inline uint32_t zvksh_w(uint32_t m16, uint32_t m9, uint32_t m3,
112
+ uint32_t m13, uint32_t m6)
113
+{
114
+ return p1(m16 ^ m9 ^ rol32(m3, 15)) ^ rol32(m13, 7) ^ m6;
115
+}
116
+
117
+void HELPER(vsm3me_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
118
+ CPURISCVState *env, uint32_t desc)
119
+{
120
+ uint32_t esz = memop_size(FIELD_EX64(env->vtype, VTYPE, VSEW));
121
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
122
+ uint32_t vta = vext_vta(desc);
123
+ uint32_t *vd = vd_vptr;
124
+ uint32_t *vs1 = vs1_vptr;
125
+ uint32_t *vs2 = vs2_vptr;
126
+
127
+ for (int i = env->vstart / 8; i < env->vl / 8; i++) {
128
+ uint32_t w[24];
129
+ for (int j = 0; j < 8; j++) {
130
+ w[j] = bswap32(vs1[H4((i * 8) + j)]);
131
+ w[j + 8] = bswap32(vs2[H4((i * 8) + j)]);
132
+ }
133
+ for (int j = 0; j < 8; j++) {
134
+ w[j + 16] =
135
+ zvksh_w(w[j], w[j + 7], w[j + 13], w[j + 3], w[j + 10]);
136
+ }
137
+ for (int j = 0; j < 8; j++) {
138
+ vd[(i * 8) + j] = bswap32(w[H4(j + 16)]);
139
+ }
140
+ }
141
+ vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
142
+ env->vstart = 0;
143
+}
144
+
145
+static inline uint32_t ff1(uint32_t x, uint32_t y, uint32_t z)
146
+{
147
+ return x ^ y ^ z;
148
+}
149
+
150
+static inline uint32_t ff2(uint32_t x, uint32_t y, uint32_t z)
151
+{
152
+ return (x & y) | (x & z) | (y & z);
153
+}
154
+
155
+static inline uint32_t ff_j(uint32_t x, uint32_t y, uint32_t z, uint32_t j)
156
+{
157
+ return (j <= 15) ? ff1(x, y, z) : ff2(x, y, z);
158
+}
159
+
160
+static inline uint32_t gg1(uint32_t x, uint32_t y, uint32_t z)
161
+{
162
+ return x ^ y ^ z;
163
+}
164
+
165
+static inline uint32_t gg2(uint32_t x, uint32_t y, uint32_t z)
166
+{
167
+ return (x & y) | (~x & z);
168
+}
169
+
170
+static inline uint32_t gg_j(uint32_t x, uint32_t y, uint32_t z, uint32_t j)
171
+{
172
+ return (j <= 15) ? gg1(x, y, z) : gg2(x, y, z);
173
+}
174
+
175
+static inline uint32_t t_j(uint32_t j)
176
+{
177
+ return (j <= 15) ? 0x79cc4519 : 0x7a879d8a;
178
+}
179
+
180
+static inline uint32_t p_0(uint32_t x)
181
+{
182
+ return x ^ rol32(x, 9) ^ rol32(x, 17);
183
+}
184
+
185
+static void sm3c(uint32_t *vd, uint32_t *vs1, uint32_t *vs2, uint32_t uimm)
186
+{
187
+ uint32_t x0, x1;
188
+ uint32_t j;
189
+ uint32_t ss1, ss2, tt1, tt2;
190
+ x0 = vs2[0] ^ vs2[4];
191
+ x1 = vs2[1] ^ vs2[5];
192
+ j = 2 * uimm;
193
+ ss1 = rol32(rol32(vs1[0], 12) + vs1[4] + rol32(t_j(j), j % 32), 7);
194
+ ss2 = ss1 ^ rol32(vs1[0], 12);
195
+ tt1 = ff_j(vs1[0], vs1[1], vs1[2], j) + vs1[3] + ss2 + x0;
196
+ tt2 = gg_j(vs1[4], vs1[5], vs1[6], j) + vs1[7] + ss1 + vs2[0];
197
+ vs1[3] = vs1[2];
198
+ vd[3] = rol32(vs1[1], 9);
199
+ vs1[1] = vs1[0];
200
+ vd[1] = tt1;
201
+ vs1[7] = vs1[6];
202
+ vd[7] = rol32(vs1[5], 19);
203
+ vs1[5] = vs1[4];
204
+ vd[5] = p_0(tt2);
205
+ j = 2 * uimm + 1;
206
+ ss1 = rol32(rol32(vd[1], 12) + vd[5] + rol32(t_j(j), j % 32), 7);
207
+ ss2 = ss1 ^ rol32(vd[1], 12);
208
+ tt1 = ff_j(vd[1], vs1[1], vd[3], j) + vs1[3] + ss2 + x1;
209
+ tt2 = gg_j(vd[5], vs1[5], vd[7], j) + vs1[7] + ss1 + vs2[1];
210
+ vd[2] = rol32(vs1[1], 9);
211
+ vd[0] = tt1;
212
+ vd[6] = rol32(vs1[5], 19);
213
+ vd[4] = p_0(tt2);
214
+}
215
+
216
+void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
217
+ CPURISCVState *env, uint32_t desc)
218
+{
219
+ uint32_t esz = memop_size(FIELD_EX64(env->vtype, VTYPE, VSEW));
220
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
221
+ uint32_t vta = vext_vta(desc);
222
+ uint32_t *vd = vd_vptr;
223
+ uint32_t *vs2 = vs2_vptr;
224
+ uint32_t v1[8], v2[8], v3[8];
225
+
226
+ for (int i = env->vstart / 8; i < env->vl / 8; i++) {
227
+ for (int k = 0; k < 8; k++) {
228
+ v2[k] = bswap32(vd[H4(i * 8 + k)]);
229
+ v3[k] = bswap32(vs2[H4(i * 8 + k)]);
230
+ }
231
+ sm3c(v1, v2, v3, uimm);
232
+ for (int k = 0; k < 8; k++) {
233
+ vd[i * 8 + k] = bswap32(v1[H4(k)]);
234
+ }
235
+ }
236
+ vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
237
+ env->vstart = 0;
238
+}
239
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
240
index XXXXXXX..XXXXXXX 100644
241
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
242
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
243
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
80
}
244
}
81
return false;
245
return false;
82
}
246
}
83
+
247
+
84
+static bool trans_vfwmaccbf16_vv(DisasContext *ctx, arg_vfwmaccbf16_vv *a)
248
+/*
85
+{
249
+ * Zvksh
86
+ REQUIRE_FPU;
250
+ */
87
+ REQUIRE_ZVFBFWMA(ctx);
251
+
88
+
252
+#define ZVKSH_EGS 8
89
+ if (require_rvv(ctx) && vext_check_isa_ill(ctx) && (ctx->sew == MO_16) &&
253
+
90
+ vext_check_dss(ctx, a->rd, a->rs1, a->rs2, a->vm)) {
254
+static inline bool vsm3_check(DisasContext *s, arg_rmrr *a)
91
+ uint32_t data = 0;
255
+{
92
+ TCGLabel *over = gen_new_label();
256
+ int egw_bytes = ZVKSH_EGS << s->sew;
93
+
257
+ int mult = 1 << MAX(s->lmul, 0);
94
+ gen_set_rm_chkfrm(ctx, RISCV_FRM_DYN);
258
+ return s->cfg_ptr->ext_zvksh == true &&
95
+ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
259
+ require_rvv(s) &&
96
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
260
+ vext_check_isa_ill(s) &&
97
+
261
+ !is_overlapped(a->rd, mult, a->rs2, mult) &&
98
+ data = FIELD_DP32(data, VDATA, VM, a->vm);
262
+ MAXSZ(s) >= egw_bytes &&
99
+ data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
263
+ s->sew == MO_32;
100
+ data = FIELD_DP32(data, VDATA, VTA, ctx->vta);
264
+}
101
+ data = FIELD_DP32(data, VDATA, VMA, ctx->vma);
265
+
102
+ tcg_gen_gvec_4_ptr(vreg_ofs(ctx, a->rd), vreg_ofs(ctx, 0),
266
+static inline bool vsm3me_check(DisasContext *s, arg_rmrr *a)
103
+ vreg_ofs(ctx, a->rs1),
267
+{
104
+ vreg_ofs(ctx, a->rs2), cpu_env,
268
+ return vsm3_check(s, a) && vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm);
105
+ ctx->cfg_ptr->vlen / 8,
269
+}
106
+ ctx->cfg_ptr->vlen / 8, data,
270
+
107
+ gen_helper_vfwmaccbf16_vv);
271
+static inline bool vsm3c_check(DisasContext *s, arg_rmrr *a)
108
+ mark_vs_dirty(ctx);
272
+{
109
+ gen_set_label(over);
273
+ return vsm3_check(s, a) && vext_check_ss(s, a->rd, a->rs2, a->vm);
110
+ return true;
274
+}
111
+ }
275
+
112
+ return false;
276
+GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS)
113
+}
277
+GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS)
114
+
115
+static bool trans_vfwmaccbf16_vf(DisasContext *ctx, arg_vfwmaccbf16_vf *a)
116
+{
117
+ REQUIRE_FPU;
118
+ REQUIRE_ZVFBFWMA(ctx);
119
+
120
+ if (require_rvv(ctx) && (ctx->sew == MO_16) && vext_check_isa_ill(ctx) &&
121
+ vext_check_ds(ctx, a->rd, a->rs2, a->vm)) {
122
+ uint32_t data = 0;
123
+
124
+ gen_set_rm(ctx, RISCV_FRM_DYN);
125
+ data = FIELD_DP32(data, VDATA, VM, a->vm);
126
+ data = FIELD_DP32(data, VDATA, LMUL, ctx->lmul);
127
+ data = FIELD_DP32(data, VDATA, VTA, ctx->vta);
128
+ data = FIELD_DP32(data, VDATA, VMA, ctx->vma);
129
+ return opfvf_trans(a->rd, a->rs1, a->rs2, data,
130
+ gen_helper_vfwmaccbf16_vf, ctx);
131
+ }
132
+
133
+ return false;
134
+}
135
--
278
--
136
2.40.1
279
2.41.0
diff view generated by jsdifflib
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
Add trans_* and helper function for Zfbfmin instructions.
3
This commit adds support for the Zvkg vector-crypto extension, which
4
4
consists of the following instructions:
5
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
5
6
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
6
* vgmul.vv
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
* vghsh.vv
8
Message-Id: <20230615063302.102409-3-liweiwei@iscas.ac.cn>
8
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
14
[max.chou@sifive.com: Replaced vstart checking by TCG op]
15
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
16
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
17
Signed-off-by: Max Chou <max.chou@sifive.com>
18
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
19
[max.chou@sifive.com: Exposed x-zvkg property]
20
[max.chou@sifive.com: Replaced uint by int for cross win32 build]
21
Message-ID: <20230711165917.2629866-13-max.chou@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
23
---
11
target/riscv/helper.h | 4 ++
24
target/riscv/cpu_cfg.h | 1 +
12
target/riscv/insn32.decode | 4 ++
25
target/riscv/helper.h | 3 +
13
target/riscv/fpu_helper.c | 12 +++++
26
target/riscv/insn32.decode | 4 ++
14
target/riscv/translate.c | 1 +
27
target/riscv/cpu.c | 6 +-
15
target/riscv/insn_trans/trans_rvbf16.c.inc | 53 ++++++++++++++++++++++
28
target/riscv/vcrypto_helper.c | 72 ++++++++++++++++++++++++
16
target/riscv/insn_trans/trans_rvzfh.c.inc | 12 ++---
29
target/riscv/insn_trans/trans_rvvk.c.inc | 30 ++++++++++
17
6 files changed, 80 insertions(+), 6 deletions(-)
30
6 files changed, 114 insertions(+), 2 deletions(-)
18
create mode 100644 target/riscv/insn_trans/trans_rvbf16.c.inc
31
19
32
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/cpu_cfg.h
35
+++ b/target/riscv/cpu_cfg.h
36
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
37
bool ext_zve64d;
38
bool ext_zvbb;
39
bool ext_zvbc;
40
+ bool ext_zvkg;
41
bool ext_zvkned;
42
bool ext_zvknha;
43
bool ext_zvknhb;
20
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
44
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
21
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/helper.h
46
--- a/target/riscv/helper.h
23
+++ b/target/riscv/helper.h
47
+++ b/target/riscv/helper.h
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sm4ks, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl)
48
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
25
49
26
/* Zce helper */
50
DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
27
DEF_HELPER_FLAGS_2(cm_jalt, TCG_CALL_NO_WG, tl, env, i32)
51
DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
28
+
52
+
29
+/* BF16 functions */
53
+DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
30
+DEF_HELPER_FLAGS_2(fcvt_bf16_s, TCG_CALL_NO_RWG, i64, env, i64)
54
+DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
31
+DEF_HELPER_FLAGS_2(fcvt_s_bf16, TCG_CALL_NO_RWG, i64, env, i64)
32
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
55
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
33
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/insn32.decode
57
--- a/target/riscv/insn32.decode
35
+++ b/target/riscv/insn32.decode
58
+++ b/target/riscv/insn32.decode
36
@@ -XXX,XX +XXX,XX @@ sm4ks .. 11010 ..... ..... 000 ..... 0110011 @k_aes
59
@@ -XXX,XX +XXX,XX @@ vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
37
# *** RV32 Zicond Standard Extension ***
60
# *** Zvksh vector crypto extension ***
38
czero_eqz 0000111 ..... ..... 101 ..... 0110011 @r
61
vsm3me_vv 100000 1 ..... ..... 010 ..... 1110111 @r_vm_1
39
czero_nez 0000111 ..... ..... 111 ..... 0110011 @r
62
vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
40
+
63
+
41
+# *** Zfbfmin Standard Extension ***
64
+# *** Zvkg vector crypto extension ***
42
+fcvt_bf16_s 0100010 01000 ..... ... ..... 1010011 @r2_rm
65
+vghsh_vv 101100 1 ..... ..... 010 ..... 1110111 @r_vm_1
43
+fcvt_s_bf16 0100000 00110 ..... ... ..... 1010011 @r2_rm
66
+vgmul_vv 101000 1 ..... 10001 010 ..... 1110111 @r2_vm_1
44
diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
67
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
45
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
46
--- a/target/riscv/fpu_helper.c
69
--- a/target/riscv/cpu.c
47
+++ b/target/riscv/fpu_helper.c
70
+++ b/target/riscv/cpu.c
48
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fcvt_d_h(CPURISCVState *env, uint64_t rs1)
71
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
49
float16 frs1 = check_nanbox_h(env, rs1);
72
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
50
return float16_to_float64(frs1, true, &env->fp_status);
73
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
74
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
75
+ ISA_EXT_DATA_ENTRY(zvkg, PRIV_VERSION_1_12_0, ext_zvkg),
76
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
77
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
78
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
79
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
80
* In principle Zve*x would also suffice here, were they supported
81
* in qemu
82
*/
83
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
84
- cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
85
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
86
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
87
error_setg(errp,
88
"Vector crypto extensions require V or Zve* extensions");
89
return;
90
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
91
/* Vector cryptography extensions */
92
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
93
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
94
+ DEFINE_PROP_BOOL("x-zvkg", RISCVCPU, cfg.ext_zvkg, false),
95
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
96
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
97
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
98
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/riscv/vcrypto_helper.c
101
+++ b/target/riscv/vcrypto_helper.c
102
@@ -XXX,XX +XXX,XX @@ void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
103
vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
104
env->vstart = 0;
51
}
105
}
52
+
106
+
53
+uint64_t helper_fcvt_bf16_s(CPURISCVState *env, uint64_t rs1)
107
+void HELPER(vghsh_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
54
+{
108
+ CPURISCVState *env, uint32_t desc)
55
+ float32 frs1 = check_nanbox_s(env, rs1);
109
+{
56
+ return nanbox_h(env, float32_to_bfloat16(frs1, &env->fp_status));
110
+ uint64_t *vd = vd_vptr;
57
+}
111
+ uint64_t *vs1 = vs1_vptr;
58
+
112
+ uint64_t *vs2 = vs2_vptr;
59
+uint64_t helper_fcvt_s_bf16(CPURISCVState *env, uint64_t rs1)
113
+ uint32_t vta = vext_vta(desc);
60
+{
114
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
61
+ float16 frs1 = check_nanbox_h(env, rs1);
115
+
62
+ return nanbox_s(env, bfloat16_to_float32(frs1, &env->fp_status));
116
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
63
+}
117
+ uint64_t Y[2] = {vd[i * 2 + 0], vd[i * 2 + 1]};
64
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
118
+ uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
65
index XXXXXXX..XXXXXXX 100644
119
+ uint64_t X[2] = {vs1[i * 2 + 0], vs1[i * 2 + 1]};
66
--- a/target/riscv/translate.c
120
+ uint64_t Z[2] = {0, 0};
67
+++ b/target/riscv/translate.c
121
+
68
@@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
122
+ uint64_t S[2] = {brev8(Y[0] ^ X[0]), brev8(Y[1] ^ X[1])};
69
#include "insn_trans/trans_rvk.c.inc"
123
+
70
#include "insn_trans/trans_privileged.c.inc"
124
+ for (int j = 0; j < 128; j++) {
71
#include "insn_trans/trans_svinval.c.inc"
125
+ if ((S[j / 64] >> (j % 64)) & 1) {
72
+#include "insn_trans/trans_rvbf16.c.inc"
126
+ Z[0] ^= H[0];
73
#include "decode-xthead.c.inc"
127
+ Z[1] ^= H[1];
74
#include "insn_trans/trans_xthead.c.inc"
128
+ }
75
#include "insn_trans/trans_xventanacondops.c.inc"
129
+ bool reduce = ((H[1] >> 63) & 1);
76
diff --git a/target/riscv/insn_trans/trans_rvbf16.c.inc b/target/riscv/insn_trans/trans_rvbf16.c.inc
130
+ H[1] = H[1] << 1 | H[0] >> 63;
77
new file mode 100644
131
+ H[0] = H[0] << 1;
78
index XXXXXXX..XXXXXXX
132
+ if (reduce) {
79
--- /dev/null
133
+ H[0] ^= 0x87;
80
+++ b/target/riscv/insn_trans/trans_rvbf16.c.inc
134
+ }
81
@@ -XXX,XX +XXX,XX @@
135
+ }
136
+
137
+ vd[i * 2 + 0] = brev8(Z[0]);
138
+ vd[i * 2 + 1] = brev8(Z[1]);
139
+ }
140
+ /* set tail elements to 1s */
141
+ vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
142
+ env->vstart = 0;
143
+}
144
+
145
+void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env,
146
+ uint32_t desc)
147
+{
148
+ uint64_t *vd = vd_vptr;
149
+ uint64_t *vs2 = vs2_vptr;
150
+ uint32_t vta = vext_vta(desc);
151
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
152
+
153
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
154
+ uint64_t Y[2] = {brev8(vd[i * 2 + 0]), brev8(vd[i * 2 + 1])};
155
+ uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
156
+ uint64_t Z[2] = {0, 0};
157
+
158
+ for (int j = 0; j < 128; j++) {
159
+ if ((Y[j / 64] >> (j % 64)) & 1) {
160
+ Z[0] ^= H[0];
161
+ Z[1] ^= H[1];
162
+ }
163
+ bool reduce = ((H[1] >> 63) & 1);
164
+ H[1] = H[1] << 1 | H[0] >> 63;
165
+ H[0] = H[0] << 1;
166
+ if (reduce) {
167
+ H[0] ^= 0x87;
168
+ }
169
+ }
170
+
171
+ vd[i * 2 + 0] = brev8(Z[0]);
172
+ vd[i * 2 + 1] = brev8(Z[1]);
173
+ }
174
+ /* set tail elements to 1s */
175
+ vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
176
+ env->vstart = 0;
177
+}
178
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
179
index XXXXXXX..XXXXXXX 100644
180
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
181
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
182
@@ -XXX,XX +XXX,XX @@ static inline bool vsm3c_check(DisasContext *s, arg_rmrr *a)
183
184
GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS)
185
GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS)
186
+
82
+/*
187
+/*
83
+ * RISC-V translation routines for the BF16 Standard Extensions.
188
+ * Zvkg
84
+ *
85
+ * Copyright (c) 2020-2023 PLCT Lab
86
+ *
87
+ * This program is free software; you can redistribute it and/or modify it
88
+ * under the terms and conditions of the GNU General Public License,
89
+ * version 2 or later, as published by the Free Software Foundation.
90
+ *
91
+ * This program is distributed in the hope it will be useful, but WITHOUT
92
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
93
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
94
+ * more details.
95
+ *
96
+ * You should have received a copy of the GNU General Public License along with
97
+ * this program. If not, see <http://www.gnu.org/licenses/>.
98
+ */
189
+ */
99
+
190
+
100
+#define REQUIRE_ZFBFMIN(ctx) do { \
191
+#define ZVKG_EGS 4
101
+ if (!ctx->cfg_ptr->ext_zfbfmin) { \
192
+
102
+ return false; \
193
+static bool vgmul_check(DisasContext *s, arg_rmr *a)
103
+ } \
194
+{
104
+} while (0)
195
+ int egw_bytes = ZVKG_EGS << s->sew;
105
+
196
+ return s->cfg_ptr->ext_zvkg == true &&
106
+static bool trans_fcvt_bf16_s(DisasContext *ctx, arg_fcvt_bf16_s *a)
197
+ vext_check_isa_ill(s) &&
107
+{
198
+ require_rvv(s) &&
108
+ REQUIRE_FPU;
199
+ MAXSZ(s) >= egw_bytes &&
109
+ REQUIRE_ZFBFMIN(ctx);
200
+ vext_check_ss(s, a->rd, a->rs2, a->vm) &&
110
+
201
+ s->sew == MO_32;
111
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
202
+}
112
+ TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
203
+
113
+
204
+GEN_V_UNMASKED_TRANS(vgmul_vv, vgmul_check, ZVKG_EGS)
114
+ gen_set_rm(ctx, a->rm);
205
+
115
+ gen_helper_fcvt_bf16_s(dest, cpu_env, src1);
206
+static bool vghsh_check(DisasContext *s, arg_rmrr *a)
116
+ gen_set_fpr_hs(ctx, a->rd, dest);
207
+{
117
+ mark_fs_dirty(ctx);
208
+ int egw_bytes = ZVKG_EGS << s->sew;
118
+ return true;
209
+ return s->cfg_ptr->ext_zvkg == true &&
119
+}
210
+ opivv_check(s, a) &&
120
+
211
+ MAXSZ(s) >= egw_bytes &&
121
+static bool trans_fcvt_s_bf16(DisasContext *ctx, arg_fcvt_s_bf16 *a)
212
+ s->sew == MO_32;
122
+{
213
+}
123
+ REQUIRE_FPU;
214
+
124
+ REQUIRE_ZFBFMIN(ctx);
215
+GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
125
+
126
+ TCGv_i64 dest = dest_fpr(ctx, a->rd);
127
+ TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
128
+
129
+ gen_set_rm(ctx, a->rm);
130
+ gen_helper_fcvt_s_bf16(dest, cpu_env, src1);
131
+ gen_set_fpr_hs(ctx, a->rd, dest);
132
+ mark_fs_dirty(ctx);
133
+ return true;
134
+}
135
diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc b/target/riscv/insn_trans/trans_rvzfh.c.inc
136
index XXXXXXX..XXXXXXX 100644
137
--- a/target/riscv/insn_trans/trans_rvzfh.c.inc
138
+++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
139
@@ -XXX,XX +XXX,XX @@
140
} \
141
} while (0)
142
143
-#define REQUIRE_ZFHMIN(ctx) do { \
144
- if (!ctx->cfg_ptr->ext_zfhmin) { \
145
+#define REQUIRE_ZFHMIN_OR_ZFBFMIN(ctx) do { \
146
+ if (!ctx->cfg_ptr->ext_zfhmin && !ctx->cfg_ptr->ext_zfbfmin) { \
147
return false; \
148
} \
149
} while (0)
150
@@ -XXX,XX +XXX,XX @@ static bool trans_flh(DisasContext *ctx, arg_flh *a)
151
TCGv t0;
152
153
REQUIRE_FPU;
154
- REQUIRE_ZFHMIN(ctx);
155
+ REQUIRE_ZFHMIN_OR_ZFBFMIN(ctx);
156
157
decode_save_opc(ctx);
158
t0 = get_gpr(ctx, a->rs1, EXT_NONE);
159
@@ -XXX,XX +XXX,XX @@ static bool trans_fsh(DisasContext *ctx, arg_fsh *a)
160
TCGv t0;
161
162
REQUIRE_FPU;
163
- REQUIRE_ZFHMIN(ctx);
164
+ REQUIRE_ZFHMIN_OR_ZFBFMIN(ctx);
165
166
decode_save_opc(ctx);
167
t0 = get_gpr(ctx, a->rs1, EXT_NONE);
168
@@ -XXX,XX +XXX,XX @@ static bool trans_fcvt_h_wu(DisasContext *ctx, arg_fcvt_h_wu *a)
169
static bool trans_fmv_x_h(DisasContext *ctx, arg_fmv_x_h *a)
170
{
171
REQUIRE_FPU;
172
- REQUIRE_ZFHMIN(ctx);
173
+ REQUIRE_ZFHMIN_OR_ZFBFMIN(ctx);
174
175
TCGv dest = dest_gpr(ctx, a->rd);
176
177
@@ -XXX,XX +XXX,XX @@ static bool trans_fmv_x_h(DisasContext *ctx, arg_fmv_x_h *a)
178
static bool trans_fmv_h_x(DisasContext *ctx, arg_fmv_h_x *a)
179
{
180
REQUIRE_FPU;
181
- REQUIRE_ZFHMIN(ctx);
182
+ REQUIRE_ZFHMIN_OR_ZFBFMIN(ctx);
183
184
TCGv t0 = get_gpr(ctx, a->rs1, EXT_ZERO);
185
186
--
216
--
187
2.40.1
217
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
At this moment we're retrieving env->misa_ext during
3
Allows sharing of sm4_subword between different targets.
4
kvm_arch_init_cpu(), leaving env->misa_ext_mask behind.
5
4
6
We want to set env->misa_ext_mask, and we want to set it as early as
5
Signed-off-by: Max Chou <max.chou@sifive.com>
7
possible. The reason is that we're going to use it in the validation
6
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
process of the KVM MISA properties we're going to add next. Setting it
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
during arch_init_cpu() is too late for user validation.
8
Signed-off-by: Max Chou <max.chou@sifive.com>
10
9
Message-ID: <20230711165917.2629866-14-max.chou@sifive.com>
11
Move the code to a new helper that is going to be called during init()
12
time, via kvm_riscv_init_user_properties(), like we're already doing for
13
the machine ID properties. Set both misa_ext and misa_ext_mask to the
14
same value retrieved by the 'isa' config reg.
15
16
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
18
Acked-by: Alistair Francis <alistair.francis@wdc.com>
19
Message-Id: <20230706101738.460804-11-dbarboza@ventanamicro.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
11
---
22
target/riscv/kvm.c | 34 +++++++++++++++++++++++-----------
12
include/crypto/sm4.h | 8 ++++++++
23
1 file changed, 23 insertions(+), 11 deletions(-)
13
target/arm/tcg/crypto_helper.c | 10 ++--------
14
2 files changed, 10 insertions(+), 8 deletions(-)
24
15
25
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
16
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
26
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
27
--- a/target/riscv/kvm.c
18
--- a/include/crypto/sm4.h
28
+++ b/target/riscv/kvm.c
19
+++ b/include/crypto/sm4.h
29
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_machine_ids(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
20
@@ -XXX,XX +XXX,XX @@
30
}
21
31
}
22
extern const uint8_t sm4_sbox[256];
32
23
33
+static void kvm_riscv_init_misa_ext_mask(RISCVCPU *cpu,
24
+static inline uint32_t sm4_subword(uint32_t word)
34
+ KVMScratchCPU *kvmcpu)
35
+{
25
+{
36
+ CPURISCVState *env = &cpu->env;
26
+ return sm4_sbox[word & 0xff] |
37
+ struct kvm_one_reg reg;
27
+ sm4_sbox[(word >> 8) & 0xff] << 8 |
38
+ int ret;
28
+ sm4_sbox[(word >> 16) & 0xff] << 16 |
39
+
29
+ sm4_sbox[(word >> 24) & 0xff] << 24;
40
+ reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
41
+ KVM_REG_RISCV_CONFIG_REG(isa));
42
+ reg.addr = (uint64_t)&env->misa_ext_mask;
43
+ ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, &reg);
44
+
45
+ if (ret) {
46
+ error_report("Unable to fetch ISA register from KVM, "
47
+ "error %d", ret);
48
+ kvm_riscv_destroy_scratch_vcpu(kvmcpu);
49
+ exit(EXIT_FAILURE);
50
+ }
51
+
52
+ env->misa_ext = env->misa_ext_mask;
53
+}
30
+}
54
+
31
+
55
void kvm_riscv_init_user_properties(Object *cpu_obj)
32
#endif
56
{
33
diff --git a/target/arm/tcg/crypto_helper.c b/target/arm/tcg/crypto_helper.c
57
RISCVCPU *cpu = RISCV_CPU(cpu_obj);
34
index XXXXXXX..XXXXXXX 100644
58
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_init_user_properties(Object *cpu_obj)
35
--- a/target/arm/tcg/crypto_helper.c
59
}
36
+++ b/target/arm/tcg/crypto_helper.c
60
37
@@ -XXX,XX +XXX,XX @@ static void do_crypto_sm4e(uint64_t *rd, uint64_t *rn, uint64_t *rm)
61
kvm_riscv_init_machine_ids(cpu, &kvmcpu);
38
CR_ST_WORD(d, (i + 3) % 4) ^
62
+ kvm_riscv_init_misa_ext_mask(cpu, &kvmcpu);
39
CR_ST_WORD(n, i);
63
40
64
kvm_riscv_destroy_scratch_vcpu(&kvmcpu);
41
- t = sm4_sbox[t & 0xff] |
65
}
42
- sm4_sbox[(t >> 8) & 0xff] << 8 |
66
@@ -XXX,XX +XXX,XX @@ static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, CPUState *cs)
43
- sm4_sbox[(t >> 16) & 0xff] << 16 |
67
int kvm_arch_init_vcpu(CPUState *cs)
44
- sm4_sbox[(t >> 24) & 0xff] << 24;
68
{
45
+ t = sm4_subword(t);
69
int ret = 0;
46
70
- target_ulong isa;
47
CR_ST_WORD(d, i) ^= t ^ rol32(t, 2) ^ rol32(t, 10) ^ rol32(t, 18) ^
71
RISCVCPU *cpu = RISCV_CPU(cs);
48
rol32(t, 24);
72
- CPURISCVState *env = &cpu->env;
49
@@ -XXX,XX +XXX,XX @@ static void do_crypto_sm4ekey(uint64_t *rd, uint64_t *rn, uint64_t *rm)
73
- uint64_t id;
50
CR_ST_WORD(d, (i + 3) % 4) ^
74
51
CR_ST_WORD(m, i);
75
qemu_add_vm_change_state_handler(kvm_riscv_vm_state_change, cs);
52
76
53
- t = sm4_sbox[t & 0xff] |
77
- id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
54
- sm4_sbox[(t >> 8) & 0xff] << 8 |
78
- KVM_REG_RISCV_CONFIG_REG(isa));
55
- sm4_sbox[(t >> 16) & 0xff] << 16 |
79
- ret = kvm_get_one_reg(cs, id, &isa);
56
- sm4_sbox[(t >> 24) & 0xff] << 24;
80
- if (ret) {
57
+ t = sm4_subword(t);
81
- return ret;
58
82
- }
59
CR_ST_WORD(d, i) ^= t ^ rol32(t, 13) ^ rol32(t, 23);
83
- env->misa_ext = isa;
84
-
85
if (!object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST)) {
86
ret = kvm_vcpu_set_machine_ids(cpu, cs);
87
}
60
}
88
--
61
--
89
2.40.1
62
2.41.0
diff view generated by jsdifflib
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
3
Adds sm4_ck constant for use in sm4 cryptography across different targets.
4
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
4
5
Acked-by: Alistair Francis <alistair.francis@wdc.com>
5
Signed-off-by: Max Chou <max.chou@sifive.com>
6
Message-Id: <20230703071759.86775-2-liweiwei@iscas.ac.cn>
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>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
---
10
---
9
disas/riscv.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
11
include/crypto/sm4.h | 1 +
10
1 file changed, 44 insertions(+)
12
crypto/sm4.c | 10 ++++++++++
13
2 files changed, 11 insertions(+)
11
14
12
diff --git a/disas/riscv.c b/disas/riscv.c
15
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/disas/riscv.c
17
--- a/include/crypto/sm4.h
15
+++ b/disas/riscv.c
18
+++ b/include/crypto/sm4.h
16
@@ -XXX,XX +XXX,XX @@ typedef enum {
19
@@ -XXX,XX +XXX,XX @@
17
rv_op_cm_jalt = 788,
20
#define QEMU_SM4_H
18
rv_op_czero_eqz = 789,
21
19
rv_op_czero_nez = 790,
22
extern const uint8_t sm4_sbox[256];
20
+ rv_op_fcvt_bf16_s = 791,
23
+extern const uint32_t sm4_ck[32];
21
+ rv_op_fcvt_s_bf16 = 792,
24
22
+ rv_op_vfncvtbf16_f_f_w = 793,
25
static inline uint32_t sm4_subword(uint32_t word)
23
+ rv_op_vfwcvtbf16_f_f_v = 794,
26
{
24
+ rv_op_vfwmaccbf16_vv = 795,
27
diff --git a/crypto/sm4.c b/crypto/sm4.c
25
+ rv_op_vfwmaccbf16_vf = 796,
28
index XXXXXXX..XXXXXXX 100644
26
+ rv_op_flh = 797,
29
--- a/crypto/sm4.c
27
+ rv_op_fsh = 798,
30
+++ b/crypto/sm4.c
28
+ rv_op_fmv_h_x = 799,
31
@@ -XXX,XX +XXX,XX @@ uint8_t const sm4_sbox[] = {
29
+ rv_op_fmv_x_h = 800,
32
0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
30
} rv_op;
31
32
/* register names */
33
@@ -XXX,XX +XXX,XX @@ const rv_opcode_data rvi_opcode_data[] = {
34
{ "cm.jalt", rv_codec_zcmt_jt, rv_fmt_zcmt_index, NULL, 0 },
35
{ "czero.eqz", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
36
{ "czero.nez", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
37
+ { "fcvt.bf16.s", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
38
+ { "fcvt.s.bf16", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
39
+ { "vfncvtbf16.f.f.w", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
40
+ { "vfwcvtbf16.f.f.v", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, 0, 0, 0 },
41
+ { "vfwmaccbf16.vv", rv_codec_v_r, rv_fmt_vd_vs1_vs2_vm, NULL, 0, 0, 0 },
42
+ { "vfwmaccbf16.vf", rv_codec_v_r, rv_fmt_vd_fs1_vs2_vm, NULL, 0, 0, 0 },
43
+ { "flh", rv_codec_i, rv_fmt_frd_offset_rs1, NULL, 0, 0, 0 },
44
+ { "fsh", rv_codec_s, rv_fmt_frs2_offset_rs1, NULL, 0, 0, 0 },
45
+ { "fmv.h.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
46
+ { "fmv.x.h", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
47
};
33
};
48
34
49
/* CSR names */
35
+uint32_t const sm4_ck[] = {
50
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
36
+ 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
51
case 3: op = rv_op_vloxei8_v; break;
37
+ 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
52
}
38
+ 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
53
break;
39
+ 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
54
+ case 1: op = rv_op_flh; break;
40
+ 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
55
case 2: op = rv_op_flw; break;
41
+ 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
56
case 3: op = rv_op_fld; break;
42
+ 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
57
case 4: op = rv_op_flq; break;
43
+ 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
58
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
44
+};
59
case 3: op = rv_op_vsoxei8_v; break;
60
}
61
break;
62
+ case 1: op = rv_op_fsh; break;
63
case 2: op = rv_op_fsw; break;
64
case 3: op = rv_op_fsd; break;
65
case 4: op = rv_op_fsq; break;
66
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
67
switch ((inst >> 20) & 0b11111) {
68
case 1: op = rv_op_fcvt_s_d; break;
69
case 3: op = rv_op_fcvt_s_q; break;
70
+ case 6: op = rv_op_fcvt_s_bf16; break;
71
}
72
break;
73
case 33:
74
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
75
case 3: op = rv_op_fcvt_d_q; break;
76
}
77
break;
78
+ case 34:
79
+ switch (((inst >> 20) & 0b11111)) {
80
+ case 8: op = rv_op_fcvt_bf16_s; break;
81
+ }
82
+ break;
83
case 35:
84
switch ((inst >> 20) & 0b11111) {
85
case 0: op = rv_op_fcvt_q_s; break;
86
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
87
case 1: op = rv_op_fclass_d; break;
88
}
89
break;
90
+ case 114:
91
+ switch (((inst >> 17) & 0b11111000) |
92
+ ((inst >> 12) & 0b00000111)) {
93
+ case 0: op = rv_op_fmv_x_h; break;
94
+ }
95
+ break;
96
case 115:
97
switch (((inst >> 17) & 0b11111000) |
98
((inst >> 12) & 0b00000111)) {
99
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
100
case 0: op = rv_op_fmv_d_x; break;
101
}
102
break;
103
+ case 122:
104
+ switch (((inst >> 17) & 0b11111000) |
105
+ ((inst >> 12) & 0b00000111)) {
106
+ case 0: op = rv_op_fmv_h_x; break;
107
+ }
108
+ break;
109
case 123:
110
switch (((inst >> 17) & 0b11111000) |
111
((inst >> 12) & 0b00000111)) {
112
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
113
case 10: op = rv_op_vfwcvt_f_xu_v; break;
114
case 11: op = rv_op_vfwcvt_f_x_v; break;
115
case 12: op = rv_op_vfwcvt_f_f_v; break;
116
+ case 13: op = rv_op_vfwcvtbf16_f_f_v; break;
117
case 14: op = rv_op_vfwcvt_rtz_xu_f_v; break;
118
case 15: op = rv_op_vfwcvt_rtz_x_f_v; break;
119
case 16: op = rv_op_vfncvt_xu_f_w; break;
120
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
121
case 21: op = rv_op_vfncvt_rod_f_f_w; break;
122
case 22: op = rv_op_vfncvt_rtz_xu_f_w; break;
123
case 23: op = rv_op_vfncvt_rtz_x_f_w; break;
124
+ case 29: op = rv_op_vfncvtbf16_f_f_w; break;
125
}
126
break;
127
case 19:
128
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
129
case 52: op = rv_op_vfwadd_wv; break;
130
case 54: op = rv_op_vfwsub_wv; break;
131
case 56: op = rv_op_vfwmul_vv; break;
132
+ case 59: op = rv_op_vfwmaccbf16_vv; break;
133
case 60: op = rv_op_vfwmacc_vv; break;
134
case 61: op = rv_op_vfwnmacc_vv; break;
135
case 62: op = rv_op_vfwmsac_vv; break;
136
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
137
case 52: op = rv_op_vfwadd_wf; break;
138
case 54: op = rv_op_vfwsub_wf; break;
139
case 56: op = rv_op_vfwmul_vf; break;
140
+ case 59: op = rv_op_vfwmaccbf16_vf; break;
141
case 60: op = rv_op_vfwmacc_vf; break;
142
case 61: op = rv_op_vfwnmacc_vf; break;
143
case 62: op = rv_op_vfwmsac_vf; break;
144
--
45
--
145
2.40.1
46
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
'marchid' shouldn't be set to a different value as previously set for
3
This commit adds support for the Zvksed vector-crypto extension, which
4
named CPUs.
4
consists of the following instructions:
5
5
6
For all other CPUs it shouldn't be freely set either - the spec requires
6
* vsm4k.vi
7
that 'marchid' can't have the MSB (most significant bit) set and every
7
* vsm4r.[vv,vs]
8
other bit set to zero, i.e. 0x80000000 is an invalid 'marchid' value for
8
9
32 bit CPUs.
9
Translation functions are defined in
10
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
As with 'mimpid', setting a default value based on the current QEMU
11
`target/riscv/vcrypto_helper.c`.
12
version is not a good idea because it implies that the CPU
12
13
implementation changes from one QEMU version to the other. Named CPUs
13
Signed-off-by: Max Chou <max.chou@sifive.com>
14
should set 'marchid' to a meaningful value instead, and generic CPUs can
14
Reviewed-by: Frank Chang <frank.chang@sifive.com>
15
set to any valid value.
15
[lawrence.hunter@codethink.co.uk: Moved SM4 functions from
16
16
crypto_helper.c to vcrypto_helper.c]
17
For the 'veyron-v1' CPU this is the error thrown if 'marchid' is set to
17
[nazar.kazakov@codethink.co.uk: Added alignment checks, refactored code to
18
a different val:
18
use macros, and minor style changes]
19
19
Signed-off-by: Max Chou <max.chou@sifive.com>
20
$ ./build/qemu-system-riscv64 -M virt -nographic -cpu veyron-v1,marchid=0x80000000
20
Message-ID: <20230711165917.2629866-16-max.chou@sifive.com>
21
qemu-system-riscv64: can't apply global veyron-v1-riscv-cpu.marchid=0x80000000:
22
Unable to change veyron-v1-riscv-cpu marchid (0x8000000000010000)
23
24
And, for generics CPUs, this is the error when trying to set to an
25
invalid val:
26
27
$ ./build/qemu-system-riscv64 -M virt -nographic -cpu rv64,marchid=0x8000000000000000
28
qemu-system-riscv64: can't apply global rv64-riscv-cpu.marchid=0x8000000000000000:
29
Unable to set marchid with MSB (64) bit set and the remaining bits zero
30
31
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
32
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
33
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
34
Message-Id: <20230706101738.460804-6-dbarboza@ventanamicro.com>
35
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
36
---
22
---
37
target/riscv/cpu.c | 60 ++++++++++++++++++++++++++++++++++++++++------
23
target/riscv/cpu_cfg.h | 1 +
38
1 file changed, 53 insertions(+), 7 deletions(-)
24
target/riscv/helper.h | 4 +
39
25
target/riscv/insn32.decode | 5 +
26
target/riscv/cpu.c | 5 +-
27
target/riscv/vcrypto_helper.c | 127 +++++++++++++++++++++++
28
target/riscv/insn_trans/trans_rvvk.c.inc | 43 ++++++++
29
6 files changed, 184 insertions(+), 1 deletion(-)
30
31
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/cpu_cfg.h
34
+++ b/target/riscv/cpu_cfg.h
35
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
36
bool ext_zvkned;
37
bool ext_zvknha;
38
bool ext_zvknhb;
39
+ bool ext_zvksed;
40
bool ext_zvksh;
41
bool ext_zmmul;
42
bool ext_zvfbfmin;
43
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/helper.h
46
+++ b/target/riscv/helper.h
47
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
48
49
DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
50
DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
51
+
52
+DEF_HELPER_5(vsm4k_vi, void, ptr, ptr, i32, env, i32)
53
+DEF_HELPER_4(vsm4r_vv, void, ptr, ptr, env, i32)
54
+DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32)
55
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/riscv/insn32.decode
58
+++ b/target/riscv/insn32.decode
59
@@ -XXX,XX +XXX,XX @@ vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
60
# *** Zvkg vector crypto extension ***
61
vghsh_vv 101100 1 ..... ..... 010 ..... 1110111 @r_vm_1
62
vgmul_vv 101000 1 ..... 10001 010 ..... 1110111 @r2_vm_1
63
+
64
+# *** Zvksed vector crypto extension ***
65
+vsm4k_vi 100001 1 ..... ..... 010 ..... 1110111 @r_vm_1
66
+vsm4r_vv 101000 1 ..... 10000 010 ..... 1110111 @r2_vm_1
67
+vsm4r_vs 101001 1 ..... 10000 010 ..... 1110111 @r2_vm_1
40
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
41
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
42
--- a/target/riscv/cpu.c
70
--- a/target/riscv/cpu.c
43
+++ b/target/riscv/cpu.c
71
+++ b/target/riscv/cpu.c
72
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
73
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
74
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
75
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
76
+ ISA_EXT_DATA_ENTRY(zvksed, PRIV_VERSION_1_12_0, ext_zvksed),
77
ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh),
78
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
79
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
80
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
81
* in qemu
82
*/
83
if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
84
- cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
85
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed || cpu->cfg.ext_zvksh) &&
86
+ !cpu->cfg.ext_zve32f) {
87
error_setg(errp,
88
"Vector crypto extensions require V or Zve* extensions");
89
return;
90
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
91
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
92
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
93
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
94
+ DEFINE_PROP_BOOL("x-zvksed", RISCVCPU, cfg.ext_zvksed, false),
95
DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
96
97
DEFINE_PROP_END_OF_LIST(),
98
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/riscv/vcrypto_helper.c
101
+++ b/target/riscv/vcrypto_helper.c
44
@@ -XXX,XX +XXX,XX @@
102
@@ -XXX,XX +XXX,XX @@
45
#include "tcg/tcg.h"
103
#include "cpu.h"
46
104
#include "crypto/aes.h"
47
/* RISC-V CPU definitions */
105
#include "crypto/aes-round.h"
48
-
106
+#include "crypto/sm4.h"
49
-#define RISCV_CPU_MARCHID ((QEMU_VERSION_MAJOR << 16) | \
107
#include "exec/memop.h"
50
- (QEMU_VERSION_MINOR << 8) | \
108
#include "exec/exec-all.h"
51
- (QEMU_VERSION_MICRO))
109
#include "exec/helper-proto.h"
52
-
110
@@ -XXX,XX +XXX,XX @@ void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env,
53
static const char riscv_single_letter_exts[] = "IEMAFDQCPVH";
111
vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
54
112
env->vstart = 0;
55
struct isa_ext_data {
56
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_add_user_properties(Object *obj)
57
static Property riscv_cpu_properties[] = {
58
DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
59
60
- DEFINE_PROP_UINT64("marchid", RISCVCPU, cfg.marchid, RISCV_CPU_MARCHID),
61
-
62
#ifndef CONFIG_USER_ONLY
63
DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC),
64
#endif
65
@@ -XXX,XX +XXX,XX @@ static void cpu_get_mimpid(Object *obj, Visitor *v, const char *name,
66
visit_type_bool(v, name, &value, errp);
67
}
113
}
68
114
+
69
+static void cpu_set_marchid(Object *obj, Visitor *v, const char *name,
115
+void HELPER(vsm4k_vi)(void *vd, void *vs2, uint32_t uimm5, CPURISCVState *env,
70
+ void *opaque, Error **errp)
116
+ uint32_t desc)
71
+{
117
+{
72
+ bool dynamic_cpu = riscv_cpu_is_dynamic(obj);
118
+ const uint32_t egs = 4;
73
+ RISCVCPU *cpu = RISCV_CPU(obj);
119
+ uint32_t rnd = uimm5 & 0x7;
74
+ uint64_t prev_val = cpu->cfg.marchid;
120
+ uint32_t group_start = env->vstart / egs;
75
+ uint64_t value, invalid_val;
121
+ uint32_t group_end = env->vl / egs;
76
+ uint32_t mxlen = 0;
122
+ uint32_t esz = sizeof(uint32_t);
77
+
123
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
78
+ if (!visit_type_uint64(v, name, &value, errp)) {
124
+
79
+ return;
125
+ for (uint32_t i = group_start; i < group_end; ++i) {
80
+ }
126
+ uint32_t vstart = i * egs;
81
+
127
+ uint32_t vend = (i + 1) * egs;
82
+ if (!dynamic_cpu && prev_val != value) {
128
+ uint32_t rk[4] = {0};
83
+ error_setg(errp, "Unable to change %s marchid (0x%" PRIu64 ")",
129
+ uint32_t tmp[8] = {0};
84
+ object_get_typename(obj), prev_val);
130
+
85
+ return;
131
+ for (uint32_t j = vstart; j < vend; ++j) {
86
+ }
132
+ rk[j - vstart] = *((uint32_t *)vs2 + H4(j));
87
+
133
+ }
88
+ switch (riscv_cpu_mxl(&cpu->env)) {
134
+
89
+ case MXL_RV32:
135
+ for (uint32_t j = 0; j < egs; ++j) {
90
+ mxlen = 32;
136
+ tmp[j] = rk[j];
91
+ break;
137
+ }
92
+ case MXL_RV64:
138
+
93
+ case MXL_RV128:
139
+ for (uint32_t j = 0; j < egs; ++j) {
94
+ mxlen = 64;
140
+ uint32_t b, s;
95
+ break;
141
+ b = tmp[j + 1] ^ tmp[j + 2] ^ tmp[j + 3] ^ sm4_ck[rnd * 4 + j];
96
+ default:
142
+
97
+ g_assert_not_reached();
143
+ s = sm4_subword(b);
98
+ }
144
+
99
+
145
+ tmp[j + 4] = tmp[j] ^ (s ^ rol32(s, 13) ^ rol32(s, 23));
100
+ invalid_val = 1LL << (mxlen - 1);
146
+ }
101
+
147
+
102
+ if (value == invalid_val) {
148
+ for (uint32_t j = vstart; j < vend; ++j) {
103
+ error_setg(errp, "Unable to set marchid with MSB (%u) bit set "
149
+ *((uint32_t *)vd + H4(j)) = tmp[egs + (j - vstart)];
104
+ "and the remaining bits zero", mxlen);
150
+ }
105
+ return;
151
+ }
106
+ }
152
+
107
+
153
+ env->vstart = 0;
108
+ cpu->cfg.marchid = value;
154
+ /* set tail elements to 1s */
109
+}
155
+ vext_set_elems_1s(vd, vext_vta(desc), env->vl * esz, total_elems * esz);
110
+
156
+}
111
+static void cpu_get_marchid(Object *obj, Visitor *v, const char *name,
157
+
112
+ void *opaque, Error **errp)
158
+static void do_sm4_round(uint32_t *rk, uint32_t *buf)
113
+{
159
+{
114
+ bool value = RISCV_CPU(obj)->cfg.marchid;
160
+ const uint32_t egs = 4;
115
+
161
+ uint32_t s, b;
116
+ visit_type_bool(v, name, &value, errp);
162
+
117
+}
163
+ for (uint32_t j = egs; j < egs * 2; ++j) {
118
+
164
+ b = buf[j - 3] ^ buf[j - 2] ^ buf[j - 1] ^ rk[j - 4];
119
static void riscv_cpu_class_init(ObjectClass *c, void *data)
165
+
120
{
166
+ s = sm4_subword(b);
121
RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
167
+
122
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
168
+ buf[j] = buf[j - 4] ^ (s ^ rol32(s, 2) ^ rol32(s, 10) ^ rol32(s, 18) ^
123
object_class_property_add(c, "mimpid", "uint64", cpu_get_mimpid,
169
+ rol32(s, 24));
124
cpu_set_mimpid, NULL, NULL);
170
+ }
125
171
+}
126
+ object_class_property_add(c, "marchid", "uint64", cpu_get_marchid,
172
+
127
+ cpu_set_marchid, NULL, NULL);
173
+void HELPER(vsm4r_vv)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
128
+
174
+{
129
device_class_set_props(dc, riscv_cpu_properties);
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)
130
}
245
}
131
246
247
GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
248
+
249
+/*
250
+ * Zvksed
251
+ */
252
+
253
+#define ZVKSED_EGS 4
254
+
255
+static bool zvksed_check(DisasContext *s)
256
+{
257
+ int egw_bytes = ZVKSED_EGS << s->sew;
258
+ return s->cfg_ptr->ext_zvksed == true &&
259
+ require_rvv(s) &&
260
+ vext_check_isa_ill(s) &&
261
+ MAXSZ(s) >= egw_bytes &&
262
+ s->sew == MO_32;
263
+}
264
+
265
+static bool vsm4k_vi_check(DisasContext *s, arg_rmrr *a)
266
+{
267
+ return zvksed_check(s) &&
268
+ require_align(a->rd, s->lmul) &&
269
+ require_align(a->rs2, s->lmul);
270
+}
271
+
272
+GEN_VI_UNMASKED_TRANS(vsm4k_vi, vsm4k_vi_check, ZVKSED_EGS)
273
+
274
+static bool vsm4r_vv_check(DisasContext *s, arg_rmr *a)
275
+{
276
+ return zvksed_check(s) &&
277
+ require_align(a->rd, s->lmul) &&
278
+ require_align(a->rs2, s->lmul);
279
+}
280
+
281
+GEN_V_UNMASKED_TRANS(vsm4r_vv, vsm4r_vv_check, ZVKSED_EGS)
282
+
283
+static bool vsm4r_vs_check(DisasContext *s, arg_rmr *a)
284
+{
285
+ return zvksed_check(s) &&
286
+ !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) &&
287
+ require_align(a->rd, s->lmul);
288
+}
289
+
290
+GEN_V_UNMASKED_TRANS(vsm4r_vs, vsm4r_vs_check, ZVKSED_EGS)
132
--
291
--
133
2.40.1
292
2.41.0
diff view generated by jsdifflib
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
From: Rob Bradford <rbradford@rivosinc.com>
2
2
3
SXL is initialized as env->misa_mxl which is also the mxl value.
3
These are WARL fields - zero out the bits for unavailable counters and
4
So we can just remain it unchanged to keep it read-only.
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
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Tested by modifying OpenSBI to write max value to these CSRs and upon
7
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
9
subsequent read the appropriate number of bits for number of PMUs is
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
enabled and the TM bit is zero in mcountinhibit.
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
10
Message-Id: <20230603134236.15719-4-liweiwei@iscas.ac.cn>
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>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
17
---
13
target/riscv/csr.c | 4 ----
18
target/riscv/csr.c | 11 +++++++++--
14
1 file changed, 4 deletions(-)
19
1 file changed, 9 insertions(+), 2 deletions(-)
15
20
16
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
17
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/csr.c
23
--- a/target/riscv/csr.c
19
+++ b/target/riscv/csr.c
24
+++ b/target/riscv/csr.c
20
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
25
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
21
26
{
22
mstatus = (mstatus & ~mask) | (val & mask);
27
int cidx;
23
28
PMUCTRState *counter;
24
- if (xl > MXL_RV32) {
29
+ RISCVCPU *cpu = env_archcpu(env);
25
- /* SXL field is for now read only */
30
26
- mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
31
- env->mcountinhibit = val;
27
- }
32
+ /* WARL register - disable unavailable counters; TM bit is always 0 */
28
env->mstatus = mstatus;
33
+ env->mcountinhibit =
29
34
+ val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_IR);
30
/*
35
36
/* Check if any other counter is also monitoring cycles/instructions */
37
for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
38
@@ -XXX,XX +XXX,XX @@ static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
39
static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
40
target_ulong val)
41
{
42
- env->mcounteren = val;
43
+ RISCVCPU *cpu = env_archcpu(env);
44
+
45
+ /* WARL register - disable unavailable counters */
46
+ env->mcounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
47
+ COUNTEREN_IR);
48
return RISCV_EXCP_NONE;
49
}
50
31
--
51
--
32
2.40.1
52
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
Commit 7f0bdfb5bfc2 ("target/riscv/cpu.c: remove cfg setup from
3
RVA23 Profiles states:
4
riscv_cpu_init()") removed code that was enabling mmu, pmp, ext_ifencei
4
The RVA23 profiles are intended to be used for 64-bit application
5
and ext_icsr from riscv_cpu_init(), the init() function of
5
processors that will run rich OS stacks from standard binary OS
6
TYPE_RISCV_CPU, parent type of all RISC-V CPUss. This was done to force
6
distributions and with a substantial number of third-party binary user
7
CPUs to explictly enable all extensions and features it requires,
7
applications that will be supported over a considerable length of time
8
without any 'magic values' that were inherited by the parent type.
8
in the field.
9
9
10
This commit failed to make appropriate changes in the 'veyron-v1' CPU,
10
The chapter 4 of the unprivileged spec introduces the Zihintntl extension
11
added earlier by commit e1d084a8524a. The result is that the veyron-v1
11
and Zihintntl is a mandatory extension presented in RVA23 Profiles, whose
12
CPU has ext_ifencei, ext_icsr and pmp set to 'false', which is not the
12
purpose is to enable application and operating system portability across
13
case.
13
different implementations. Thus the DTS should contain the Zihintntl ISA
14
string in order to pass to software.
14
15
15
The reason why it took this long to notice (thanks LIU Zhiwei for
16
The unprivileged spec states:
16
reporting it) is because Linux doesn't mind 'ifencei' and 'icsr' being
17
Like any HINTs, these instructions may be freely ignored. Hence, although
17
absent in the 'riscv,isa' DT, implying that they're both present if the
18
they are described in terms of cache-based memory hierarchies, they do not
18
'i' extension is enabled. OpenSBI also doesn't error out or warns about
19
mandate the provision of caches.
19
the lack of 'pmp', it'll just not protect memory pages.
20
20
21
Fix it by setting them to 'true' in rv64_veyron_v1_cpu_init() like
21
These instructions are encoded with non-used opcode, e.g. ADD x0, x0, x2,
22
7f0bdfb5bfc2 already did with other CPUs.
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.
23
25
24
Reported-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
26
Reviewed-by: Frank Chang <frank.chang@sifive.com>
25
Fixes: 7f0bdfb5bfc2 ("target/riscv/cpu.c: remove cfg setup from riscv_cpu_init()")
26
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
27
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
27
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
28
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
28
Signed-off-by: Jason Chien <jason.chien@sifive.com>
29
Message-Id: <20230620152443.137079-1-dbarboza@ventanamicro.com>
29
Message-ID: <20230726074049.19505-2-jason.chien@sifive.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
31
---
31
---
32
target/riscv/cpu.c | 3 +++
32
target/riscv/cpu_cfg.h | 1 +
33
1 file changed, 3 insertions(+)
33
target/riscv/cpu.c | 2 ++
34
2 files changed, 3 insertions(+)
34
35
36
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/cpu_cfg.h
39
+++ b/target/riscv/cpu_cfg.h
40
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
41
bool ext_icbom;
42
bool ext_icboz;
43
bool ext_zicond;
44
+ bool ext_zihintntl;
45
bool ext_zihintpause;
46
bool ext_smstateen;
47
bool ext_sstc;
35
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
36
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/cpu.c
50
--- a/target/riscv/cpu.c
38
+++ b/target/riscv/cpu.c
51
+++ b/target/riscv/cpu.c
39
@@ -XXX,XX +XXX,XX @@ static void rv64_veyron_v1_cpu_init(Object *obj)
52
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
40
53
ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
41
/* Enable ISA extensions */
54
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
42
cpu->cfg.mmu = true;
55
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
43
+ cpu->cfg.ext_ifencei = true;
56
+ ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl),
44
+ cpu->cfg.ext_icsr = true;
57
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
45
+ cpu->cfg.pmp = true;
58
ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
46
cpu->cfg.ext_icbom = true;
59
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
47
cpu->cfg.cbom_blocksize = 64;
60
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
48
cpu->cfg.cboz_blocksize = 64;
61
DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
62
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
63
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
64
+ DEFINE_PROP_BOOL("Zihintntl", RISCVCPU, cfg.ext_zihintntl, true),
65
DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
66
DEFINE_PROP_BOOL("Zawrs", RISCVCPU, cfg.ext_zawrs, true),
67
DEFINE_PROP_BOOL("Zfa", RISCVCPU, cfg.ext_zfa, true),
49
--
68
--
50
2.40.1
69
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
2
3
We're now ready to update the multi-letter extensions status for KVM.
3
Commit a47842d ("riscv: Add support for the Zfa extension") implemented the zfa extension.
4
However, it has some typos for fleq.d and fltq.d. Both of them misused the fltq.s
5
helper function.
4
6
5
kvm_riscv_update_cpu_cfg_isa_ext() is called called during vcpu creation
7
Fixes: a47842d ("riscv: Add support for the Zfa extension")
6
time to verify which user options changes host defaults (via the 'user_set'
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
7
flag) and tries to write them back to KVM.
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
Failure to commit a change to KVM is only ignored in case KVM doesn't
11
Message-ID: <20230728003906.768-1-zhiwei_liu@linux.alibaba.com>
10
know about the extension (-EINVAL error code) and the user wanted to
11
disable the given extension. Otherwise we're going to abort the boot
12
process.
13
14
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-Id: <20230706101738.460804-19-dbarboza@ventanamicro.com>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
13
---
20
target/riscv/kvm.c | 27 +++++++++++++++++++++++++++
14
target/riscv/insn_trans/trans_rvzfa.c.inc | 4 ++--
21
1 file changed, 27 insertions(+)
15
1 file changed, 2 insertions(+), 2 deletions(-)
22
16
23
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
17
diff --git a/target/riscv/insn_trans/trans_rvzfa.c.inc b/target/riscv/insn_trans/trans_rvzfa.c.inc
24
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
25
--- a/target/riscv/kvm.c
19
--- a/target/riscv/insn_trans/trans_rvzfa.c.inc
26
+++ b/target/riscv/kvm.c
20
+++ b/target/riscv/insn_trans/trans_rvzfa.c.inc
27
@@ -XXX,XX +XXX,XX @@ static void kvm_cpu_set_multi_ext_cfg(Object *obj, Visitor *v,
21
@@ -XXX,XX +XXX,XX @@ bool trans_fleq_d(DisasContext *ctx, arg_fleq_d *a)
28
kvm_cpu_cfg_set(cpu, multi_ext_cfg, value);
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
}
29
}
30
30
@@ -XXX,XX +XXX,XX @@ bool trans_fltq_d(DisasContext *ctx, arg_fltq_d *a)
31
+static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
31
TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
32
+{
32
TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
33
+ CPURISCVState *env = &cpu->env;
33
34
+ uint64_t id, reg;
34
- gen_helper_fltq_s(dest, cpu_env, src1, src2);
35
+ int i, ret;
35
+ gen_helper_fltq_d(dest, cpu_env, src1, src2);
36
+
36
gen_set_gpr(ctx, a->rd, dest);
37
+ for (i = 0; i < ARRAY_SIZE(kvm_multi_ext_cfgs); i++) {
37
return true;
38
+ KVMCPUConfig *multi_ext_cfg = &kvm_multi_ext_cfgs[i];
39
+
40
+ if (!multi_ext_cfg->user_set) {
41
+ continue;
42
+ }
43
+
44
+ id = kvm_riscv_reg_id(env, KVM_REG_RISCV_ISA_EXT,
45
+ multi_ext_cfg->kvm_reg_id);
46
+ reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
47
+ ret = kvm_set_one_reg(cs, id, &reg);
48
+ if (ret != 0) {
49
+ error_report("Unable to %s extension %s in KVM, error %d",
50
+ reg ? "enable" : "disable",
51
+ multi_ext_cfg->name, ret);
52
+ exit(EXIT_FAILURE);
53
+ }
54
+ }
55
+}
56
+
57
static void kvm_riscv_add_cpu_user_properties(Object *cpu_obj)
58
{
59
int i;
60
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
61
}
62
63
kvm_riscv_update_cpu_misa_ext(cpu, cs);
64
+ kvm_riscv_update_cpu_cfg_isa_ext(cpu, cs);
65
66
return ret;
67
}
38
}
68
--
39
--
69
2.40.1
40
2.41.0
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
The privileged spec states:
3
When writing the upper mtime, we should keep the original lower mtime
4
For a memory access made to support VS-stage address translation (such as
4
whose value is given by cpu_riscv_read_rtc() instead of
5
to read/write a VS-level page table), permissions are checked as though
5
cpu_riscv_read_rtc_raw(). The same logic applies to writes to lower mtime.
6
for a load or store, not for the original access type. However, any
7
exception is always reported for the original access type (instruction,
8
load, or store/AMO).
9
10
The current implementation converts the access type to LOAD if implicit
11
G-stage translation fails which results in only reporting "Load guest-page
12
fault". This commit removes the convertion of access type, so the reported
13
exception conforms to the spec.
14
6
15
Signed-off-by: Jason Chien <jason.chien@sifive.com>
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
16
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-Id: <20230627074915.7686-1-jason.chien@sifive.com>
9
Message-ID: <20230728082502.26439-1-jason.chien@sifive.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
11
---
21
target/riscv/cpu_helper.c | 1 -
12
hw/intc/riscv_aclint.c | 5 +++--
22
1 file changed, 1 deletion(-)
13
1 file changed, 3 insertions(+), 2 deletions(-)
23
14
24
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
15
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
25
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu_helper.c
17
--- a/hw/intc/riscv_aclint.c
27
+++ b/target/riscv/cpu_helper.c
18
+++ b/hw/intc/riscv_aclint.c
28
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
19
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
29
if (ret == TRANSLATE_G_STAGE_FAIL) {
20
return;
30
first_stage_error = false;
21
} else if (addr == mtimer->time_base || addr == mtimer->time_base + 4) {
31
two_stage_indirect_error = true;
22
uint64_t rtc_r = cpu_riscv_read_rtc_raw(mtimer->timebase_freq);
32
- access_type = MMU_DATA_LOAD;
23
+ uint64_t rtc = cpu_riscv_read_rtc(mtimer);
33
}
24
34
25
if (addr == mtimer->time_base) {
35
qemu_log_mask(CPU_LOG_MMU,
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",
36
--
42
--
37
2.40.1
43
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
Following the same logic used with 'mvendorid' let's also restrict
3
The variables whose values are given by cpu_riscv_read_rtc() should be named
4
'mimpid' for named CPUs. Generic CPUs keep setting the value freely.
4
"rtc". The variables whose value are given by cpu_riscv_read_rtc_raw()
5
should be named "rtc_r".
5
6
6
Note that we're getting rid of the default RISCV_CPU_MARCHID value. The
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
7
reason is that this is not a good default since it's dynamic, changing
8
with with every QEMU version, regardless of whether the actual
9
implementation of the CPU changed from one QEMU version to the other.
10
Named CPU should set it to a meaningful value instead and generic CPUs
11
can set whatever they want.
12
13
This is the error thrown for an invalid 'mimpid' value for the veyron-v1
14
CPU:
15
16
$ ./qemu-system-riscv64 -M virt -nographic -cpu veyron-v1,mimpid=2
17
qemu-system-riscv64: can't apply global veyron-v1-riscv-cpu.mimpid=2:
18
Unable to change veyron-v1-riscv-cpu mimpid (0x111)
19
20
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
21
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
22
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Message-Id: <20230706101738.460804-5-dbarboza@ventanamicro.com>
9
Message-ID: <20230728082502.26439-2-jason.chien@sifive.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
11
---
26
target/riscv/cpu.c | 34 ++++++++++++++++++++++++++++++++--
12
hw/intc/riscv_aclint.c | 6 +++---
27
1 file changed, 32 insertions(+), 2 deletions(-)
13
1 file changed, 3 insertions(+), 3 deletions(-)
28
14
29
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
30
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/cpu.c
17
--- a/hw/intc/riscv_aclint.c
32
+++ b/target/riscv/cpu.c
18
+++ b/hw/intc/riscv_aclint.c
33
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
34
#define RISCV_CPU_MARCHID ((QEMU_VERSION_MAJOR << 16) | \
20
uint64_t next;
35
(QEMU_VERSION_MINOR << 8) | \
21
uint64_t diff;
36
(QEMU_VERSION_MICRO))
22
37
-#define RISCV_CPU_MIMPID RISCV_CPU_MARCHID
23
- uint64_t rtc_r = cpu_riscv_read_rtc(mtimer);
38
24
+ uint64_t rtc = cpu_riscv_read_rtc(mtimer);
39
static const char riscv_single_letter_exts[] = "IEMAFDQCPVH";
25
40
26
/* Compute the relative hartid w.r.t the socket */
41
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = {
27
hartid = hartid - mtimer->hartid_base;
42
DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
28
43
29
mtimer->timecmp[hartid] = value;
44
DEFINE_PROP_UINT64("marchid", RISCVCPU, cfg.marchid, RISCV_CPU_MARCHID),
30
- if (mtimer->timecmp[hartid] <= rtc_r) {
45
- DEFINE_PROP_UINT64("mimpid", RISCVCPU, cfg.mimpid, RISCV_CPU_MIMPID),
31
+ if (mtimer->timecmp[hartid] <= rtc) {
46
32
/*
47
#ifndef CONFIG_USER_ONLY
33
* If we're setting an MTIMECMP value in the "past",
48
DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC),
34
* immediately raise the timer interrupt
49
@@ -XXX,XX +XXX,XX @@ static void cpu_get_mvendorid(Object *obj, Visitor *v, const char *name,
35
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
50
visit_type_bool(v, name, &value, errp);
36
51
}
37
/* otherwise, set up the future timer interrupt */
52
38
qemu_irq_lower(mtimer->timer_irqs[hartid]);
53
+static void cpu_set_mimpid(Object *obj, Visitor *v, const char *name,
39
- diff = mtimer->timecmp[hartid] - rtc_r;
54
+ void *opaque, Error **errp)
40
+ diff = mtimer->timecmp[hartid] - rtc;
55
+{
41
/* back to ns (note args switched in muldiv64) */
56
+ bool dynamic_cpu = riscv_cpu_is_dynamic(obj);
42
uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
57
+ RISCVCPU *cpu = RISCV_CPU(obj);
58
+ uint64_t prev_val = cpu->cfg.mimpid;
59
+ uint64_t value;
60
+
61
+ if (!visit_type_uint64(v, name, &value, errp)) {
62
+ return;
63
+ }
64
+
65
+ if (!dynamic_cpu && prev_val != value) {
66
+ error_setg(errp, "Unable to change %s mimpid (0x%" PRIu64 ")",
67
+ object_get_typename(obj), prev_val);
68
+ return;
69
+ }
70
+
71
+ cpu->cfg.mimpid = value;
72
+}
73
+
74
+static void cpu_get_mimpid(Object *obj, Visitor *v, const char *name,
75
+ void *opaque, Error **errp)
76
+{
77
+ bool value = RISCV_CPU(obj)->cfg.mimpid;
78
+
79
+ visit_type_bool(v, name, &value, errp);
80
+}
81
+
82
static void riscv_cpu_class_init(ObjectClass *c, void *data)
83
{
84
RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
85
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
86
object_class_property_add(c, "mvendorid", "uint32", cpu_get_mvendorid,
87
cpu_set_mvendorid, NULL, NULL);
88
89
+ object_class_property_add(c, "mimpid", "uint64", cpu_get_mimpid,
90
+ cpu_set_mimpid, NULL, NULL);
91
+
92
device_class_set_props(dc, riscv_cpu_properties);
93
}
94
43
95
--
44
--
96
2.40.1
45
2.41.0
diff view generated by jsdifflib
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
2
3
Disassemble function(plugin_disas, target_disas, monitor_disas) will
3
We should not use types dependend on host arch for target_ucontext.
4
always call set_disas_info before disassembling instructions.
4
This bug is found when run rv32 applications.
5
6
plugin_disas and target_disas will always be called under a TB, which
7
has the same XLEN.
8
9
We can't ensure that monitor_disas will always be called under a TB,
10
but current XLEN will still be a better choice, thus we can ensure at
11
least the disassemble of the nearest one TB is right.
12
5
13
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
6
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
16
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
17
Message-Id: <20230612111034.3955227-2-christoph.muellner@vrull.eu>
10
Message-ID: <20230811055438.1945-1-zhiwei_liu@linux.alibaba.com>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
12
---
20
target/riscv/cpu.c | 3 ++-
13
linux-user/riscv/signal.c | 4 ++--
21
1 file changed, 2 insertions(+), 1 deletion(-)
14
1 file changed, 2 insertions(+), 2 deletions(-)
22
15
23
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
16
diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c
24
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
25
--- a/target/riscv/cpu.c
18
--- a/linux-user/riscv/signal.c
26
+++ b/target/riscv/cpu.c
19
+++ b/linux-user/riscv/signal.c
27
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ struct target_sigcontext {
28
static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
21
}; /* cf. riscv-linux:arch/riscv/include/uapi/asm/ptrace.h */
29
{
22
30
RISCVCPU *cpu = RISCV_CPU(s);
23
struct target_ucontext {
31
+ CPURISCVState *env = &cpu->env;
24
- unsigned long uc_flags;
32
info->target_info = &cpu->cfg;
25
- struct target_ucontext *uc_link;
33
26
+ abi_ulong uc_flags;
34
- switch (riscv_cpu_mxl(&cpu->env)) {
27
+ abi_ptr uc_link;
35
+ switch (env->xl) {
28
target_stack_t uc_stack;
36
case MXL_RV32:
29
target_sigset_t uc_sigmask;
37
info->print_insn = print_insn_riscv32;
30
uint8_t __unused[1024 / 8 - sizeof(target_sigset_t)];
38
break;
39
--
31
--
40
2.40.1
32
2.41.0
41
33
42
34
diff view generated by jsdifflib
Deleted patch
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
2
1
3
In order to enable vendor disassembler support, we need to
4
move types and constants into a header file so that other
5
compilation units can use them as well.
6
7
This patch does not introduce any functional changes.
8
9
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
12
Message-Id: <20230612111034.3955227-4-christoph.muellner@vrull.eu>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
disas/riscv.h | 282 ++++++++++++++++++++++++++++++++++++++++++++++++++
16
disas/riscv.c | 270 +----------------------------------------------
17
2 files changed, 283 insertions(+), 269 deletions(-)
18
create mode 100644 disas/riscv.h
19
20
diff --git a/disas/riscv.h b/disas/riscv.h
21
new file mode 100644
22
index XXXXXXX..XXXXXXX
23
--- /dev/null
24
+++ b/disas/riscv.h
25
@@ -XXX,XX +XXX,XX @@
26
+/*
27
+ * QEMU disassembler -- RISC-V specific header.
28
+ *
29
+ * SPDX-License-Identifier: GPL-2.0-or-later
30
+ */
31
+
32
+#ifndef DISAS_RISCV_H
33
+#define DISAS_RISCV_H
34
+
35
+#include "qemu/osdep.h"
36
+#include "target/riscv/cpu_cfg.h"
37
+
38
+/* types */
39
+
40
+typedef uint64_t rv_inst;
41
+typedef uint16_t rv_opcode;
42
+
43
+/* enums */
44
+
45
+typedef enum {
46
+ rv32,
47
+ rv64,
48
+ rv128
49
+} rv_isa;
50
+
51
+typedef enum {
52
+ rv_rm_rne = 0,
53
+ rv_rm_rtz = 1,
54
+ rv_rm_rdn = 2,
55
+ rv_rm_rup = 3,
56
+ rv_rm_rmm = 4,
57
+ rv_rm_dyn = 7,
58
+} rv_rm;
59
+
60
+typedef enum {
61
+ rv_fence_i = 8,
62
+ rv_fence_o = 4,
63
+ rv_fence_r = 2,
64
+ rv_fence_w = 1,
65
+} rv_fence;
66
+
67
+typedef enum {
68
+ rv_ireg_zero,
69
+ rv_ireg_ra,
70
+ rv_ireg_sp,
71
+ rv_ireg_gp,
72
+ rv_ireg_tp,
73
+ rv_ireg_t0,
74
+ rv_ireg_t1,
75
+ rv_ireg_t2,
76
+ rv_ireg_s0,
77
+ rv_ireg_s1,
78
+ rv_ireg_a0,
79
+ rv_ireg_a1,
80
+ rv_ireg_a2,
81
+ rv_ireg_a3,
82
+ rv_ireg_a4,
83
+ rv_ireg_a5,
84
+ rv_ireg_a6,
85
+ rv_ireg_a7,
86
+ rv_ireg_s2,
87
+ rv_ireg_s3,
88
+ rv_ireg_s4,
89
+ rv_ireg_s5,
90
+ rv_ireg_s6,
91
+ rv_ireg_s7,
92
+ rv_ireg_s8,
93
+ rv_ireg_s9,
94
+ rv_ireg_s10,
95
+ rv_ireg_s11,
96
+ rv_ireg_t3,
97
+ rv_ireg_t4,
98
+ rv_ireg_t5,
99
+ rv_ireg_t6,
100
+} rv_ireg;
101
+
102
+typedef enum {
103
+ rvc_end,
104
+ rvc_rd_eq_ra,
105
+ rvc_rd_eq_x0,
106
+ rvc_rs1_eq_x0,
107
+ rvc_rs2_eq_x0,
108
+ rvc_rs2_eq_rs1,
109
+ rvc_rs1_eq_ra,
110
+ rvc_imm_eq_zero,
111
+ rvc_imm_eq_n1,
112
+ rvc_imm_eq_p1,
113
+ rvc_csr_eq_0x001,
114
+ rvc_csr_eq_0x002,
115
+ rvc_csr_eq_0x003,
116
+ rvc_csr_eq_0xc00,
117
+ rvc_csr_eq_0xc01,
118
+ rvc_csr_eq_0xc02,
119
+ rvc_csr_eq_0xc80,
120
+ rvc_csr_eq_0xc81,
121
+ rvc_csr_eq_0xc82,
122
+} rvc_constraint;
123
+
124
+typedef enum {
125
+ rv_codec_illegal,
126
+ rv_codec_none,
127
+ rv_codec_u,
128
+ rv_codec_uj,
129
+ rv_codec_i,
130
+ rv_codec_i_sh5,
131
+ rv_codec_i_sh6,
132
+ rv_codec_i_sh7,
133
+ rv_codec_i_csr,
134
+ rv_codec_s,
135
+ rv_codec_sb,
136
+ rv_codec_r,
137
+ rv_codec_r_m,
138
+ rv_codec_r4_m,
139
+ rv_codec_r_a,
140
+ rv_codec_r_l,
141
+ rv_codec_r_f,
142
+ rv_codec_cb,
143
+ rv_codec_cb_imm,
144
+ rv_codec_cb_sh5,
145
+ rv_codec_cb_sh6,
146
+ rv_codec_ci,
147
+ rv_codec_ci_sh5,
148
+ rv_codec_ci_sh6,
149
+ rv_codec_ci_16sp,
150
+ rv_codec_ci_lwsp,
151
+ rv_codec_ci_ldsp,
152
+ rv_codec_ci_lqsp,
153
+ rv_codec_ci_li,
154
+ rv_codec_ci_lui,
155
+ rv_codec_ci_none,
156
+ rv_codec_ciw_4spn,
157
+ rv_codec_cj,
158
+ rv_codec_cj_jal,
159
+ rv_codec_cl_lw,
160
+ rv_codec_cl_ld,
161
+ rv_codec_cl_lq,
162
+ rv_codec_cr,
163
+ rv_codec_cr_mv,
164
+ rv_codec_cr_jalr,
165
+ rv_codec_cr_jr,
166
+ rv_codec_cs,
167
+ rv_codec_cs_sw,
168
+ rv_codec_cs_sd,
169
+ rv_codec_cs_sq,
170
+ rv_codec_css_swsp,
171
+ rv_codec_css_sdsp,
172
+ rv_codec_css_sqsp,
173
+ rv_codec_k_bs,
174
+ rv_codec_k_rnum,
175
+ rv_codec_v_r,
176
+ rv_codec_v_ldst,
177
+ rv_codec_v_i,
178
+ rv_codec_vsetvli,
179
+ rv_codec_vsetivli,
180
+ rv_codec_zcb_ext,
181
+ rv_codec_zcb_mul,
182
+ rv_codec_zcb_lb,
183
+ rv_codec_zcb_lh,
184
+ rv_codec_zcmp_cm_pushpop,
185
+ rv_codec_zcmp_cm_mv,
186
+ rv_codec_zcmt_jt,
187
+} rv_codec;
188
+
189
+/* structures */
190
+
191
+typedef struct {
192
+ RISCVCPUConfig *cfg;
193
+ uint64_t pc;
194
+ uint64_t inst;
195
+ int32_t imm;
196
+ uint16_t op;
197
+ uint8_t codec;
198
+ uint8_t rd;
199
+ uint8_t rs1;
200
+ uint8_t rs2;
201
+ uint8_t rs3;
202
+ uint8_t rm;
203
+ uint8_t pred;
204
+ uint8_t succ;
205
+ uint8_t aq;
206
+ uint8_t rl;
207
+ uint8_t bs;
208
+ uint8_t rnum;
209
+ uint8_t vm;
210
+ uint32_t vzimm;
211
+ uint8_t rlist;
212
+} rv_decode;
213
+
214
+typedef struct {
215
+ const int op;
216
+ const rvc_constraint *constraints;
217
+} rv_comp_data;
218
+
219
+enum {
220
+ rvcd_imm_nz = 0x1
221
+};
222
+
223
+typedef struct {
224
+ const char * const name;
225
+ const rv_codec codec;
226
+ const char * const format;
227
+ const rv_comp_data *pseudo;
228
+ const short decomp_rv32;
229
+ const short decomp_rv64;
230
+ const short decomp_rv128;
231
+ const short decomp_data;
232
+} rv_opcode_data;
233
+
234
+/* instruction formats */
235
+
236
+#define rv_fmt_none "O\t"
237
+#define rv_fmt_rs1 "O\t1"
238
+#define rv_fmt_offset "O\to"
239
+#define rv_fmt_pred_succ "O\tp,s"
240
+#define rv_fmt_rs1_rs2 "O\t1,2"
241
+#define rv_fmt_rd_imm "O\t0,i"
242
+#define rv_fmt_rd_offset "O\t0,o"
243
+#define rv_fmt_rd_rs1_rs2 "O\t0,1,2"
244
+#define rv_fmt_frd_rs1 "O\t3,1"
245
+#define rv_fmt_frd_frs1 "O\t3,4"
246
+#define rv_fmt_rd_frs1 "O\t0,4"
247
+#define rv_fmt_rd_frs1_frs2 "O\t0,4,5"
248
+#define rv_fmt_frd_frs1_frs2 "O\t3,4,5"
249
+#define rv_fmt_rm_frd_frs1 "O\tr,3,4"
250
+#define rv_fmt_rm_frd_rs1 "O\tr,3,1"
251
+#define rv_fmt_rm_rd_frs1 "O\tr,0,4"
252
+#define rv_fmt_rm_frd_frs1_frs2 "O\tr,3,4,5"
253
+#define rv_fmt_rm_frd_frs1_frs2_frs3 "O\tr,3,4,5,6"
254
+#define rv_fmt_rd_rs1_imm "O\t0,1,i"
255
+#define rv_fmt_rd_rs1_offset "O\t0,1,i"
256
+#define rv_fmt_rd_offset_rs1 "O\t0,i(1)"
257
+#define rv_fmt_frd_offset_rs1 "O\t3,i(1)"
258
+#define rv_fmt_rd_csr_rs1 "O\t0,c,1"
259
+#define rv_fmt_rd_csr_zimm "O\t0,c,7"
260
+#define rv_fmt_rs2_offset_rs1 "O\t2,i(1)"
261
+#define rv_fmt_frs2_offset_rs1 "O\t5,i(1)"
262
+#define rv_fmt_rs1_rs2_offset "O\t1,2,o"
263
+#define rv_fmt_rs2_rs1_offset "O\t2,1,o"
264
+#define rv_fmt_aqrl_rd_rs2_rs1 "OAR\t0,2,(1)"
265
+#define rv_fmt_aqrl_rd_rs1 "OAR\t0,(1)"
266
+#define rv_fmt_rd "O\t0"
267
+#define rv_fmt_rd_zimm "O\t0,7"
268
+#define rv_fmt_rd_rs1 "O\t0,1"
269
+#define rv_fmt_rd_rs2 "O\t0,2"
270
+#define rv_fmt_rs1_offset "O\t1,o"
271
+#define rv_fmt_rs2_offset "O\t2,o"
272
+#define rv_fmt_rs1_rs2_bs "O\t1,2,b"
273
+#define rv_fmt_rd_rs1_rnum "O\t0,1,n"
274
+#define rv_fmt_ldst_vd_rs1_vm "O\tD,(1)m"
275
+#define rv_fmt_ldst_vd_rs1_rs2_vm "O\tD,(1),2m"
276
+#define rv_fmt_ldst_vd_rs1_vs2_vm "O\tD,(1),Fm"
277
+#define rv_fmt_vd_vs2_vs1 "O\tD,F,E"
278
+#define rv_fmt_vd_vs2_vs1_vl "O\tD,F,El"
279
+#define rv_fmt_vd_vs2_vs1_vm "O\tD,F,Em"
280
+#define rv_fmt_vd_vs2_rs1_vl "O\tD,F,1l"
281
+#define rv_fmt_vd_vs2_fs1_vl "O\tD,F,4l"
282
+#define rv_fmt_vd_vs2_rs1_vm "O\tD,F,1m"
283
+#define rv_fmt_vd_vs2_fs1_vm "O\tD,F,4m"
284
+#define rv_fmt_vd_vs2_imm_vl "O\tD,F,il"
285
+#define rv_fmt_vd_vs2_imm_vm "O\tD,F,im"
286
+#define rv_fmt_vd_vs2_uimm_vm "O\tD,F,um"
287
+#define rv_fmt_vd_vs1_vs2_vm "O\tD,E,Fm"
288
+#define rv_fmt_vd_rs1_vs2_vm "O\tD,1,Fm"
289
+#define rv_fmt_vd_fs1_vs2_vm "O\tD,4,Fm"
290
+#define rv_fmt_vd_vs1 "O\tD,E"
291
+#define rv_fmt_vd_rs1 "O\tD,1"
292
+#define rv_fmt_vd_fs1 "O\tD,4"
293
+#define rv_fmt_vd_imm "O\tD,i"
294
+#define rv_fmt_vd_vs2 "O\tD,F"
295
+#define rv_fmt_vd_vs2_vm "O\tD,Fm"
296
+#define rv_fmt_rd_vs2_vm "O\t0,Fm"
297
+#define rv_fmt_rd_vs2 "O\t0,F"
298
+#define rv_fmt_fd_vs2 "O\t3,F"
299
+#define rv_fmt_vd_vm "O\tDm"
300
+#define rv_fmt_vsetvli "O\t0,1,v"
301
+#define rv_fmt_vsetivli "O\t0,u,v"
302
+#define rv_fmt_rs1_rs2_zce_ldst "O\t2,i(1)"
303
+#define rv_fmt_push_rlist "O\tx,-i"
304
+#define rv_fmt_pop_rlist "O\tx,i"
305
+#define rv_fmt_zcmt_index "O\ti"
306
+
307
+#endif /* DISAS_RISCV_H */
308
diff --git a/disas/riscv.c b/disas/riscv.c
309
index XXXXXXX..XXXXXXX 100644
310
--- a/disas/riscv.c
311
+++ b/disas/riscv.c
312
@@ -XXX,XX +XXX,XX @@
313
#include "qemu/osdep.h"
314
#include "disas/dis-asm.h"
315
#include "target/riscv/cpu_cfg.h"
316
-
317
-/* types */
318
-
319
-typedef uint64_t rv_inst;
320
-typedef uint16_t rv_opcode;
321
-
322
-/* enums */
323
-
324
-typedef enum {
325
- rv32,
326
- rv64,
327
- rv128
328
-} rv_isa;
329
-
330
-typedef enum {
331
- rv_rm_rne = 0,
332
- rv_rm_rtz = 1,
333
- rv_rm_rdn = 2,
334
- rv_rm_rup = 3,
335
- rv_rm_rmm = 4,
336
- rv_rm_dyn = 7,
337
-} rv_rm;
338
-
339
-typedef enum {
340
- rv_fence_i = 8,
341
- rv_fence_o = 4,
342
- rv_fence_r = 2,
343
- rv_fence_w = 1,
344
-} rv_fence;
345
-
346
-typedef enum {
347
- rv_ireg_zero,
348
- rv_ireg_ra,
349
- rv_ireg_sp,
350
- rv_ireg_gp,
351
- rv_ireg_tp,
352
- rv_ireg_t0,
353
- rv_ireg_t1,
354
- rv_ireg_t2,
355
- rv_ireg_s0,
356
- rv_ireg_s1,
357
- rv_ireg_a0,
358
- rv_ireg_a1,
359
- rv_ireg_a2,
360
- rv_ireg_a3,
361
- rv_ireg_a4,
362
- rv_ireg_a5,
363
- rv_ireg_a6,
364
- rv_ireg_a7,
365
- rv_ireg_s2,
366
- rv_ireg_s3,
367
- rv_ireg_s4,
368
- rv_ireg_s5,
369
- rv_ireg_s6,
370
- rv_ireg_s7,
371
- rv_ireg_s8,
372
- rv_ireg_s9,
373
- rv_ireg_s10,
374
- rv_ireg_s11,
375
- rv_ireg_t3,
376
- rv_ireg_t4,
377
- rv_ireg_t5,
378
- rv_ireg_t6,
379
-} rv_ireg;
380
-
381
-typedef enum {
382
- rvc_end,
383
- rvc_rd_eq_ra,
384
- rvc_rd_eq_x0,
385
- rvc_rs1_eq_x0,
386
- rvc_rs2_eq_x0,
387
- rvc_rs2_eq_rs1,
388
- rvc_rs1_eq_ra,
389
- rvc_imm_eq_zero,
390
- rvc_imm_eq_n1,
391
- rvc_imm_eq_p1,
392
- rvc_csr_eq_0x001,
393
- rvc_csr_eq_0x002,
394
- rvc_csr_eq_0x003,
395
- rvc_csr_eq_0xc00,
396
- rvc_csr_eq_0xc01,
397
- rvc_csr_eq_0xc02,
398
- rvc_csr_eq_0xc80,
399
- rvc_csr_eq_0xc81,
400
- rvc_csr_eq_0xc82,
401
-} rvc_constraint;
402
-
403
-typedef enum {
404
- rv_codec_illegal,
405
- rv_codec_none,
406
- rv_codec_u,
407
- rv_codec_uj,
408
- rv_codec_i,
409
- rv_codec_i_sh5,
410
- rv_codec_i_sh6,
411
- rv_codec_i_sh7,
412
- rv_codec_i_csr,
413
- rv_codec_s,
414
- rv_codec_sb,
415
- rv_codec_r,
416
- rv_codec_r_m,
417
- rv_codec_r4_m,
418
- rv_codec_r_a,
419
- rv_codec_r_l,
420
- rv_codec_r_f,
421
- rv_codec_cb,
422
- rv_codec_cb_imm,
423
- rv_codec_cb_sh5,
424
- rv_codec_cb_sh6,
425
- rv_codec_ci,
426
- rv_codec_ci_sh5,
427
- rv_codec_ci_sh6,
428
- rv_codec_ci_16sp,
429
- rv_codec_ci_lwsp,
430
- rv_codec_ci_ldsp,
431
- rv_codec_ci_lqsp,
432
- rv_codec_ci_li,
433
- rv_codec_ci_lui,
434
- rv_codec_ci_none,
435
- rv_codec_ciw_4spn,
436
- rv_codec_cj,
437
- rv_codec_cj_jal,
438
- rv_codec_cl_lw,
439
- rv_codec_cl_ld,
440
- rv_codec_cl_lq,
441
- rv_codec_cr,
442
- rv_codec_cr_mv,
443
- rv_codec_cr_jalr,
444
- rv_codec_cr_jr,
445
- rv_codec_cs,
446
- rv_codec_cs_sw,
447
- rv_codec_cs_sd,
448
- rv_codec_cs_sq,
449
- rv_codec_css_swsp,
450
- rv_codec_css_sdsp,
451
- rv_codec_css_sqsp,
452
- rv_codec_k_bs,
453
- rv_codec_k_rnum,
454
- rv_codec_v_r,
455
- rv_codec_v_ldst,
456
- rv_codec_v_i,
457
- rv_codec_vsetvli,
458
- rv_codec_vsetivli,
459
- rv_codec_zcb_ext,
460
- rv_codec_zcb_mul,
461
- rv_codec_zcb_lb,
462
- rv_codec_zcb_lh,
463
- rv_codec_zcmp_cm_pushpop,
464
- rv_codec_zcmp_cm_mv,
465
- rv_codec_zcmt_jt,
466
-} rv_codec;
467
+#include "disas/riscv.h"
468
469
typedef enum {
470
rv_op_illegal = 0,
471
@@ -XXX,XX +XXX,XX @@ typedef enum {
472
rv_op_czero_nez = 790,
473
} rv_op;
474
475
-/* structures */
476
-
477
-typedef struct {
478
- RISCVCPUConfig *cfg;
479
- uint64_t pc;
480
- uint64_t inst;
481
- int32_t imm;
482
- uint16_t op;
483
- uint8_t codec;
484
- uint8_t rd;
485
- uint8_t rs1;
486
- uint8_t rs2;
487
- uint8_t rs3;
488
- uint8_t rm;
489
- uint8_t pred;
490
- uint8_t succ;
491
- uint8_t aq;
492
- uint8_t rl;
493
- uint8_t bs;
494
- uint8_t rnum;
495
- uint8_t vm;
496
- uint32_t vzimm;
497
- uint8_t rlist;
498
-} rv_decode;
499
-
500
-typedef struct {
501
- const int op;
502
- const rvc_constraint *constraints;
503
-} rv_comp_data;
504
-
505
-enum {
506
- rvcd_imm_nz = 0x1
507
-};
508
-
509
-typedef struct {
510
- const char * const name;
511
- const rv_codec codec;
512
- const char * const format;
513
- const rv_comp_data *pseudo;
514
- const short decomp_rv32;
515
- const short decomp_rv64;
516
- const short decomp_rv128;
517
- const short decomp_data;
518
-} rv_opcode_data;
519
-
520
/* register names */
521
522
static const char rv_ireg_name_sym[32][5] = {
523
@@ -XXX,XX +XXX,XX @@ static const char rv_vreg_name_sym[32][4] = {
524
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
525
};
526
527
-/* instruction formats */
528
-
529
-#define rv_fmt_none "O\t"
530
-#define rv_fmt_rs1 "O\t1"
531
-#define rv_fmt_offset "O\to"
532
-#define rv_fmt_pred_succ "O\tp,s"
533
-#define rv_fmt_rs1_rs2 "O\t1,2"
534
-#define rv_fmt_rd_imm "O\t0,i"
535
-#define rv_fmt_rd_offset "O\t0,o"
536
-#define rv_fmt_rd_rs1_rs2 "O\t0,1,2"
537
-#define rv_fmt_frd_rs1 "O\t3,1"
538
-#define rv_fmt_frd_frs1 "O\t3,4"
539
-#define rv_fmt_rd_frs1 "O\t0,4"
540
-#define rv_fmt_rd_frs1_frs2 "O\t0,4,5"
541
-#define rv_fmt_frd_frs1_frs2 "O\t3,4,5"
542
-#define rv_fmt_rm_frd_frs1 "O\tr,3,4"
543
-#define rv_fmt_rm_frd_rs1 "O\tr,3,1"
544
-#define rv_fmt_rm_rd_frs1 "O\tr,0,4"
545
-#define rv_fmt_rm_frd_frs1_frs2 "O\tr,3,4,5"
546
-#define rv_fmt_rm_frd_frs1_frs2_frs3 "O\tr,3,4,5,6"
547
-#define rv_fmt_rd_rs1_imm "O\t0,1,i"
548
-#define rv_fmt_rd_rs1_offset "O\t0,1,i"
549
-#define rv_fmt_rd_offset_rs1 "O\t0,i(1)"
550
-#define rv_fmt_frd_offset_rs1 "O\t3,i(1)"
551
-#define rv_fmt_rd_csr_rs1 "O\t0,c,1"
552
-#define rv_fmt_rd_csr_zimm "O\t0,c,7"
553
-#define rv_fmt_rs2_offset_rs1 "O\t2,i(1)"
554
-#define rv_fmt_frs2_offset_rs1 "O\t5,i(1)"
555
-#define rv_fmt_rs1_rs2_offset "O\t1,2,o"
556
-#define rv_fmt_rs2_rs1_offset "O\t2,1,o"
557
-#define rv_fmt_aqrl_rd_rs2_rs1 "OAR\t0,2,(1)"
558
-#define rv_fmt_aqrl_rd_rs1 "OAR\t0,(1)"
559
-#define rv_fmt_rd "O\t0"
560
-#define rv_fmt_rd_zimm "O\t0,7"
561
-#define rv_fmt_rd_rs1 "O\t0,1"
562
-#define rv_fmt_rd_rs2 "O\t0,2"
563
-#define rv_fmt_rs1_offset "O\t1,o"
564
-#define rv_fmt_rs2_offset "O\t2,o"
565
-#define rv_fmt_rs1_rs2_bs "O\t1,2,b"
566
-#define rv_fmt_rd_rs1_rnum "O\t0,1,n"
567
-#define rv_fmt_ldst_vd_rs1_vm "O\tD,(1)m"
568
-#define rv_fmt_ldst_vd_rs1_rs2_vm "O\tD,(1),2m"
569
-#define rv_fmt_ldst_vd_rs1_vs2_vm "O\tD,(1),Fm"
570
-#define rv_fmt_vd_vs2_vs1 "O\tD,F,E"
571
-#define rv_fmt_vd_vs2_vs1_vl "O\tD,F,El"
572
-#define rv_fmt_vd_vs2_vs1_vm "O\tD,F,Em"
573
-#define rv_fmt_vd_vs2_rs1_vl "O\tD,F,1l"
574
-#define rv_fmt_vd_vs2_fs1_vl "O\tD,F,4l"
575
-#define rv_fmt_vd_vs2_rs1_vm "O\tD,F,1m"
576
-#define rv_fmt_vd_vs2_fs1_vm "O\tD,F,4m"
577
-#define rv_fmt_vd_vs2_imm_vl "O\tD,F,il"
578
-#define rv_fmt_vd_vs2_imm_vm "O\tD,F,im"
579
-#define rv_fmt_vd_vs2_uimm_vm "O\tD,F,um"
580
-#define rv_fmt_vd_vs1_vs2_vm "O\tD,E,Fm"
581
-#define rv_fmt_vd_rs1_vs2_vm "O\tD,1,Fm"
582
-#define rv_fmt_vd_fs1_vs2_vm "O\tD,4,Fm"
583
-#define rv_fmt_vd_vs1 "O\tD,E"
584
-#define rv_fmt_vd_rs1 "O\tD,1"
585
-#define rv_fmt_vd_fs1 "O\tD,4"
586
-#define rv_fmt_vd_imm "O\tD,i"
587
-#define rv_fmt_vd_vs2 "O\tD,F"
588
-#define rv_fmt_vd_vs2_vm "O\tD,Fm"
589
-#define rv_fmt_rd_vs2_vm "O\t0,Fm"
590
-#define rv_fmt_rd_vs2 "O\t0,F"
591
-#define rv_fmt_fd_vs2 "O\t3,F"
592
-#define rv_fmt_vd_vm "O\tDm"
593
-#define rv_fmt_vsetvli "O\t0,1,v"
594
-#define rv_fmt_vsetivli "O\t0,u,v"
595
-#define rv_fmt_rs1_rs2_zce_ldst "O\t2,i(1)"
596
-#define rv_fmt_push_rlist "O\tx,-i"
597
-#define rv_fmt_pop_rlist "O\tx,i"
598
-#define rv_fmt_zcmt_index "O\ti"
599
-
600
/* pseudo-instruction constraints */
601
602
static const rvc_constraint rvcc_jal[] = { rvc_rd_eq_ra, rvc_end };
603
--
604
2.40.1
605
606
diff view generated by jsdifflib
Deleted patch
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
2
1
3
The enum value 'rv_op_illegal' does not represent an
4
instruction, but is a catch-all value in case we have
5
no match in the decoder. Let's make the value a shared
6
one, so that other compile units can reuse it.
7
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
10
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
11
Message-Id: <20230612111034.3955227-5-christoph.muellner@vrull.eu>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
disas/riscv.h | 4 ++++
15
disas/riscv.c | 2 +-
16
2 files changed, 5 insertions(+), 1 deletion(-)
17
18
diff --git a/disas/riscv.h b/disas/riscv.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/disas/riscv.h
21
+++ b/disas/riscv.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct {
23
const rvc_constraint *constraints;
24
} rv_comp_data;
25
26
+enum {
27
+ rv_op_illegal = 0
28
+};
29
+
30
enum {
31
rvcd_imm_nz = 0x1
32
};
33
diff --git a/disas/riscv.c b/disas/riscv.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/disas/riscv.c
36
+++ b/disas/riscv.c
37
@@ -XXX,XX +XXX,XX @@
38
#include "disas/riscv.h"
39
40
typedef enum {
41
- rv_op_illegal = 0,
42
+ /* 0 is reserved for rv_op_illegal. */
43
rv_op_lui = 1,
44
rv_op_auipc = 2,
45
rv_op_jal = 3,
46
--
47
2.40.1
48
49
diff view generated by jsdifflib
Deleted patch
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
2
1
3
This patch adds a reference to a struct rv_opcode_data object
4
into struct rv_decode. This further allows to remove all references
5
to the global variable opcode_data (which is renamed to rvi_opcode_data).
6
7
This patch does not introduce any functional change, but prepares
8
the code for more struct rv_opcode_data objects in the future.
9
10
This patch is based on previous work from Liu Zhiwei:
11
https://lists.nongnu.org/archive/html/qemu-devel/2022-08/msg03662.html
12
13
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
16
Message-Id: <20230612111034.3955227-6-christoph.muellner@vrull.eu>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
19
disas/riscv.h | 33 +++++++++++++++++----------------
20
disas/riscv.c | 9 ++++++++-
21
2 files changed, 25 insertions(+), 17 deletions(-)
22
23
diff --git a/disas/riscv.h b/disas/riscv.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/disas/riscv.h
26
+++ b/disas/riscv.h
27
@@ -XXX,XX +XXX,XX @@ typedef enum {
28
29
/* structures */
30
31
+typedef struct {
32
+ const int op;
33
+ const rvc_constraint *constraints;
34
+} rv_comp_data;
35
+
36
+typedef struct {
37
+ const char * const name;
38
+ const rv_codec codec;
39
+ const char * const format;
40
+ const rv_comp_data *pseudo;
41
+ const short decomp_rv32;
42
+ const short decomp_rv64;
43
+ const short decomp_rv128;
44
+ const short decomp_data;
45
+} rv_opcode_data;
46
+
47
typedef struct {
48
RISCVCPUConfig *cfg;
49
uint64_t pc;
50
uint64_t inst;
51
+ const rv_opcode_data *opcode_data;
52
int32_t imm;
53
uint16_t op;
54
uint8_t codec;
55
@@ -XXX,XX +XXX,XX @@ typedef struct {
56
uint8_t rlist;
57
} rv_decode;
58
59
-typedef struct {
60
- const int op;
61
- const rvc_constraint *constraints;
62
-} rv_comp_data;
63
-
64
enum {
65
rv_op_illegal = 0
66
};
67
@@ -XXX,XX +XXX,XX @@ enum {
68
rvcd_imm_nz = 0x1
69
};
70
71
-typedef struct {
72
- const char * const name;
73
- const rv_codec codec;
74
- const char * const format;
75
- const rv_comp_data *pseudo;
76
- const short decomp_rv32;
77
- const short decomp_rv64;
78
- const short decomp_rv128;
79
- const short decomp_data;
80
-} rv_opcode_data;
81
-
82
/* instruction formats */
83
84
#define rv_fmt_none "O\t"
85
diff --git a/disas/riscv.c b/disas/riscv.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/disas/riscv.c
88
+++ b/disas/riscv.c
89
@@ -XXX,XX +XXX,XX @@ static const rv_comp_data rvcp_fsgnjx_q[] = {
90
91
/* instruction metadata */
92
93
-const rv_opcode_data opcode_data[] = {
94
+const rv_opcode_data rvi_opcode_data[] = {
95
{ "illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
96
{ "lui", rv_codec_u, rv_fmt_rd_imm, NULL, 0, 0, 0 },
97
{ "auipc", rv_codec_u, rv_fmt_rd_offset, NULL, 0, 0, 0 },
98
@@ -XXX,XX +XXX,XX @@ static uint32_t operand_tbl_index(rv_inst inst)
99
100
static void decode_inst_operands(rv_decode *dec, rv_isa isa)
101
{
102
+ const rv_opcode_data *opcode_data = dec->opcode_data;
103
rv_inst inst = dec->inst;
104
dec->codec = opcode_data[dec->op].codec;
105
switch (dec->codec) {
106
@@ -XXX,XX +XXX,XX @@ static void append(char *s1, const char *s2, size_t n)
107
108
static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
109
{
110
+ const rv_opcode_data *opcode_data = dec->opcode_data;
111
char tmp[64];
112
const char *fmt;
113
114
@@ -XXX,XX +XXX,XX @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
115
116
static void decode_inst_lift_pseudo(rv_decode *dec)
117
{
118
+ const rv_opcode_data *opcode_data = dec->opcode_data;
119
const rv_comp_data *comp_data = opcode_data[dec->op].pseudo;
120
if (!comp_data) {
121
return;
122
@@ -XXX,XX +XXX,XX @@ static void decode_inst_lift_pseudo(rv_decode *dec)
123
124
static void decode_inst_decompress_rv32(rv_decode *dec)
125
{
126
+ const rv_opcode_data *opcode_data = dec->opcode_data;
127
int decomp_op = opcode_data[dec->op].decomp_rv32;
128
if (decomp_op != rv_op_illegal) {
129
if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
130
@@ -XXX,XX +XXX,XX @@ static void decode_inst_decompress_rv32(rv_decode *dec)
131
132
static void decode_inst_decompress_rv64(rv_decode *dec)
133
{
134
+ const rv_opcode_data *opcode_data = dec->opcode_data;
135
int decomp_op = opcode_data[dec->op].decomp_rv64;
136
if (decomp_op != rv_op_illegal) {
137
if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
138
@@ -XXX,XX +XXX,XX @@ static void decode_inst_decompress_rv64(rv_decode *dec)
139
140
static void decode_inst_decompress_rv128(rv_decode *dec)
141
{
142
+ const rv_opcode_data *opcode_data = dec->opcode_data;
143
int decomp_op = opcode_data[dec->op].decomp_rv128;
144
if (decomp_op != rv_op_illegal) {
145
if ((opcode_data[dec->op].decomp_data & rvcd_imm_nz)
146
@@ -XXX,XX +XXX,XX @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst,
147
rv_decode dec = { 0 };
148
dec.pc = pc;
149
dec.inst = inst;
150
+ dec.opcode_data = rvi_opcode_data;
151
dec.cfg = cfg;
152
decode_inst_opcode(&dec, isa);
153
decode_inst_operands(&dec, isa);
154
--
155
2.40.1
156
157
diff view generated by jsdifflib
Deleted patch
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
2
1
3
A previous patch provides a pointer to the RISCVCPUConfig data.
4
Let's use this to add the necessary code for vendor extensions.
5
This patch does not change the current behaviour, but clearly
6
defines how vendor extension support can be added to the disassembler.
7
8
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
11
Message-Id: <20230612111034.3955227-7-christoph.muellner@vrull.eu>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
disas/riscv.c | 28 ++++++++++++++++++++++++++--
15
1 file changed, 26 insertions(+), 2 deletions(-)
16
17
diff --git a/disas/riscv.c b/disas/riscv.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/disas/riscv.c
20
+++ b/disas/riscv.c
21
@@ -XXX,XX +XXX,XX @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst,
22
rv_decode dec = { 0 };
23
dec.pc = pc;
24
dec.inst = inst;
25
- dec.opcode_data = rvi_opcode_data;
26
dec.cfg = cfg;
27
- decode_inst_opcode(&dec, isa);
28
+
29
+ static const struct {
30
+ bool (*guard_func)(const RISCVCPUConfig *);
31
+ const rv_opcode_data *opcode_data;
32
+ void (*decode_func)(rv_decode *, rv_isa);
33
+ } decoders[] = {
34
+ { always_true_p, rvi_opcode_data, decode_inst_opcode },
35
+ };
36
+
37
+ for (size_t i = 0; i < ARRAY_SIZE(decoders); i++) {
38
+ bool (*guard_func)(const RISCVCPUConfig *) = decoders[i].guard_func;
39
+ const rv_opcode_data *opcode_data = decoders[i].opcode_data;
40
+ void (*decode_func)(rv_decode *, rv_isa) = decoders[i].decode_func;
41
+
42
+ if (guard_func(cfg)) {
43
+ dec.opcode_data = opcode_data;
44
+ decode_func(&dec, isa);
45
+ if (dec.op != rv_op_illegal)
46
+ break;
47
+ }
48
+ }
49
+
50
+ if (dec.op == rv_op_illegal) {
51
+ dec.opcode_data = rvi_opcode_data;
52
+ }
53
+
54
decode_inst_operands(&dec, isa);
55
decode_inst_decompress(&dec, isa);
56
decode_inst_lift_pseudo(&dec);
57
--
58
2.40.1
59
60
diff view generated by jsdifflib
Deleted patch
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
2
1
3
This patch adds XVentanaCondOps support to the RISC-V disassembler.
4
5
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Message-Id: <20230612111034.3955227-8-christoph.muellner@vrull.eu>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
disas/riscv-xventana.h | 18 ++++++++++++++++++
13
disas/riscv-xventana.c | 41 +++++++++++++++++++++++++++++++++++++++++
14
disas/riscv.c | 4 ++++
15
disas/meson.build | 5 ++++-
16
4 files changed, 67 insertions(+), 1 deletion(-)
17
create mode 100644 disas/riscv-xventana.h
18
create mode 100644 disas/riscv-xventana.c
19
20
diff --git a/disas/riscv-xventana.h b/disas/riscv-xventana.h
21
new file mode 100644
22
index XXXXXXX..XXXXXXX
23
--- /dev/null
24
+++ b/disas/riscv-xventana.h
25
@@ -XXX,XX +XXX,XX @@
26
+/*
27
+ * QEMU disassembler -- RISC-V specific header (xventana*).
28
+ *
29
+ * Copyright (c) 2023 VRULL GmbH
30
+ *
31
+ * SPDX-License-Identifier: GPL-2.0-or-later
32
+ */
33
+
34
+#ifndef DISAS_RISCV_XVENTANA_H
35
+#define DISAS_RISCV_XVENTANA_H
36
+
37
+#include "disas/riscv.h"
38
+
39
+extern const rv_opcode_data ventana_opcode_data[];
40
+
41
+void decode_xventanacondops(rv_decode*, rv_isa);
42
+
43
+#endif /* DISAS_RISCV_XVENTANA_H */
44
diff --git a/disas/riscv-xventana.c b/disas/riscv-xventana.c
45
new file mode 100644
46
index XXXXXXX..XXXXXXX
47
--- /dev/null
48
+++ b/disas/riscv-xventana.c
49
@@ -XXX,XX +XXX,XX @@
50
+/*
51
+ * QEMU RISC-V Disassembler for xventana.
52
+ *
53
+ * SPDX-License-Identifier: GPL-2.0-or-later
54
+ */
55
+
56
+#include "disas/riscv.h"
57
+#include "disas/riscv-xventana.h"
58
+
59
+typedef enum {
60
+ /* 0 is reserved for rv_op_illegal. */
61
+ ventana_op_vt_maskc = 1,
62
+ ventana_op_vt_maskcn = 2,
63
+} rv_ventana_op;
64
+
65
+const rv_opcode_data ventana_opcode_data[] = {
66
+ { "vt.illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
67
+ { "vt.maskc", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
68
+ { "vt.maskcn", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
69
+};
70
+
71
+void decode_xventanacondops(rv_decode *dec, rv_isa isa)
72
+{
73
+ rv_inst inst = dec->inst;
74
+ rv_opcode op = rv_op_illegal;
75
+
76
+ switch (((inst >> 0) & 0b11)) {
77
+ case 3:
78
+ switch (((inst >> 2) & 0b11111)) {
79
+ case 30:
80
+ switch (((inst >> 22) & 0b1111111000) | ((inst >> 12) & 0b0000000111)) {
81
+ case 6: op = ventana_op_vt_maskc; break;
82
+ case 7: op = ventana_op_vt_maskcn; break;
83
+ }
84
+ break;
85
+ }
86
+ break;
87
+ }
88
+
89
+ dec->op = op;
90
+}
91
diff --git a/disas/riscv.c b/disas/riscv.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/disas/riscv.c
94
+++ b/disas/riscv.c
95
@@ -XXX,XX +XXX,XX @@
96
#include "target/riscv/cpu_cfg.h"
97
#include "disas/riscv.h"
98
99
+/* Vendor extensions */
100
+#include "disas/riscv-xventana.h"
101
+
102
typedef enum {
103
/* 0 is reserved for rv_op_illegal. */
104
rv_op_lui = 1,
105
@@ -XXX,XX +XXX,XX @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst,
106
void (*decode_func)(rv_decode *, rv_isa);
107
} decoders[] = {
108
{ always_true_p, rvi_opcode_data, decode_inst_opcode },
109
+ { has_XVentanaCondOps_p, ventana_opcode_data, decode_xventanacondops },
110
};
111
112
for (size_t i = 0; i < ARRAY_SIZE(decoders); i++) {
113
diff --git a/disas/meson.build b/disas/meson.build
114
index XXXXXXX..XXXXXXX 100644
115
--- a/disas/meson.build
116
+++ b/disas/meson.build
117
@@ -XXX,XX +XXX,XX @@ common_ss.add(when: 'CONFIG_M68K_DIS', if_true: files('m68k.c'))
118
common_ss.add(when: 'CONFIG_MICROBLAZE_DIS', if_true: files('microblaze.c'))
119
common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c', 'nanomips.c'))
120
common_ss.add(when: 'CONFIG_NIOS2_DIS', if_true: files('nios2.c'))
121
-common_ss.add(when: 'CONFIG_RISCV_DIS', if_true: files('riscv.c'))
122
+common_ss.add(when: 'CONFIG_RISCV_DIS', if_true: files(
123
+ 'riscv.c',
124
+ 'riscv-xventana.c'
125
+))
126
common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c'))
127
common_ss.add(when: 'CONFIG_SPARC_DIS', if_true: files('sparc.c'))
128
common_ss.add(when: 'CONFIG_XTENSA_DIS', if_true: files('xtensa.c'))
129
--
130
2.40.1
131
132
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
If we don't set a proper cbom_blocksize|cboz_blocksize in the FDT the
3
In this patch, we create the APLIC and IMSIC FDT helper functions and
4
Linux Kernel will fail to detect the availability of the CBOM/CBOZ
4
remove M mode AIA devices when using KVM acceleration.
5
extensions, regardless of the contents of the 'riscv,isa' DT prop.
6
5
7
The FDT is being written using the cpu->cfg.cbom|z_blocksize attributes,
6
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
8
so let's expose them as user properties like it is already done with
7
Reviewed-by: Jim Shu <jim.shu@sifive.com>
9
TCG.
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
11
This will also require us to determine proper blocksize values during
12
init() time since the FDT is already created during realize(). We'll
13
take a ride in kvm_riscv_init_multiext_cfg() to do it. Note that we
14
don't need to fetch both cbom and cboz blocksizes every time: check for
15
their parent extensions (icbom and icboz) and only read the blocksizes
16
if needed.
17
18
In contrast with cbom|z_blocksize properties from TCG, the user is not
19
able to set any value that is different from the 'host' value when
20
running KVM. KVM can be particularly harsh dealing with it: a ENOTSUPP
21
can be thrown for the mere attempt of executing kvm_set_one_reg() for
22
these 2 regs.
23
24
Hopefully we don't need to call kvm_set_one_reg() for these regs.
25
We'll check if the user input matches the host value in
26
kvm_cpu_set_cbomz_blksize(), the set() accessor for both blocksize
27
properties. We'll fail fast since it's already known to not be
28
supported.
29
30
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
31
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
9
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
32
Acked-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-ID: <20230727102439.22554-2-yongxuan.wang@sifive.com>
33
Message-Id: <20230706101738.460804-21-dbarboza@ventanamicro.com>
34
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
---
12
---
36
target/riscv/kvm.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++
13
hw/riscv/virt.c | 290 +++++++++++++++++++++++-------------------------
37
1 file changed, 70 insertions(+)
14
1 file changed, 137 insertions(+), 153 deletions(-)
38
15
39
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
16
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
40
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/kvm.c
18
--- a/hw/riscv/virt.c
42
+++ b/target/riscv/kvm.c
19
+++ b/hw/riscv/virt.c
43
@@ -XXX,XX +XXX,XX @@ static void kvm_cpu_set_multi_ext_cfg(Object *obj, Visitor *v,
20
@@ -XXX,XX +XXX,XX @@ static uint32_t imsic_num_bits(uint32_t count)
44
kvm_cpu_cfg_set(cpu, multi_ext_cfg, value);
21
return ret;
45
}
22
}
46
23
47
+static KVMCPUConfig kvm_cbom_blocksize = {
24
-static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
48
+ .name = "cbom_blocksize",
25
- uint32_t *phandle, uint32_t *intc_phandles,
49
+ .offset = CPUCFG(cbom_blocksize),
26
- uint32_t *msi_m_phandle, uint32_t *msi_s_phandle)
50
+ .kvm_reg_id = KVM_REG_RISCV_CONFIG_REG(zicbom_block_size)
27
+static void create_fdt_one_imsic(RISCVVirtState *s, hwaddr base_addr,
51
+};
28
+ uint32_t *intc_phandles, uint32_t msi_phandle,
52
+
29
+ bool m_mode, uint32_t imsic_guest_bits)
53
+static KVMCPUConfig kvm_cboz_blocksize = {
30
{
54
+ .name = "cboz_blocksize",
31
int cpu, socket;
55
+ .offset = CPUCFG(cboz_blocksize),
32
char *imsic_name;
56
+ .kvm_reg_id = KVM_REG_RISCV_CONFIG_REG(zicboz_block_size)
33
MachineState *ms = MACHINE(s);
57
+};
34
int socket_count = riscv_socket_count(ms);
58
+
35
- uint32_t imsic_max_hart_per_socket, imsic_guest_bits;
59
+static void kvm_cpu_set_cbomz_blksize(Object *obj, Visitor *v,
36
+ uint32_t imsic_max_hart_per_socket;
60
+ const char *name,
37
uint32_t *imsic_cells, *imsic_regs, imsic_addr, imsic_size;
61
+ void *opaque, Error **errp)
38
39
- *msi_m_phandle = (*phandle)++;
40
- *msi_s_phandle = (*phandle)++;
41
imsic_cells = g_new0(uint32_t, ms->smp.cpus * 2);
42
imsic_regs = g_new0(uint32_t, socket_count * 4);
43
44
- /* M-level IMSIC node */
45
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
46
imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
47
- imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
48
+ imsic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
49
}
50
- imsic_max_hart_per_socket = 0;
51
- for (socket = 0; socket < socket_count; socket++) {
52
- imsic_addr = memmap[VIRT_IMSIC_M].base +
53
- socket * VIRT_IMSIC_GROUP_MAX_SIZE;
54
- imsic_size = IMSIC_HART_SIZE(0) * s->soc[socket].num_harts;
55
- imsic_regs[socket * 4 + 0] = 0;
56
- imsic_regs[socket * 4 + 1] = cpu_to_be32(imsic_addr);
57
- imsic_regs[socket * 4 + 2] = 0;
58
- imsic_regs[socket * 4 + 3] = cpu_to_be32(imsic_size);
59
- if (imsic_max_hart_per_socket < s->soc[socket].num_harts) {
60
- imsic_max_hart_per_socket = s->soc[socket].num_harts;
61
- }
62
- }
63
- imsic_name = g_strdup_printf("/soc/imsics@%lx",
64
- (unsigned long)memmap[VIRT_IMSIC_M].base);
65
- qemu_fdt_add_subnode(ms->fdt, imsic_name);
66
- qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
67
- "riscv,imsics");
68
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
69
- FDT_IMSIC_INT_CELLS);
70
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
71
- NULL, 0);
72
- qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
73
- NULL, 0);
74
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
75
- imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
76
- qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
77
- socket_count * sizeof(uint32_t) * 4);
78
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
79
- VIRT_IRQCHIP_NUM_MSIS);
80
- if (socket_count > 1) {
81
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
82
- imsic_num_bits(imsic_max_hart_per_socket));
83
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
84
- imsic_num_bits(socket_count));
85
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
86
- IMSIC_MMIO_GROUP_MIN_SHIFT);
87
- }
88
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_m_phandle);
89
-
90
- g_free(imsic_name);
91
92
- /* S-level IMSIC node */
93
- for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
94
- imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
95
- imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
96
- }
97
- imsic_guest_bits = imsic_num_bits(s->aia_guests + 1);
98
imsic_max_hart_per_socket = 0;
99
for (socket = 0; socket < socket_count; socket++) {
100
- imsic_addr = memmap[VIRT_IMSIC_S].base +
101
- socket * VIRT_IMSIC_GROUP_MAX_SIZE;
102
+ imsic_addr = base_addr + socket * VIRT_IMSIC_GROUP_MAX_SIZE;
103
imsic_size = IMSIC_HART_SIZE(imsic_guest_bits) *
104
s->soc[socket].num_harts;
105
imsic_regs[socket * 4 + 0] = 0;
106
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
107
imsic_max_hart_per_socket = s->soc[socket].num_harts;
108
}
109
}
110
- imsic_name = g_strdup_printf("/soc/imsics@%lx",
111
- (unsigned long)memmap[VIRT_IMSIC_S].base);
112
+
113
+ imsic_name = g_strdup_printf("/soc/imsics@%lx", (unsigned long)base_addr);
114
qemu_fdt_add_subnode(ms->fdt, imsic_name);
115
- qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
116
- "riscv,imsics");
117
+ qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible", "riscv,imsics");
118
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
119
- FDT_IMSIC_INT_CELLS);
120
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
121
- NULL, 0);
122
- qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
123
- NULL, 0);
124
+ FDT_IMSIC_INT_CELLS);
125
+ qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller", NULL, 0);
126
+ qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller", NULL, 0);
127
qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
128
- imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
129
+ imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
130
qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
131
- socket_count * sizeof(uint32_t) * 4);
132
+ socket_count * sizeof(uint32_t) * 4);
133
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
134
- VIRT_IRQCHIP_NUM_MSIS);
135
+ VIRT_IRQCHIP_NUM_MSIS);
136
+
137
if (imsic_guest_bits) {
138
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,guest-index-bits",
139
- imsic_guest_bits);
140
+ imsic_guest_bits);
141
}
142
+
143
if (socket_count > 1) {
144
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
145
- imsic_num_bits(imsic_max_hart_per_socket));
146
+ imsic_num_bits(imsic_max_hart_per_socket));
147
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
148
- imsic_num_bits(socket_count));
149
+ imsic_num_bits(socket_count));
150
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
151
- IMSIC_MMIO_GROUP_MIN_SHIFT);
152
+ IMSIC_MMIO_GROUP_MIN_SHIFT);
153
}
154
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_s_phandle);
155
- g_free(imsic_name);
156
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", msi_phandle);
157
158
+ g_free(imsic_name);
159
g_free(imsic_regs);
160
g_free(imsic_cells);
161
}
162
163
-static void create_fdt_socket_aplic(RISCVVirtState *s,
164
- const MemMapEntry *memmap, int socket,
165
- uint32_t msi_m_phandle,
166
- uint32_t msi_s_phandle,
167
- uint32_t *phandle,
168
- uint32_t *intc_phandles,
169
- uint32_t *aplic_phandles)
170
+static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
171
+ uint32_t *phandle, uint32_t *intc_phandles,
172
+ uint32_t *msi_m_phandle, uint32_t *msi_s_phandle)
62
+{
173
+{
63
+ KVMCPUConfig *cbomz_cfg = opaque;
174
+ *msi_m_phandle = (*phandle)++;
64
+ RISCVCPU *cpu = RISCV_CPU(obj);
175
+ *msi_s_phandle = (*phandle)++;
65
+ uint16_t value, *host_val;
176
+
66
+
177
+ if (!kvm_enabled()) {
67
+ if (!visit_type_uint16(v, name, &value, errp)) {
178
+ /* M-level IMSIC node */
68
+ return;
179
+ create_fdt_one_imsic(s, memmap[VIRT_IMSIC_M].base, intc_phandles,
180
+ *msi_m_phandle, true, 0);
69
+ }
181
+ }
70
+
182
+
71
+ host_val = kvmconfig_get_cfg_addr(cpu, cbomz_cfg);
183
+ /* S-level IMSIC node */
72
+
184
+ create_fdt_one_imsic(s, memmap[VIRT_IMSIC_S].base, intc_phandles,
73
+ if (value != *host_val) {
185
+ *msi_s_phandle, false,
74
+ error_report("Unable to set %s to a different value than "
186
+ imsic_num_bits(s->aia_guests + 1));
75
+ "the host (%u)",
187
+
76
+ cbomz_cfg->name, *host_val);
188
+}
77
+ exit(EXIT_FAILURE);
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)
197
{
198
int cpu;
199
char *aplic_name;
200
uint32_t *aplic_cells;
201
- unsigned long aplic_addr;
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);
78
+ }
254
+ }
79
+
255
+
80
+ cbomz_cfg->user_set = true;
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);
81
+}
262
+}
82
+
263
83
static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
264
- /* S-level APLIC node */
84
{
265
- for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
85
CPURISCVState *env = &cpu->env;
266
- aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
86
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_add_cpu_user_properties(Object *cpu_obj)
267
- aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
87
kvm_cpu_set_multi_ext_cfg,
268
+static void create_fdt_socket_aplic(RISCVVirtState *s,
88
NULL, multi_cfg);
269
+ const MemMapEntry *memmap, int socket,
89
}
270
+ uint32_t msi_m_phandle,
90
+
271
+ uint32_t msi_s_phandle,
91
+ object_property_add(cpu_obj, "cbom_blocksize", "uint16",
272
+ uint32_t *phandle,
92
+ NULL, kvm_cpu_set_cbomz_blksize,
273
+ uint32_t *intc_phandles,
93
+ NULL, &kvm_cbom_blocksize);
274
+ uint32_t *aplic_phandles)
94
+
275
+{
95
+ object_property_add(cpu_obj, "cboz_blocksize", "uint16",
276
+ char *aplic_name;
96
+ NULL, kvm_cpu_set_cbomz_blksize,
277
+ unsigned long aplic_addr;
97
+ NULL, &kvm_cboz_blocksize);
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;
98
}
330
}
99
331
100
static int kvm_riscv_get_regs_core(CPUState *cs)
332
@@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
101
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_misa_ext_mask(RISCVCPU *cpu,
333
int i;
102
env->misa_ext = env->misa_ext_mask;
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;
103
}
409
}
104
410
105
+static void kvm_riscv_read_cbomz_blksize(RISCVCPU *cpu, KVMScratchCPU *kvmcpu,
411
static void create_platform_bus(RISCVVirtState *s, DeviceState *irqchip)
106
+ KVMCPUConfig *cbomz_cfg)
107
+{
108
+ CPURISCVState *env = &cpu->env;
109
+ struct kvm_one_reg reg;
110
+ int ret;
111
+
112
+ reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
113
+ cbomz_cfg->kvm_reg_id);
114
+ reg.addr = (uint64_t)kvmconfig_get_cfg_addr(cpu, cbomz_cfg);
115
+ ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, &reg);
116
+ if (ret != 0) {
117
+ error_report("Unable to read KVM reg %s, error %d",
118
+ cbomz_cfg->name, ret);
119
+ exit(EXIT_FAILURE);
120
+ }
121
+}
122
+
123
static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
124
{
125
CPURISCVState *env = &cpu->env;
126
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
127
128
kvm_cpu_cfg_set(cpu, multi_ext_cfg, val);
129
}
130
+
131
+ if (cpu->cfg.ext_icbom) {
132
+ kvm_riscv_read_cbomz_blksize(cpu, kvmcpu, &kvm_cbom_blocksize);
133
+ }
134
+
135
+ if (cpu->cfg.ext_icboz) {
136
+ kvm_riscv_read_cbomz_blksize(cpu, kvmcpu, &kvm_cboz_blocksize);
137
+ }
138
}
139
140
void kvm_riscv_init_user_properties(Object *cpu_obj)
141
--
412
--
142
2.40.1
413
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
Allow 'marchid' and 'mimpid' to also be initialized in
3
We check the in-kernel irqchip support when using KVM acceleration.
4
kvm_riscv_init_machine_ids().
5
4
6
After this change, the handling of mvendorid/marchid/mimpid for the
5
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
7
'host' CPU type will be equal to what we already have for TCG named
6
Reviewed-by: Jim Shu <jim.shu@sifive.com>
8
CPUs, i.e. the user is not able to set these values to a different val
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
than the one that is already preset.
10
11
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
8
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20230727102439.22554-3-yongxuan.wang@sifive.com>
14
Message-Id: <20230706101738.460804-8-dbarboza@ventanamicro.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/kvm.c | 16 ++++++++++++++++
12
target/riscv/kvm.c | 10 +++++++++-
18
1 file changed, 16 insertions(+)
13
1 file changed, 9 insertions(+), 1 deletion(-)
19
14
20
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
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/kvm.c
17
--- a/target/riscv/kvm.c
23
+++ b/target/riscv/kvm.c
18
+++ b/target/riscv/kvm.c
24
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_machine_ids(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
19
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
25
if (ret != 0) {
20
26
error_report("Unable to retrieve mvendorid from host, error %d", ret);
21
int kvm_arch_irqchip_create(KVMState *s)
27
}
22
{
28
+
23
- return 0;
29
+ reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
24
+ if (kvm_kernel_irqchip_split()) {
30
+ KVM_REG_RISCV_CONFIG_REG(marchid));
25
+ error_report("-machine kernel_irqchip=split is not supported on RISC-V.");
31
+ reg.addr = (uint64_t)&cpu->cfg.marchid;
26
+ exit(1);
32
+ ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, &reg);
33
+ if (ret != 0) {
34
+ error_report("Unable to retrieve marchid from host, error %d", ret);
35
+ }
27
+ }
36
+
28
+
37
+ reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
29
+ /*
38
+ KVM_REG_RISCV_CONFIG_REG(mimpid));
30
+ * We can create the VAIA using the newer device control API.
39
+ reg.addr = (uint64_t)&cpu->cfg.mimpid;
31
+ */
40
+ ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, &reg);
32
+ return kvm_check_extension(s, KVM_CAP_DEVICE_CTRL);
41
+ if (ret != 0) {
42
+ error_report("Unable to retrieve mimpid from host, error %d", ret);
43
+ }
44
}
33
}
45
34
46
void kvm_riscv_init_user_properties(Object *cpu_obj)
35
int kvm_arch_process_async_events(CPUState *cs)
47
--
36
--
48
2.40.1
37
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
Certain validations, such as the validations done for the machine IDs
3
We create a vAIA chip by using the KVM_DEV_TYPE_RISCV_AIA and then set up
4
(mvendorid/marchid/mimpid), are done before starting the CPU.
4
the chip with the KVM_DEV_RISCV_AIA_GRP_* APIs.
5
Non-dynamic (named) CPUs tries to match user input with a preset
5
We also extend KVM accelerator to specify the KVM AIA mode. The "riscv-aia"
6
default. As it is today we can't prefetch a KVM default for these cases
6
parameter is passed along with --accel in QEMU command-line.
7
because we're only able to read/write KVM regs after the vcpu is
7
1) "riscv-aia=emul": IMSIC is emulated by hypervisor
8
spinning.
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.
9
11
10
Our target/arm friends use a concept called "scratch CPU", which
12
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
11
consists of creating a vcpu for doing queries and validations and so on,
13
Reviewed-by: Jim Shu <jim.shu@sifive.com>
12
which is discarded shortly after use [1]. This is a suitable solution
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
for what we need so let's implement it in target/riscv as well.
14
15
kvm_riscv_init_machine_ids() will be used to do any pre-launch setup for
16
KVM CPUs, via riscv_cpu_add_user_properties(). The function will create
17
a KVM scratch CPU, fetch KVM regs that work as default values for user
18
properties, and then discard the scratch CPU afterwards.
19
20
We're starting by initializing 'mvendorid'. This concept will be used to
21
init other KVM specific properties in the next patches as well.
22
23
[1] target/arm/kvm.c, kvm_arm_create_scratch_host_vcpu()
24
25
Suggested-by: Andrew Jones <ajones@ventanamicro.com>
26
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
27
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
15
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
28
Acked-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-ID: <20230727102439.22554-4-yongxuan.wang@sifive.com>
29
Message-Id: <20230706101738.460804-7-dbarboza@ventanamicro.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
31
---
18
---
32
target/riscv/kvm_riscv.h | 1 +
19
target/riscv/kvm_riscv.h | 4 +
33
target/riscv/cpu.c | 6 +++
20
target/riscv/kvm.c | 186 +++++++++++++++++++++++++++++++++++++++
34
target/riscv/kvm.c | 85 ++++++++++++++++++++++++++++++++++++++++
21
2 files changed, 190 insertions(+)
35
3 files changed, 92 insertions(+)
36
22
37
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
23
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
38
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
39
--- a/target/riscv/kvm_riscv.h
25
--- a/target/riscv/kvm_riscv.h
40
+++ b/target/riscv/kvm_riscv.h
26
+++ b/target/riscv/kvm_riscv.h
41
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@
42
#ifndef QEMU_KVM_RISCV_H
28
void kvm_riscv_init_user_properties(Object *cpu_obj);
43
#define QEMU_KVM_RISCV_H
44
45
+void kvm_riscv_init_user_properties(Object *cpu_obj);
46
void kvm_riscv_reset_vcpu(RISCVCPU *cpu);
29
void kvm_riscv_reset_vcpu(RISCVCPU *cpu);
47
void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level);
30
void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level);
48
31
+void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
49
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
32
+ uint64_t aia_irq_num, uint64_t aia_msi_num,
50
index XXXXXXX..XXXXXXX 100644
33
+ uint64_t aplic_base, uint64_t imsic_base,
51
--- a/target/riscv/cpu.c
34
+ uint64_t guest_num);
52
+++ b/target/riscv/cpu.c
35
53
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_add_user_properties(Object *obj)
36
#endif
54
Property *prop;
55
DeviceState *dev = DEVICE(obj);
56
57
+#ifndef CONFIG_USER_ONLY
58
+ if (kvm_enabled()) {
59
+ kvm_riscv_init_user_properties(obj);
60
+ }
61
+#endif
62
+
63
riscv_cpu_add_misa_properties(obj);
64
65
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
66
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
37
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
67
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/kvm.c
39
--- a/target/riscv/kvm.c
69
+++ b/target/riscv/kvm.c
40
+++ b/target/riscv/kvm.c
70
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_put_regs_timer(CPUState *cs)
41
@@ -XXX,XX +XXX,XX @@
71
env->kvm_timer_dirty = false;
42
#include "exec/address-spaces.h"
43
#include "hw/boards.h"
44
#include "hw/irq.h"
45
+#include "hw/intc/riscv_imsic.h"
46
#include "qemu/log.h"
47
#include "hw/loader.h"
48
#include "kvm_riscv.h"
49
@@ -XXX,XX +XXX,XX @@
50
#include "chardev/char-fe.h"
51
#include "migration/migration.h"
52
#include "sysemu/runstate.h"
53
+#include "hw/riscv/numa.h"
54
55
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
56
uint64_t idx)
57
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_cpu_check_are_resettable(void)
58
return true;
72
}
59
}
73
60
74
+typedef struct KVMScratchCPU {
61
+static int aia_mode;
75
+ int kvmfd;
62
+
76
+ int vmfd;
63
+static const char *kvm_aia_mode_str(uint64_t mode)
77
+ int cpufd;
64
+{
78
+} KVMScratchCPU;
65
+ switch (mode) {
79
+
66
+ case KVM_DEV_RISCV_AIA_MODE_EMUL:
80
+/*
67
+ return "emul";
81
+ * Heavily inspired by kvm_arm_create_scratch_host_vcpu()
68
+ case KVM_DEV_RISCV_AIA_MODE_HWACCEL:
82
+ * from target/arm/kvm.c.
69
+ return "hwaccel";
83
+ */
70
+ case KVM_DEV_RISCV_AIA_MODE_AUTO:
84
+static bool kvm_riscv_create_scratch_vcpu(KVMScratchCPU *scratch)
71
+ default:
85
+{
72
+ return "auto";
86
+ int kvmfd = -1, vmfd = -1, cpufd = -1;
73
+ };
87
+
74
+}
88
+ kvmfd = qemu_open_old("/dev/kvm", O_RDWR);
75
+
89
+ if (kvmfd < 0) {
76
+static char *riscv_get_kvm_aia(Object *obj, Error **errp)
90
+ goto err;
77
+{
91
+ }
78
+ return g_strdup(kvm_aia_mode_str(aia_mode));
92
+ do {
79
+}
93
+ vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0);
80
+
94
+ } while (vmfd == -1 && errno == EINTR);
81
+static void riscv_set_kvm_aia(Object *obj, const char *val, Error **errp)
95
+ if (vmfd < 0) {
82
+{
96
+ goto err;
83
+ if (!strcmp(val, "emul")) {
97
+ }
84
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_EMUL;
98
+ cpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0);
85
+ } else if (!strcmp(val, "hwaccel")) {
99
+ if (cpufd < 0) {
86
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_HWACCEL;
100
+ goto err;
87
+ } else if (!strcmp(val, "auto")) {
101
+ }
88
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_AUTO;
102
+
89
+ } else {
103
+ scratch->kvmfd = kvmfd;
90
+ error_setg(errp, "Invalid KVM AIA mode");
104
+ scratch->vmfd = vmfd;
91
+ error_append_hint(errp, "Valid values are emul, hwaccel, and auto.\n");
105
+ scratch->cpufd = cpufd;
92
+ }
106
+
93
+}
107
+ return true;
94
+
108
+
95
void kvm_arch_accel_class_init(ObjectClass *oc)
109
+ err:
96
{
110
+ if (cpufd >= 0) {
97
+ object_class_property_add_str(oc, "riscv-aia", riscv_get_kvm_aia,
111
+ close(cpufd);
98
+ riscv_set_kvm_aia);
112
+ }
99
+ object_class_property_set_description(oc, "riscv-aia",
113
+ if (vmfd >= 0) {
100
+ "Set KVM AIA mode. Valid values are "
114
+ close(vmfd);
101
+ "emul, hwaccel, and auto. Default "
115
+ }
102
+ "is auto.");
116
+ if (kvmfd >= 0) {
103
+ object_property_set_default_str(object_class_property_find(oc, "riscv-aia"),
117
+ close(kvmfd);
104
+ "auto");
118
+ }
105
+}
119
+
106
+
120
+ return false;
107
+void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
121
+}
108
+ uint64_t aia_irq_num, uint64_t aia_msi_num,
122
+
109
+ uint64_t aplic_base, uint64_t imsic_base,
123
+static void kvm_riscv_destroy_scratch_vcpu(KVMScratchCPU *scratch)
110
+ uint64_t guest_num)
124
+{
111
+{
125
+ close(scratch->cpufd);
112
+ int ret, i;
126
+ close(scratch->vmfd);
113
+ int aia_fd = -1;
127
+ close(scratch->kvmfd);
114
+ uint64_t default_aia_mode;
128
+}
115
+ uint64_t socket_count = riscv_socket_count(machine);
129
+
116
+ uint64_t max_hart_per_socket = 0;
130
+static void kvm_riscv_init_machine_ids(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
117
+ uint64_t socket, base_hart, hart_count, socket_imsic_base, imsic_addr;
131
+{
118
+ uint64_t socket_bits, hart_bits, guest_bits;
132
+ CPURISCVState *env = &cpu->env;
119
+
133
+ struct kvm_one_reg reg;
120
+ aia_fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_RISCV_AIA, false);
134
+ int ret;
121
+
135
+
122
+ if (aia_fd < 0) {
136
+ reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
123
+ error_report("Unable to create in-kernel irqchip");
137
+ KVM_REG_RISCV_CONFIG_REG(mvendorid));
124
+ exit(1);
138
+ reg.addr = (uint64_t)&cpu->cfg.mvendorid;
125
+ }
139
+ ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, &reg);
126
+
140
+ if (ret != 0) {
127
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
141
+ error_report("Unable to retrieve mvendorid from host, error %d", ret);
128
+ KVM_DEV_RISCV_AIA_CONFIG_MODE,
142
+ }
129
+ &default_aia_mode, false, NULL);
143
+}
130
+ if (ret < 0) {
144
+
131
+ error_report("KVM AIA: failed to get current KVM AIA mode");
145
+void kvm_riscv_init_user_properties(Object *cpu_obj)
132
+ exit(1);
146
+{
133
+ }
147
+ RISCVCPU *cpu = RISCV_CPU(cpu_obj);
134
+ qemu_log("KVM AIA: default mode is %s\n",
148
+ KVMScratchCPU kvmcpu;
135
+ kvm_aia_mode_str(default_aia_mode));
149
+
136
+
150
+ if (!kvm_riscv_create_scratch_vcpu(&kvmcpu)) {
137
+ if (default_aia_mode != aia_mode) {
151
+ return;
138
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
152
+ }
139
+ KVM_DEV_RISCV_AIA_CONFIG_MODE,
153
+
140
+ &aia_mode, true, NULL);
154
+ kvm_riscv_init_machine_ids(cpu, &kvmcpu);
141
+ if (ret < 0)
155
+
142
+ warn_report("KVM AIA: failed to set KVM AIA mode");
156
+ kvm_riscv_destroy_scratch_vcpu(&kvmcpu);
143
+ else
157
+}
144
+ qemu_log("KVM AIA: set current mode to %s\n",
158
+
145
+ kvm_aia_mode_str(aia_mode));
159
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
146
+ }
160
KVM_CAP_LAST_INFO
147
+
161
};
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
}
162
--
248
--
163
2.40.1
249
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
Let's add KVM user properties for the multi-letter extensions that KVM
3
KVM AIA can't emulate APLIC only. When "aia=aplic" parameter is passed,
4
currently supports: zicbom, zicboz, zihintpause, zbb, ssaia, sstc,
4
APLIC devices is emulated by QEMU. For "aia=aplic-imsic", remove the
5
svinval and svpbmt.
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
As with MISA extensions, we're using the KVMCPUConfig type to hold
10
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
8
information about the state of each extension. However, multi-letter
11
Reviewed-by: Jim Shu <jim.shu@sifive.com>
9
extensions have more cases to cover than MISA extensions, so we're
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
adding an extra 'supported' flag as well. This flag will reflect if a
11
given extension is supported by KVM, i.e. KVM knows how to handle it.
12
This is determined during KVM extension discovery in
13
kvm_riscv_init_multiext_cfg(), where we test for EINVAL errors. Any
14
other error will cause an abort.
15
16
The use of the 'user_set' is similar to what we already do with MISA
17
extensions: the flag set only if the user is changing the extension
18
state.
19
20
The 'supported' flag will be used later on to make an exception for
21
users that are disabling multi-letter extensions that are unknown to
22
KVM.
23
24
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
25
Acked-by: Alistair Francis <alistair.francis@wdc.com>
26
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
13
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
27
Message-Id: <20230706101738.460804-15-dbarboza@ventanamicro.com>
14
Message-ID: <20230727102439.22554-5-yongxuan.wang@sifive.com>
28
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
29
---
16
---
30
target/riscv/cpu.c | 8 +++
17
hw/intc/riscv_aplic.c | 56 ++++++++++++++++++++++++++++++-------------
31
target/riscv/kvm.c | 119 +++++++++++++++++++++++++++++++++++++++++++++
18
hw/intc/riscv_imsic.c | 25 +++++++++++++++----
32
2 files changed, 127 insertions(+)
19
2 files changed, 61 insertions(+), 20 deletions(-)
33
20
34
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
21
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
35
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
36
--- a/target/riscv/cpu.c
23
--- a/hw/intc/riscv_aplic.c
37
+++ b/target/riscv/cpu.c
24
+++ b/hw/intc/riscv_aplic.c
38
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_add_user_properties(Object *obj)
25
@@ -XXX,XX +XXX,XX @@
39
riscv_cpu_add_misa_properties(obj);
26
#include "hw/irq.h"
40
27
#include "target/riscv/cpu.h"
41
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
28
#include "sysemu/sysemu.h"
42
+#ifndef CONFIG_USER_ONLY
29
+#include "sysemu/kvm.h"
43
+ if (kvm_enabled()) {
30
#include "migration/vmstate.h"
44
+ /* Check if KVM created the property already */
31
45
+ if (object_property_find(obj, prop->name)) {
32
#define APLIC_MAX_IDC (1UL << 14)
46
+ continue;
33
@@ -XXX,XX +XXX,XX @@
47
+ }
34
48
+ }
35
#define APLIC_IDC_CLAIMI 0x1c
49
+#endif
36
50
qdev_property_add_static(dev, prop);
37
+/*
51
}
38
+ * KVM AIA only supports APLIC MSI, fallback to QEMU emulation if we want to use
52
39
+ * APLIC Wired.
53
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
40
+ */
54
index XXXXXXX..XXXXXXX 100644
41
+static bool is_kvm_aia(bool msimode)
55
--- a/target/riscv/kvm.c
56
+++ b/target/riscv/kvm.c
57
@@ -XXX,XX +XXX,XX @@ typedef struct KVMCPUConfig {
58
target_ulong offset;
59
int kvm_reg_id;
60
bool user_set;
61
+ bool supported;
62
} KVMCPUConfig;
63
64
#define KVM_MISA_CFG(_bit, _reg_id) \
65
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_update_cpu_misa_ext(RISCVCPU *cpu, CPUState *cs)
66
}
67
}
68
69
+#define CPUCFG(_prop) offsetof(struct RISCVCPUConfig, _prop)
70
+
71
+#define KVM_EXT_CFG(_name, _prop, _reg_id) \
72
+ {.name = _name, .offset = CPUCFG(_prop), \
73
+ .kvm_reg_id = _reg_id}
74
+
75
+static KVMCPUConfig kvm_multi_ext_cfgs[] = {
76
+ KVM_EXT_CFG("zicbom", ext_icbom, KVM_RISCV_ISA_EXT_ZICBOM),
77
+ KVM_EXT_CFG("zicboz", ext_icboz, KVM_RISCV_ISA_EXT_ZICBOZ),
78
+ KVM_EXT_CFG("zihintpause", ext_zihintpause, KVM_RISCV_ISA_EXT_ZIHINTPAUSE),
79
+ KVM_EXT_CFG("zbb", ext_zbb, KVM_RISCV_ISA_EXT_ZBB),
80
+ KVM_EXT_CFG("ssaia", ext_ssaia, KVM_RISCV_ISA_EXT_SSAIA),
81
+ KVM_EXT_CFG("sstc", ext_sstc, KVM_RISCV_ISA_EXT_SSTC),
82
+ KVM_EXT_CFG("svinval", ext_svinval, KVM_RISCV_ISA_EXT_SVINVAL),
83
+ KVM_EXT_CFG("svpbmt", ext_svpbmt, KVM_RISCV_ISA_EXT_SVPBMT),
84
+};
85
+
86
+static void kvm_cpu_cfg_set(RISCVCPU *cpu, KVMCPUConfig *multi_ext,
87
+ uint32_t val)
88
+{
42
+{
89
+ int cpu_cfg_offset = multi_ext->offset;
43
+ return kvm_irqchip_in_kernel() && msimode;
90
+ bool *ext_enabled = (void *)&cpu->cfg + cpu_cfg_offset;
91
+
92
+ *ext_enabled = val;
93
+}
44
+}
94
+
45
+
95
+static uint32_t kvm_cpu_cfg_get(RISCVCPU *cpu,
46
static uint32_t riscv_aplic_read_input_word(RISCVAPLICState *aplic,
96
+ KVMCPUConfig *multi_ext)
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)
97
+{
54
+{
98
+ int cpu_cfg_offset = multi_ext->offset;
55
+ kvm_set_irq(kvm_state, irq, !!level);
99
+ bool *ext_enabled = (void *)&cpu->cfg + cpu_cfg_offset;
100
+
101
+ return *ext_enabled;
102
+}
56
+}
103
+
57
+
104
+static void kvm_cpu_set_multi_ext_cfg(Object *obj, Visitor *v,
58
static void riscv_aplic_request(void *opaque, int irq, int level)
105
+ const char *name,
59
{
106
+ void *opaque, Error **errp)
60
bool update = false;
107
+{
61
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
108
+ KVMCPUConfig *multi_ext_cfg = opaque;
62
uint32_t i;
109
+ RISCVCPU *cpu = RISCV_CPU(obj);
63
RISCVAPLICState *aplic = RISCV_APLIC(dev);
110
+ bool value, host_val;
64
65
- aplic->bitfield_words = (aplic->num_irqs + 31) >> 5;
66
- aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs);
67
- aplic->state = g_new0(uint32_t, aplic->num_irqs);
68
- aplic->target = g_new0(uint32_t, aplic->num_irqs);
69
- if (!aplic->msimode) {
70
- for (i = 0; i < aplic->num_irqs; i++) {
71
- aplic->target[i] = 1;
72
+ if (!is_kvm_aia(aplic->msimode)) {
73
+ aplic->bitfield_words = (aplic->num_irqs + 31) >> 5;
74
+ aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs);
75
+ aplic->state = g_new0(uint32_t, aplic->num_irqs);
76
+ aplic->target = g_new0(uint32_t, aplic->num_irqs);
77
+ if (!aplic->msimode) {
78
+ for (i = 0; i < aplic->num_irqs; i++) {
79
+ aplic->target[i] = 1;
80
+ }
81
}
82
- }
83
- aplic->idelivery = g_new0(uint32_t, aplic->num_harts);
84
- aplic->iforce = g_new0(uint32_t, aplic->num_harts);
85
- aplic->ithreshold = g_new0(uint32_t, aplic->num_harts);
86
+ aplic->idelivery = g_new0(uint32_t, aplic->num_harts);
87
+ aplic->iforce = g_new0(uint32_t, aplic->num_harts);
88
+ aplic->ithreshold = g_new0(uint32_t, aplic->num_harts);
89
90
- memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops, aplic,
91
- TYPE_RISCV_APLIC, aplic->aperture_size);
92
- sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio);
93
+ memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops,
94
+ aplic, TYPE_RISCV_APLIC, aplic->aperture_size);
95
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio);
96
+ }
97
98
/*
99
* Only root APLICs have hardware IRQ lines. All non-root APLICs
100
* have IRQ lines delegated by their parent APLIC.
101
*/
102
if (!aplic->parent) {
103
- qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
104
+ if (is_kvm_aia(aplic->msimode)) {
105
+ qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs);
106
+ } else {
107
+ qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
108
+ }
109
}
110
111
/* Create output IRQ lines for non-MSI mode */
112
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
113
qdev_prop_set_bit(dev, "mmode", mmode);
114
115
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
116
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
111
+
117
+
112
+ if (!visit_type_bool(v, name, &value, errp)) {
118
+ if (!is_kvm_aia(msimode)) {
113
+ return;
119
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
114
+ }
120
+ }
121
122
if (parent) {
123
riscv_aplic_add_child(parent, dev);
124
diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c
125
index XXXXXXX..XXXXXXX 100644
126
--- a/hw/intc/riscv_imsic.c
127
+++ b/hw/intc/riscv_imsic.c
128
@@ -XXX,XX +XXX,XX @@
129
#include "target/riscv/cpu.h"
130
#include "target/riscv/cpu_bits.h"
131
#include "sysemu/sysemu.h"
132
+#include "sysemu/kvm.h"
133
#include "migration/vmstate.h"
134
135
#define IMSIC_MMIO_PAGE_LE 0x00
136
@@ -XXX,XX +XXX,XX @@ static void riscv_imsic_write(void *opaque, hwaddr addr, uint64_t value,
137
goto err;
138
}
139
140
+#if defined(CONFIG_KVM)
141
+ if (kvm_irqchip_in_kernel()) {
142
+ struct kvm_msi msi;
115
+
143
+
116
+ host_val = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
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);
117
+
147
+
118
+ /*
148
+ kvm_vm_ioctl(kvm_state, KVM_SIGNAL_MSI, &msi);
119
+ * Ignore if the user is setting the same value
120
+ * as the host.
121
+ */
122
+ if (value == host_val) {
123
+ return;
124
+ }
125
+
126
+ if (!multi_ext_cfg->supported) {
127
+ /*
128
+ * Error out if the user is trying to enable an
129
+ * extension that KVM doesn't support. Ignore
130
+ * option otherwise.
131
+ */
132
+ if (value) {
133
+ error_setg(errp, "KVM does not support disabling extension %s",
134
+ multi_ext_cfg->name);
135
+ }
136
+
149
+
137
+ return;
150
+ return;
138
+ }
151
+ }
152
+#endif
139
+
153
+
140
+ multi_ext_cfg->user_set = true;
154
/* Writes only supported for MSI little-endian registers */
141
+ kvm_cpu_cfg_set(cpu, multi_ext_cfg, value);
155
page = addr >> IMSIC_MMIO_PAGE_SHIFT;
142
+}
156
if ((addr & (IMSIC_MMIO_PAGE_SZ - 1)) == IMSIC_MMIO_PAGE_LE) {
143
+
157
@@ -XXX,XX +XXX,XX @@ static void riscv_imsic_realize(DeviceState *dev, Error **errp)
144
static void kvm_riscv_add_cpu_user_properties(Object *cpu_obj)
158
CPUState *cpu = cpu_by_arch_id(imsic->hartid);
145
{
159
CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
146
int i;
160
147
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_add_cpu_user_properties(Object *cpu_obj)
161
- imsic->num_eistate = imsic->num_pages * imsic->num_irqs;
148
object_property_set_description(cpu_obj, misa_cfg->name,
162
- imsic->eidelivery = g_new0(uint32_t, imsic->num_pages);
149
misa_cfg->description);
163
- imsic->eithreshold = g_new0(uint32_t, imsic->num_pages);
150
}
164
- imsic->eistate = g_new0(uint32_t, imsic->num_eistate);
151
+
165
+ if (!kvm_irqchip_in_kernel()) {
152
+ for (i = 0; i < ARRAY_SIZE(kvm_multi_ext_cfgs); i++) {
166
+ imsic->num_eistate = imsic->num_pages * imsic->num_irqs;
153
+ KVMCPUConfig *multi_cfg = &kvm_multi_ext_cfgs[i];
167
+ imsic->eidelivery = g_new0(uint32_t, imsic->num_pages);
154
+
168
+ imsic->eithreshold = g_new0(uint32_t, imsic->num_pages);
155
+ object_property_add(cpu_obj, multi_cfg->name, "bool",
169
+ imsic->eistate = g_new0(uint32_t, imsic->num_eistate);
156
+ NULL,
157
+ kvm_cpu_set_multi_ext_cfg,
158
+ NULL, multi_cfg);
159
+ }
170
+ }
160
}
171
161
172
memory_region_init_io(&imsic->mmio, OBJECT(dev), &riscv_imsic_ops,
162
static int kvm_riscv_get_regs_core(CPUState *cs)
173
imsic, TYPE_RISCV_IMSIC,
163
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_misa_ext_mask(RISCVCPU *cpu,
164
env->misa_ext = env->misa_ext_mask;
165
}
166
167
+static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
168
+{
169
+ CPURISCVState *env = &cpu->env;
170
+ uint64_t val;
171
+ int i, ret;
172
+
173
+ for (i = 0; i < ARRAY_SIZE(kvm_multi_ext_cfgs); i++) {
174
+ KVMCPUConfig *multi_ext_cfg = &kvm_multi_ext_cfgs[i];
175
+ struct kvm_one_reg reg;
176
+
177
+ reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_ISA_EXT,
178
+ multi_ext_cfg->kvm_reg_id);
179
+ reg.addr = (uint64_t)&val;
180
+ ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, &reg);
181
+ if (ret != 0) {
182
+ if (errno == EINVAL) {
183
+ /* Silently default to 'false' if KVM does not support it. */
184
+ multi_ext_cfg->supported = false;
185
+ val = false;
186
+ } else {
187
+ error_report("Unable to read ISA_EXT KVM register %s, "
188
+ "error %d", multi_ext_cfg->name, ret);
189
+ kvm_riscv_destroy_scratch_vcpu(kvmcpu);
190
+ exit(EXIT_FAILURE);
191
+ }
192
+ } else {
193
+ multi_ext_cfg->supported = true;
194
+ }
195
+
196
+ kvm_cpu_cfg_set(cpu, multi_ext_cfg, val);
197
+ }
198
+}
199
+
200
void kvm_riscv_init_user_properties(Object *cpu_obj)
201
{
202
RISCVCPU *cpu = RISCV_CPU(cpu_obj);
203
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_init_user_properties(Object *cpu_obj)
204
kvm_riscv_add_cpu_user_properties(cpu_obj);
205
kvm_riscv_init_machine_ids(cpu, &kvmcpu);
206
kvm_riscv_init_misa_ext_mask(cpu, &kvmcpu);
207
+ kvm_riscv_init_multiext_cfg(cpu, &kvmcpu);
208
209
kvm_riscv_destroy_scratch_vcpu(&kvmcpu);
210
}
211
--
174
--
212
2.40.1
175
2.41.0
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
The Advanced Core Local Interruptor (ACLINT) device can
3
Select KVM AIA when the host kernel has in-kernel AIA chip support.
4
only be used with TCG. Check for TCG enabled instead of
4
Since KVM AIA only has one APLIC instance, we map the QEMU APLIC
5
KVM being not. Only add the property when TCG is used.
5
devices to KVM APLIC.
6
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
8
Reviewed-by: Jim Shu <jim.shu@sifive.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
10
Message-Id: <20230629121103.87733-3-philmd@linaro.org>
11
Message-ID: <20230727102439.22554-6-yongxuan.wang@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
---
13
docs/system/riscv/virt.rst | 1 +
14
hw/riscv/virt.c | 94 +++++++++++++++++++++++++++++++++----------------
14
hw/riscv/virt.c | 18 ++++++++++--------
15
1 file changed, 63 insertions(+), 31 deletions(-)
15
2 files changed, 11 insertions(+), 8 deletions(-)
16
16
17
diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst
18
index XXXXXXX..XXXXXXX 100644
19
--- a/docs/system/riscv/virt.rst
20
+++ b/docs/system/riscv/virt.rst
21
@@ -XXX,XX +XXX,XX @@ The following machine-specific options are supported:
22
23
When this option is "on", ACLINT devices will be emulated instead of
24
SiFive CLINT. When not specified, this option is assumed to be "off".
25
+ This option is restricted to the TCG accelerator.
26
27
- aia=[none|aplic|aplic-imsic]
28
29
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
30
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/riscv/virt.c
19
--- a/hw/riscv/virt.c
32
+++ b/hw/riscv/virt.c
20
+++ b/hw/riscv/virt.c
33
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
34
#include "chardev/char.h"
22
#include "hw/riscv/virt.h"
35
#include "sysemu/device_tree.h"
23
#include "hw/riscv/boot.h"
36
#include "sysemu/sysemu.h"
24
#include "hw/riscv/numa.h"
37
+#include "sysemu/tcg.h"
25
+#include "kvm_riscv.h"
38
#include "sysemu/kvm.h"
26
#include "hw/intc/riscv_aclint.h"
39
#include "sysemu/tpm.h"
27
#include "hw/intc/riscv_aplic.h"
40
#include "hw/pci/pci.h"
28
#include "hw/intc/riscv_imsic.h"
29
@@ -XXX,XX +XXX,XX @@
30
#error "Can't accommodate all IMSIC groups in address space"
31
#endif
32
33
+/* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU. */
34
+static bool virt_use_kvm_aia(RISCVVirtState *s)
35
+{
36
+ return kvm_irqchip_in_kernel() && s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
37
+}
38
+
39
static const MemMapEntry virt_memmap[] = {
40
[VIRT_DEBUG] = { 0x0, 0x100 },
41
[VIRT_MROM] = { 0x1000, 0xf000 },
42
@@ -XXX,XX +XXX,XX @@ static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
43
uint32_t *intc_phandles,
44
uint32_t aplic_phandle,
45
uint32_t aplic_child_phandle,
46
- bool m_mode)
47
+ bool m_mode, int num_harts)
48
{
49
int cpu;
50
char *aplic_name;
51
uint32_t *aplic_cells;
52
MachineState *ms = MACHINE(s);
53
54
- aplic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
55
+ aplic_cells = g_new0(uint32_t, num_harts * 2);
56
57
- for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
58
+ for (cpu = 0; cpu < num_harts; cpu++) {
59
aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
60
aplic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
61
}
62
@@ -XXX,XX +XXX,XX @@ static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
63
64
if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
65
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
66
- aplic_cells,
67
- s->soc[socket].num_harts * sizeof(uint32_t) * 2);
68
+ aplic_cells, num_harts * sizeof(uint32_t) * 2);
69
} else {
70
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent", msi_phandle);
71
}
72
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
73
uint32_t msi_s_phandle,
74
uint32_t *phandle,
75
uint32_t *intc_phandles,
76
- uint32_t *aplic_phandles)
77
+ uint32_t *aplic_phandles,
78
+ int num_harts)
79
{
80
char *aplic_name;
81
unsigned long aplic_addr;
82
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
83
create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_M].size,
84
msi_m_phandle, intc_phandles,
85
aplic_m_phandle, aplic_s_phandle,
86
- true);
87
+ true, num_harts);
88
}
89
90
/* S-level APLIC node */
91
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
92
create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_S].size,
93
msi_s_phandle, intc_phandles,
94
aplic_s_phandle, 0,
95
- false);
96
+ false, num_harts);
97
98
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
99
41
@@ -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,
42
101
*msi_pcie_phandle = msi_s_phandle;
43
g_free(clust_name);
102
}
44
103
45
- if (!kvm_enabled()) {
104
- phandle_pos = ms->smp.cpus;
46
+ if (tcg_enabled()) {
105
- for (socket = (socket_count - 1); socket >= 0; socket--) {
47
if (s->have_aclint) {
106
- phandle_pos -= s->soc[socket].num_harts;
48
create_fdt_socket_aclint(s, memmap, socket,
107
-
49
&intc_phandles[phandle_pos]);
108
- if (s->aia_type == VIRT_AIA_TYPE_NONE) {
109
- create_fdt_socket_plic(s, memmap, socket, phandle,
110
- &intc_phandles[phandle_pos], xplic_phandles);
111
- } else {
112
- create_fdt_socket_aplic(s, memmap, socket,
113
- msi_m_phandle, msi_s_phandle, phandle,
114
- &intc_phandles[phandle_pos], xplic_phandles);
115
+ /* KVM AIA only has one APLIC instance */
116
+ if (virt_use_kvm_aia(s)) {
117
+ create_fdt_socket_aplic(s, memmap, 0,
118
+ msi_m_phandle, msi_s_phandle, phandle,
119
+ &intc_phandles[0], xplic_phandles,
120
+ ms->smp.cpus);
121
+ } else {
122
+ phandle_pos = ms->smp.cpus;
123
+ for (socket = (socket_count - 1); socket >= 0; socket--) {
124
+ phandle_pos -= s->soc[socket].num_harts;
125
+
126
+ if (s->aia_type == VIRT_AIA_TYPE_NONE) {
127
+ create_fdt_socket_plic(s, memmap, socket, phandle,
128
+ &intc_phandles[phandle_pos],
129
+ xplic_phandles);
130
+ } else {
131
+ create_fdt_socket_aplic(s, memmap, socket,
132
+ msi_m_phandle, msi_s_phandle, phandle,
133
+ &intc_phandles[phandle_pos],
134
+ xplic_phandles,
135
+ s->soc[socket].num_harts);
136
+ }
137
}
138
}
139
140
g_free(intc_phandles);
141
142
- for (socket = 0; socket < socket_count; socket++) {
143
- if (socket == 0) {
144
- *irq_mmio_phandle = xplic_phandles[socket];
145
- *irq_virtio_phandle = xplic_phandles[socket];
146
- *irq_pcie_phandle = xplic_phandles[socket];
147
- }
148
- if (socket == 1) {
149
- *irq_virtio_phandle = xplic_phandles[socket];
150
- *irq_pcie_phandle = xplic_phandles[socket];
151
- }
152
- if (socket == 2) {
153
- *irq_pcie_phandle = xplic_phandles[socket];
154
+ if (virt_use_kvm_aia(s)) {
155
+ *irq_mmio_phandle = xplic_phandles[0];
156
+ *irq_virtio_phandle = xplic_phandles[0];
157
+ *irq_pcie_phandle = xplic_phandles[0];
158
+ } else {
159
+ for (socket = 0; socket < socket_count; socket++) {
160
+ if (socket == 0) {
161
+ *irq_mmio_phandle = xplic_phandles[socket];
162
+ *irq_virtio_phandle = xplic_phandles[socket];
163
+ *irq_pcie_phandle = xplic_phandles[socket];
164
+ }
165
+ if (socket == 1) {
166
+ *irq_virtio_phandle = xplic_phandles[socket];
167
+ *irq_pcie_phandle = xplic_phandles[socket];
168
+ }
169
+ if (socket == 2) {
170
+ *irq_pcie_phandle = xplic_phandles[socket];
171
+ }
172
}
173
}
174
50
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
175
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
51
hart_count, &error_abort);
176
}
52
sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_fatal);
177
}
53
178
54
- if (!kvm_enabled()) {
179
+ if (virt_use_kvm_aia(s)) {
55
+ if (tcg_enabled()) {
180
+ kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT,
56
if (s->have_aclint) {
181
+ VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS,
57
if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) {
182
+ memmap[VIRT_APLIC_S].base,
58
/* Per-socket ACLINT MTIMER */
183
+ memmap[VIRT_IMSIC_S].base,
59
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
184
+ s->aia_guests);
60
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
61
#endif
62
63
- object_class_property_add_bool(oc, "aclint", virt_get_aclint,
64
- virt_set_aclint);
65
- object_class_property_set_description(oc, "aclint",
66
- "Set on/off to enable/disable "
67
- "emulating ACLINT devices");
68
-
69
+ if (tcg_enabled()) {
70
+ object_class_property_add_bool(oc, "aclint", virt_get_aclint,
71
+ virt_set_aclint);
72
+ object_class_property_set_description(oc, "aclint",
73
+ "Set on/off to enable/disable "
74
+ "emulating ACLINT devices");
75
+ }
185
+ }
76
object_class_property_add_str(oc, "aia", virt_get_aia,
186
+
77
virt_set_aia);
187
if (riscv_is_32bit(&s->soc[0])) {
78
object_class_property_set_description(oc, "aia",
188
#if HOST_LONG_BITS == 64
189
/* limit RAM size in a 32-bit system */
79
--
190
--
80
2.40.1
191
2.41.0
81
82
diff view generated by jsdifflib
1
From: Lakshmi Bai Raja Subramanian <lakshmi.bai.rajasubramanian@bodhicomputing.com>
1
From: Conor Dooley <conor.dooley@microchip.com>
2
2
3
fdt_load_addr was previously declared as uint32_t which doe not match
3
On a dtb dumped from the virt machine, dt-validate complains:
4
with the return type of riscv_compute_fdt_addr().
4
soc: pmu: {'riscv,event-to-mhpmcounters': [[1, 1, 524281], [2, 2, 524284], [65561, 65561, 524280], [65563, 65563, 524280], [65569, 65569, 524280]], 'compatible': ['riscv,pmu']} should not be valid under {'type': 'object'}
5
from schema $id: http://devicetree.org/schemas/simple-bus.yaml#
6
That's pretty cryptic, but running the dtb back through dtc produces
7
something a lot more reasonable:
8
Warning (simple_bus_reg): /soc/pmu: missing or empty reg/ranges property
5
9
6
This patch modifies the fdt_load_addr type from a uint32_t to a uint64_t
10
Moving the riscv,pmu node out of the soc bus solves the problem.
7
to match the riscv_compute_fdt_addr() return type.
8
11
9
This fixes calculating the fdt address when DRAM is mapped to higher
12
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
10
64-bit address.
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
11
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Signed-off-by: Lakshmi Bai Raja Subramanian <lakshmi.bai.rajasubramanian@bodhicomputing.com>
15
Message-ID: <20230727-groom-decline-2c57ce42841c@spud>
14
[ Change by AF:
15
- Cleanup commit title and message
16
]
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-Id: <168872495192.6334.3845988291412774261-1@git.sr.ht>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
17
---
21
hw/riscv/virt.c | 2 +-
18
hw/riscv/virt.c | 2 +-
22
1 file changed, 1 insertion(+), 1 deletion(-)
19
1 file changed, 1 insertion(+), 1 deletion(-)
23
20
24
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
25
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/riscv/virt.c
23
--- a/hw/riscv/virt.c
27
+++ b/hw/riscv/virt.c
24
+++ b/hw/riscv/virt.c
28
@@ -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)
29
target_ulong start_addr = memmap[VIRT_DRAM].base;
26
MachineState *ms = MACHINE(s);
30
target_ulong firmware_end_addr, kernel_start_addr;
27
RISCVCPU hart = s->soc[0].harts[0];
31
const char *firmware_name = riscv_default_firmware_name(&s->soc[0]);
28
32
- uint32_t fdt_load_addr;
29
- pmu_name = g_strdup_printf("/soc/pmu");
33
+ uint64_t fdt_load_addr;
30
+ pmu_name = g_strdup_printf("/pmu");
34
uint64_t kernel_entry = 0;
31
qemu_fdt_add_subnode(ms->fdt, pmu_name);
35
BlockBackend *pflash_blk0;
32
qemu_fdt_setprop_string(ms->fdt, pmu_name, "compatible", "riscv,pmu");
36
33
riscv_pmu_generate_fdt_node(ms->fdt, hart.cfg.pmu_num, pmu_name);
37
--
34
--
38
2.40.1
35
2.41.0
diff view generated by jsdifflib
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
2
2
3
Pointer mask is also affected by MPRV which means cur_pmbase/pmmask
3
The Svadu specification updated the name of the *envcfg bit from
4
should also take MPRV into consideration. As pointer mask for instruction
4
HADE to ADUE.
5
is not supported currently, so we can directly update cur_pmbase/pmmask
6
based on address related mode and xlen affected by MPRV now.
7
5
8
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
7
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Message-Id: <20230614032547.35895-3-liweiwei@iscas.ac.cn>
9
Message-ID: <20230816141916.66898-1-liweiwei@iscas.ac.cn>
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/cpu_helper.c | 7 +++++--
12
target/riscv/cpu_bits.h | 8 ++++----
15
target/riscv/csr.c | 27 ++++++++++++++++++++-------
13
target/riscv/cpu.c | 4 ++--
16
2 files changed, 25 insertions(+), 9 deletions(-)
14
target/riscv/cpu_helper.c | 6 +++---
15
target/riscv/csr.c | 12 ++++++------
16
4 files changed, 15 insertions(+), 15 deletions(-)
17
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++) {
18
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
19
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/cpu_helper.c
70
--- a/target/riscv/cpu_helper.c
21
+++ b/target/riscv/cpu_helper.c
71
+++ b/target/riscv/cpu_helper.c
22
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
72
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
23
void riscv_cpu_update_mask(CPURISCVState *env)
73
}
24
{
74
25
target_ulong mask = 0, base = 0;
75
bool pbmte = env->menvcfg & MENVCFG_PBMTE;
26
+ RISCVMXL xl = env->xl;
76
- bool hade = env->menvcfg & MENVCFG_HADE;
27
/*
77
+ bool adue = env->menvcfg & MENVCFG_ADUE;
28
* TODO: Current RVJ spec does not specify
78
29
* how the extension interacts with XLEN.
79
if (first_stage && two_stage && env->virt_enabled) {
30
*/
80
pbmte = pbmte && (env->henvcfg & HENVCFG_PBMTE);
31
#ifndef CONFIG_USER_ONLY
81
- hade = hade && (env->henvcfg & HENVCFG_HADE);
32
+ int mode = cpu_address_mode(env);
82
+ adue = adue && (env->henvcfg & HENVCFG_ADUE);
33
+ xl = cpu_get_xl(env, mode);
83
}
34
if (riscv_has_ext(env, RVJ)) {
84
35
- switch (env->priv) {
85
int ptshift = (levels - 1) * ptidxbits;
36
+ switch (mode) {
86
@@ -XXX,XX +XXX,XX @@ restart:
37
case PRV_M:
87
38
if (env->mmte & M_PM_ENABLE) {
88
/* Page table updates need to be atomic with MTTCG enabled */
39
mask = env->mpmmask;
89
if (updated_pte != pte && !is_debug) {
40
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_update_mask(CPURISCVState *env)
90
- if (!hade) {
91
+ if (!adue) {
92
return TRANSLATE_FAIL;
41
}
93
}
42
}
94
43
#endif
44
- if (env->xl == MXL_RV32) {
45
+ if (xl == MXL_RV32) {
46
env->cur_pmmask = mask & UINT32_MAX;
47
env->cur_pmbase = base & UINT32_MAX;
48
} else {
49
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
95
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
50
index XXXXXXX..XXXXXXX 100644
96
index XXXXXXX..XXXXXXX 100644
51
--- a/target/riscv/csr.c
97
--- a/target/riscv/csr.c
52
+++ b/target/riscv/csr.c
98
+++ b/target/riscv/csr.c
53
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
99
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
100
if (riscv_cpu_mxl(env) == MXL_RV64) {
101
mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
102
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
103
- (cfg->ext_svadu ? MENVCFG_HADE : 0);
104
+ (cfg->ext_svadu ? MENVCFG_ADUE : 0);
105
}
106
env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
107
108
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
109
const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
110
uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
111
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
112
- (cfg->ext_svadu ? MENVCFG_HADE : 0);
113
+ (cfg->ext_svadu ? MENVCFG_ADUE : 0);
114
uint64_t valh = (uint64_t)val << 32;
115
116
env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
117
@@ -XXX,XX +XXX,XX @@ static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
118
* henvcfg.stce is read_only 0 when menvcfg.stce = 0
119
* henvcfg.hade is read_only 0 when menvcfg.hade = 0
54
*/
120
*/
55
if (env->debugger) {
121
- *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) |
56
env->xl = cpu_recompute_xl(env);
122
+ *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
57
- riscv_cpu_update_mask(env);
123
env->menvcfg);
58
}
59
+
60
+ riscv_cpu_update_mask(env);
61
return RISCV_EXCP_NONE;
124
return RISCV_EXCP_NONE;
62
}
125
}
63
126
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
64
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mpmmask(CPURISCVState *env, int csrno,
65
uint64_t mstatus;
66
67
env->mpmmask = val;
68
- if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
69
+ if ((cpu_address_mode(env) == PRV_M) && (env->mmte & M_PM_ENABLE)) {
70
env->cur_pmmask = val;
71
}
127
}
72
env->mmte |= EXT_STATUS_DIRTY;
128
73
@@ -XXX,XX +XXX,XX @@ static RISCVException write_spmmask(CPURISCVState *env, int csrno,
129
if (riscv_cpu_mxl(env) == MXL_RV64) {
74
return RISCV_EXCP_NONE;
130
- mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE);
131
+ mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE);
75
}
132
}
76
env->spmmask = val;
133
77
- if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
134
env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
78
+ if ((cpu_address_mode(env) == PRV_S) && (env->mmte & S_PM_ENABLE)) {
135
@@ -XXX,XX +XXX,XX @@ static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
79
env->cur_pmmask = val;
136
return ret;
80
+ if (cpu_get_xl(env, PRV_S) == MXL_RV32) {
81
+ env->cur_pmmask &= UINT32_MAX;
82
+ }
83
}
137
}
84
env->mmte |= EXT_STATUS_DIRTY;
138
85
139
- *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) |
86
@@ -XXX,XX +XXX,XX @@ static RISCVException write_upmmask(CPURISCVState *env, int csrno,
140
+ *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
87
return RISCV_EXCP_NONE;
141
env->menvcfg)) >> 32;
88
}
142
return RISCV_EXCP_NONE;
89
env->upmmask = val;
143
}
90
- if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
144
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
91
+ if ((cpu_address_mode(env) == PRV_U) && (env->mmte & U_PM_ENABLE)) {
145
target_ulong val)
92
env->cur_pmmask = val;
146
{
93
+ if (cpu_get_xl(env, PRV_U) == MXL_RV32) {
147
uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE |
94
+ env->cur_pmmask &= UINT32_MAX;
148
- HENVCFG_HADE);
95
+ }
149
+ HENVCFG_ADUE);
96
}
150
uint64_t valh = (uint64_t)val << 32;
97
env->mmte |= EXT_STATUS_DIRTY;
151
RISCVException ret;
98
99
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mpmbase(CPURISCVState *env, int csrno,
100
uint64_t mstatus;
101
102
env->mpmbase = val;
103
- if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
104
+ if ((cpu_address_mode(env) == PRV_M) && (env->mmte & M_PM_ENABLE)) {
105
env->cur_pmbase = val;
106
}
107
env->mmte |= EXT_STATUS_DIRTY;
108
@@ -XXX,XX +XXX,XX @@ static RISCVException write_spmbase(CPURISCVState *env, int csrno,
109
return RISCV_EXCP_NONE;
110
}
111
env->spmbase = val;
112
- if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
113
+ if ((cpu_address_mode(env) == PRV_S) && (env->mmte & S_PM_ENABLE)) {
114
env->cur_pmbase = val;
115
+ if (cpu_get_xl(env, PRV_S) == MXL_RV32) {
116
+ env->cur_pmbase &= UINT32_MAX;
117
+ }
118
}
119
env->mmte |= EXT_STATUS_DIRTY;
120
121
@@ -XXX,XX +XXX,XX @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
122
return RISCV_EXCP_NONE;
123
}
124
env->upmbase = val;
125
- if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
126
+ if ((cpu_address_mode(env) == PRV_U) && (env->mmte & U_PM_ENABLE)) {
127
env->cur_pmbase = val;
128
+ if (cpu_get_xl(env, PRV_U) == MXL_RV32) {
129
+ env->cur_pmbase &= UINT32_MAX;
130
+ }
131
}
132
env->mmte |= EXT_STATUS_DIRTY;
133
152
134
--
153
--
135
2.40.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
We're going to change the handling of mvendorid/marchid/mimpid by the
3
In the same emulated RISC-V host, the 'host' KVM CPU takes 4 times
4
KVM driver. Since these are always present in all CPUs let's put the
4
longer to boot than the 'rv64' KVM CPU.
5
same validation for everyone.
6
5
7
It doesn't make sense to allow 'mvendorid' to be different than it
6
The reason is an unintended behavior of riscv_cpu_satp_mode_finalize()
8
is already set in named (vendor) CPUs. Generic (dynamic) CPUs can have
7
when satp_mode.supported = 0, i.e. when cpu_init() does not set
9
any 'mvendorid' they want.
8
satp_mode_max_supported(). satp_mode_max_from_map(map) does:
10
9
11
Change 'mvendorid' to be a class property created via
10
31 - __builtin_clz(map)
12
'object_class_property_add', instead of using the DEFINE_PROP_UINT32()
13
macro. This allow us to define a custom setter for it that will verify,
14
for named CPUs, if mvendorid is different than it is already set by the
15
CPU. This is the error thrown for the 'veyron-v1' CPU if 'mvendorid' is
16
set to an invalid value:
17
11
18
$ qemu-system-riscv64 -M virt -nographic -cpu veyron-v1,mvendorid=2
12
This means that, if satp_mode.supported = 0, satp_mode_supported_max
19
qemu-system-riscv64: can't apply global veyron-v1-riscv-cpu.mvendorid=2:
13
wil be '31 - 32'. But this is C, so satp_mode_supported_max will gladly
20
Unable to change veyron-v1-riscv-cpu mvendorid (0x61f)
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
21
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")
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
41
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
23
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
42
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
24
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
43
Message-ID: <20230817152903.694926-1-dbarboza@ventanamicro.com>
25
Message-Id: <20230706101738.460804-4-dbarboza@ventanamicro.com>
26
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
44
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
---
45
---
28
target/riscv/cpu.c | 38 +++++++++++++++++++++++++++++++++++++-
46
target/riscv/cpu.c | 23 ++++++++++++++++++++---
29
1 file changed, 37 insertions(+), 1 deletion(-)
47
1 file changed, 20 insertions(+), 3 deletions(-)
30
48
31
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
49
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
32
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/cpu.c
51
--- a/target/riscv/cpu.c
34
+++ b/target/riscv/cpu.c
52
+++ b/target/riscv/cpu.c
35
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_add_user_properties(Object *obj)
53
@@ -XXX,XX +XXX,XX @@ static uint8_t satp_mode_from_str(const char *satp_mode_str)
36
static Property riscv_cpu_properties[] = {
54
37
DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
55
uint8_t satp_mode_max_from_map(uint32_t map)
38
56
{
39
- DEFINE_PROP_UINT32("mvendorid", RISCVCPU, cfg.mvendorid, 0),
57
+ /*
40
DEFINE_PROP_UINT64("marchid", RISCVCPU, cfg.marchid, RISCV_CPU_MARCHID),
58
+ * 'map = 0' will make us return (31 - 32), which C will
41
DEFINE_PROP_UINT64("mimpid", RISCVCPU, cfg.mimpid, RISCV_CPU_MIMPID),
59
+ * happily overflow to UINT_MAX. There's no good result to
42
60
+ * return if 'map = 0' (e.g. returning 0 will be ambiguous
43
@@ -XXX,XX +XXX,XX @@ static const struct TCGCPUOps riscv_tcg_ops = {
61
+ * with the result for 'map = 1').
44
#endif /* !CONFIG_USER_ONLY */
62
+ *
45
};
63
+ * Assert out if map = 0. Callers will have to deal with
46
64
+ * it outside of this function.
47
+static bool riscv_cpu_is_dynamic(Object *cpu_obj)
65
+ */
48
+{
66
+ g_assert(map > 0);
49
+ return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
50
+}
51
+
67
+
52
+static void cpu_set_mvendorid(Object *obj, Visitor *v, const char *name,
68
/* map here has at least one bit set, so no problem with clz */
53
+ void *opaque, Error **errp)
69
return 31 - __builtin_clz(map);
54
+{
70
}
55
+ bool dynamic_cpu = riscv_cpu_is_dynamic(obj);
71
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
56
+ RISCVCPU *cpu = RISCV_CPU(obj);
72
static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
57
+ uint32_t prev_val = cpu->cfg.mvendorid;
73
{
58
+ uint32_t value;
74
bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
75
- uint8_t satp_mode_map_max;
76
- uint8_t satp_mode_supported_max =
77
- satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
78
+ uint8_t satp_mode_map_max, satp_mode_supported_max;
59
+
79
+
60
+ if (!visit_type_uint32(v, name, &value, errp)) {
80
+ /* The CPU wants the OS to decide which satp mode to use */
81
+ if (cpu->cfg.satp_mode.supported == 0) {
61
+ return;
82
+ return;
62
+ }
83
+ }
63
+
84
+
64
+ if (!dynamic_cpu && prev_val != value) {
85
+ satp_mode_supported_max =
65
+ error_setg(errp, "Unable to change %s mvendorid (0x%x)",
86
+ satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
66
+ object_get_typename(obj), prev_val);
87
67
+ return;
88
if (cpu->cfg.satp_mode.map == 0) {
68
+ }
89
if (cpu->cfg.satp_mode.init == 0) {
69
+
70
+ cpu->cfg.mvendorid = value;
71
+}
72
+
73
+static void cpu_get_mvendorid(Object *obj, Visitor *v, const char *name,
74
+ void *opaque, Error **errp)
75
+{
76
+ bool value = RISCV_CPU(obj)->cfg.mvendorid;
77
+
78
+ visit_type_bool(v, name, &value, errp);
79
+}
80
+
81
static void riscv_cpu_class_init(ObjectClass *c, void *data)
82
{
83
RISCVCPUClass *mcc = RISCV_CPU_CLASS(c);
84
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
85
cc->gdb_get_dynamic_xml = riscv_gdb_get_dynamic_xml;
86
cc->tcg_ops = &riscv_tcg_ops;
87
88
+ object_class_property_add(c, "mvendorid", "uint32", cpu_get_mvendorid,
89
+ cpu_set_mvendorid, NULL, NULL);
90
+
91
device_class_set_props(dc, riscv_cpu_properties);
92
}
93
94
--
90
--
95
2.40.1
91
2.41.0
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Vineet Gupta <vineetg@rivosinc.com>
2
2
3
KVM-specific properties are being created inside target/riscv/kvm.c. But
3
zicond is now codegen supported in both llvm and gcc.
4
at this moment we're gathering all the remaining properties from TCG and
5
adding them as is when running KVM. This creates a situation where
6
non-KVM properties are setting flags to 'true' due to its default
7
settings (e.g. Zawrs). Users can also freely enable them via command
8
line.
9
4
10
This doesn't impact runtime per se because KVM doesn't care about these
5
This change allows seamless enabling/testing of zicond in downstream
11
flags, but code such as riscv_isa_string_ext() take those flags into
6
projects. e.g. currently riscv-gnu-toolchain parses elf attributes
12
account. The result is that, for a KVM guest, setting non-KVM properties
7
to create a cmdline for qemu but fails short of enabling it because of
13
will make them appear in the riscv,isa DT.
8
the "x-" prefix.
14
9
15
We want to keep the same API for both TCG and KVM and at the same time,
10
Signed-off-by: Vineet Gupta <vineetg@rivosinc.com>
16
when running KVM, forbid non-KVM extensions to be enabled internally. We
11
Message-ID: <20230808181715.436395-1-vineetg@rivosinc.com>
17
accomplish both by changing riscv_cpu_add_user_properties() to add a
18
mock boolean property for every non-KVM extension in
19
riscv_cpu_extensions[]. Then, when running KVM, users are still free to
20
set extensions at will, but we'll error out if a non-KVM extension is
21
enabled. Setting such extension to 'false' will be ignored.
22
23
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
24
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
25
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
26
Message-Id: <20230706101738.460804-18-dbarboza@ventanamicro.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
14
---
29
target/riscv/cpu.c | 36 ++++++++++++++++++++++++++++++++++++
15
target/riscv/cpu.c | 2 +-
30
1 file changed, 36 insertions(+)
16
1 file changed, 1 insertion(+), 1 deletion(-)
31
17
32
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
33
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/cpu.c
20
--- a/target/riscv/cpu.c
35
+++ b/target/riscv/cpu.c
21
+++ b/target/riscv/cpu.c
36
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
22
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
37
DEFINE_PROP_END_OF_LIST(),
23
DEFINE_PROP_BOOL("zcf", RISCVCPU, cfg.ext_zcf, false),
38
};
24
DEFINE_PROP_BOOL("zcmp", RISCVCPU, cfg.ext_zcmp, false),
39
25
DEFINE_PROP_BOOL("zcmt", RISCVCPU, cfg.ext_zcmt, false),
40
+
26
+ DEFINE_PROP_BOOL("zicond", RISCVCPU, cfg.ext_zicond, false),
41
+#ifndef CONFIG_USER_ONLY
27
42
+static void cpu_set_cfg_unavailable(Object *obj, Visitor *v,
28
/* Vendor-specific custom extensions */
43
+ const char *name,
29
DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
44
+ void *opaque, Error **errp)
30
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
45
+{
31
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
46
+ const char *propname = opaque;
32
47
+ bool value;
33
/* These are experimental so mark with 'x-' */
48
+
34
- DEFINE_PROP_BOOL("x-zicond", RISCVCPU, cfg.ext_zicond, false),
49
+ if (!visit_type_bool(v, name, &value, errp)) {
35
50
+ return;
36
/* ePMP 0.9.3 */
51
+ }
37
DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
52
+
53
+ if (value) {
54
+ error_setg(errp, "extension %s is not available with KVM",
55
+ propname);
56
+ }
57
+}
58
+#endif
59
+
60
/*
61
* Add CPU properties with user-facing flags.
62
*
63
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_add_user_properties(Object *obj)
64
if (object_property_find(obj, prop->name)) {
65
continue;
66
}
67
+
68
+ /*
69
+ * Set the default to disabled for every extension
70
+ * unknown to KVM and error out if the user attempts
71
+ * to enable any of them.
72
+ *
73
+ * We're giving a pass for non-bool properties since they're
74
+ * not related to the availability of extensions and can be
75
+ * safely ignored as is.
76
+ */
77
+ if (prop->info == &qdev_prop_bool) {
78
+ object_property_add(obj, prop->name, "bool",
79
+ NULL, cpu_set_cfg_unavailable,
80
+ NULL, (void *)prop->name);
81
+ continue;
82
+ }
83
}
84
#endif
85
qdev_property_add_static(dev, prop);
86
--
38
--
87
2.40.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
The absence of a satp mode in riscv_host_cpu_init() is causing the
3
A build with --enable-debug and without KVM will fail as follows:
4
following error:
5
4
6
$ ./qemu/build/qemu-system-riscv64 -machine virt,accel=kvm \
5
/usr/bin/ld: libqemu-riscv64-softmmu.fa.p/hw_riscv_virt.c.o: in function `virt_machine_init':
7
-m 2G -smp 1 -nographic -snapshot \
6
./qemu/build/../hw/riscv/virt.c:1465: undefined reference to `kvm_riscv_aia_create'
8
-kernel ./guest_imgs/Image \
9
-initrd ./guest_imgs/rootfs_kvm_riscv64.img \
10
-append "earlycon=sbi root=/dev/ram rw" \
11
-cpu host
12
**
13
ERROR:../target/riscv/cpu.c:320:satp_mode_str: code should not be
14
reached
15
Bail out! ERROR:../target/riscv/cpu.c:320:satp_mode_str: code should
16
not be reached
17
Aborted
18
7
19
The error is triggered from create_fdt_socket_cpus() in hw/riscv/virt.c.
8
This happens because the code block with "if virt_use_kvm_aia(s)" isn't
20
It's trying to get satp_mode_str for a NULL cpu->cfg.satp_mode.map.
9
being ignored by the debug build, resulting in an undefined reference to
10
a KVM only function.
21
11
22
For this KVM cpu we would need to inherit the satp supported modes
12
Add a 'kvm_enabled()' conditional together with virt_use_kvm_aia() will
23
from the RISC-V host. At this moment this is not possible because the
13
make the compiler crop the kvm_riscv_aia_create() call entirely from a
24
KVM driver does not support it. And even when it does we can't just let
14
non-KVM build. Note that adding the 'kvm_enabled()' conditional inside
25
this broken for every other older kernel.
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.
26
18
27
Since mmu-type is not a required node, according to [1], skip the
19
While we're at it, use kvm_enabled() in all instances where
28
'mmu-type' FDT node if there's no satp_mode set. We'll revisit this
20
virt_use_kvm_aia() is checked to allow the compiler to elide these other
29
logic when we can get satp information from KVM.
21
kvm-only instances as well.
30
22
31
[1] https://github.com/torvalds/linux/blob/master/Documentation/devicetree/bindings/riscv/cpus.yaml
23
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
32
24
Fixes: dbdb99948e ("target/riscv: select KVM AIA in riscv virt machine")
33
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
25
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
34
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
26
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
35
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
36
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
27
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
37
Message-Id: <20230706101738.460804-3-dbarboza@ventanamicro.com>
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Message-ID: <20230830133503.711138-2-dbarboza@ventanamicro.com>
38
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
39
---
31
---
40
hw/riscv/virt.c | 14 +++++++-------
32
hw/riscv/virt.c | 6 +++---
41
1 file changed, 7 insertions(+), 7 deletions(-)
33
1 file changed, 3 insertions(+), 3 deletions(-)
42
34
43
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
44
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/riscv/virt.c
37
--- a/hw/riscv/virt.c
46
+++ b/hw/riscv/virt.c
38
+++ b/hw/riscv/virt.c
47
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket,
39
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
48
s->soc[socket].hartid_base + cpu);
40
}
49
qemu_fdt_add_subnode(ms->fdt, cpu_name);
41
50
42
/* KVM AIA only has one APLIC instance */
51
- satp_mode_max = satp_mode_max_from_map(
43
- if (virt_use_kvm_aia(s)) {
52
- s->soc[socket].harts[cpu].cfg.satp_mode.map);
44
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
53
- sv_name = g_strdup_printf("riscv,%s",
45
create_fdt_socket_aplic(s, memmap, 0,
54
- satp_mode_str(satp_mode_max, is_32_bit));
46
msi_m_phandle, msi_s_phandle, phandle,
55
- qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type", sv_name);
47
&intc_phandles[0], xplic_phandles,
56
- g_free(sv_name);
48
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
57
-
49
58
+ if (cpu_ptr->cfg.satp_mode.supported != 0) {
50
g_free(intc_phandles);
59
+ satp_mode_max = satp_mode_max_from_map(cpu_ptr->cfg.satp_mode.map);
51
60
+ sv_name = g_strdup_printf("riscv,%s",
52
- if (virt_use_kvm_aia(s)) {
61
+ satp_mode_str(satp_mode_max, is_32_bit));
53
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
62
+ qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type", sv_name);
54
*irq_mmio_phandle = xplic_phandles[0];
63
+ g_free(sv_name);
55
*irq_virtio_phandle = xplic_phandles[0];
64
+ }
56
*irq_pcie_phandle = xplic_phandles[0];
65
57
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
66
name = riscv_isa_string(cpu_ptr);
58
}
67
qemu_fdt_setprop_string(ms->fdt, cpu_name, "riscv,isa", name);
59
}
60
61
- if (virt_use_kvm_aia(s)) {
62
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
63
kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT,
64
VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS,
65
memmap[VIRT_APLIC_S].base,
68
--
66
--
69
2.40.1
67
2.41.0
70
68
71
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
Using all TCG user properties in KVM is tricky. First because KVM
3
Commit 6df0b37e2ab breaks a --enable-debug build in a non-KVM
4
supports only a small subset of what TCG provides, so most of the
4
environment with the following error:
5
cpu->cfg flags do nothing for KVM.
6
5
7
Second, and more important, we don't have a way of telling if any given
6
/usr/bin/ld: libqemu-riscv64-softmmu.fa.p/hw_intc_riscv_aplic.c.o: in function `riscv_kvm_aplic_request':
8
value is an user input or not. For TCG this has a small impact since we
7
./qemu/build/../hw/intc/riscv_aplic.c:486: undefined reference to `kvm_set_irq'
9
just validating everything and error out if needed. But for KVM it would
8
collect2: error: ld returned 1 exit status
10
be good to know if a given value was set by the user or if it's a value
11
already provided by KVM. Otherwise we don't know how to handle failed
12
kvm_set_one_regs() when writing the configurations back.
13
9
14
These characteristics make it overly complicated to use the same user
10
This happens because the debug build will poke into the
15
facing flags for both KVM and TCG. A simpler approach is to create KVM
11
'if (is_kvm_aia(aplic->msimode))' block and fail to find a reference to
16
specific properties that have specialized logic, forking KVM and TCG use
12
the KVM only function riscv_kvm_aplic_request().
17
cases for those cases only. Fully separating KVM/TCG properties is
18
unneeded at this point - in fact we want the user experience to be as
19
equal as possible, regardless of the acceleration chosen.
20
13
21
We'll start this fork with the MISA properties, adding the MISA bits
14
There are multiple solutions to fix this. We'll go with the same
22
that the KVM driver currently supports. A new KVMCPUConfig type is
15
solution from the previous patch, i.e. add a kvm_enabled() conditional
23
introduced. It'll hold general information about an extension. For MISA
16
to filter out the block. But there's a catch: riscv_kvm_aplic_request()
24
extensions we're going to use the newly created getters of
17
is a local function that would end up being used if the compiler crops
25
misa_ext_infos[] to populate their name and description. 'offset' holds
18
the block, and this won't work. Quoting Richard Henderson's explanation
26
the MISA bit (RVA, RVC, ...). We're calling it 'offset' instead of
19
in [1]:
27
'misa_bit' because this same KVMCPUConfig struct will be used to
28
multi-letter extensions later on.
29
20
30
This new type also holds a 'user_set' flag. This flag will be set when
21
"(...) the compiler won't eliminate entire unused functions with -O0"
31
the user set an option that's different than what is already configured
32
in the host, requiring KVM intervention to write the regs back during
33
kvm_arch_init_vcpu(). Similar mechanics will be implemented for
34
multi-letter extensions as well.
35
22
36
There is no need to duplicate more code than necessary, so we're going
23
We'll solve it by moving riscv_kvm_aplic_request() to kvm.c and add its
37
to use the existing kvm_riscv_init_user_properties() to add the KVM
24
declaration in kvm_riscv.h, where all other KVM specific public
38
specific properties. Any code that is adding a TCG user prop is then
25
functions are already declared. Other archs handles KVM specific code in
39
changed slightly to verify first if there's a KVM prop with the same
26
this manner and we expect to do the same from now on.
40
name already added.
27
28
[1] https://lore.kernel.org/qemu-riscv/d2f1ad02-eb03-138f-9d08-db676deeed05@linaro.org/
41
29
42
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
30
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
43
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
31
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
44
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
32
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
45
Message-Id: <20230706101738.460804-13-dbarboza@ventanamicro.com>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
34
Message-ID: <20230830133503.711138-3-dbarboza@ventanamicro.com>
46
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
47
---
36
---
48
target/riscv/cpu.c | 5 +++
37
target/riscv/kvm_riscv.h | 1 +
49
target/riscv/kvm.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++
38
hw/intc/riscv_aplic.c | 8 ++------
50
2 files changed, 83 insertions(+)
39
target/riscv/kvm.c | 5 +++++
40
3 files changed, 8 insertions(+), 6 deletions(-)
51
41
52
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
42
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
53
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
54
--- a/target/riscv/cpu.c
44
--- a/target/riscv/kvm_riscv.h
55
+++ b/target/riscv/cpu.c
45
+++ b/target/riscv/kvm_riscv.h
56
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
46
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
57
misa_cfg->name = riscv_get_misa_ext_name(bit);
47
uint64_t aia_irq_num, uint64_t aia_msi_num,
58
misa_cfg->description = riscv_get_misa_ext_description(bit);
48
uint64_t aplic_base, uint64_t imsic_base,
59
49
uint64_t guest_num);
60
+ /* Check if KVM already created the property */
50
+void riscv_kvm_aplic_request(void *opaque, int irq, int level);
61
+ if (object_property_find(cpu_obj, misa_cfg->name)) {
51
62
+ continue;
52
#endif
63
+ }
53
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
64
+
54
index XXXXXXX..XXXXXXX 100644
65
object_property_add(cpu_obj, misa_cfg->name, "bool",
55
--- a/hw/intc/riscv_aplic.c
66
cpu_get_misa_ext_cfg,
56
+++ b/hw/intc/riscv_aplic.c
67
cpu_set_misa_ext_cfg,
57
@@ -XXX,XX +XXX,XX @@
58
#include "target/riscv/cpu.h"
59
#include "sysemu/sysemu.h"
60
#include "sysemu/kvm.h"
61
+#include "kvm_riscv.h"
62
#include "migration/vmstate.h"
63
64
#define APLIC_MAX_IDC (1UL << 14)
65
@@ -XXX,XX +XXX,XX @@ static uint32_t riscv_aplic_idc_claimi(RISCVAPLICState *aplic, uint32_t idc)
66
return topi;
67
}
68
69
-static void riscv_kvm_aplic_request(void *opaque, int irq, int level)
70
-{
71
- kvm_set_irq(kvm_state, irq, !!level);
72
-}
73
-
74
static void riscv_aplic_request(void *opaque, int irq, int level)
75
{
76
bool update = false;
77
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
78
* have IRQ lines delegated by their parent APLIC.
79
*/
80
if (!aplic->parent) {
81
- if (is_kvm_aia(aplic->msimode)) {
82
+ if (kvm_enabled() && is_kvm_aia(aplic->msimode)) {
83
qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs);
84
} else {
85
qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
68
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
86
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
69
index XXXXXXX..XXXXXXX 100644
87
index XXXXXXX..XXXXXXX 100644
70
--- a/target/riscv/kvm.c
88
--- a/target/riscv/kvm.c
71
+++ b/target/riscv/kvm.c
89
+++ b/target/riscv/kvm.c
72
@@ -XXX,XX +XXX,XX @@
90
@@ -XXX,XX +XXX,XX @@
73
#include <linux/kvm.h>
91
#include "sysemu/runstate.h"
74
92
#include "hw/riscv/numa.h"
75
#include "qemu/timer.h"
93
76
+#include "qapi/error.h"
94
+void riscv_kvm_aplic_request(void *opaque, int irq, int level)
77
#include "qemu/error-report.h"
78
#include "qemu/main-loop.h"
79
+#include "qapi/visitor.h"
80
#include "sysemu/sysemu.h"
81
#include "sysemu/kvm.h"
82
#include "sysemu/kvm_int.h"
83
@@ -XXX,XX +XXX,XX @@ static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
84
} \
85
} while (0)
86
87
+typedef struct KVMCPUConfig {
88
+ const char *name;
89
+ const char *description;
90
+ target_ulong offset;
91
+ int kvm_reg_id;
92
+ bool user_set;
93
+} KVMCPUConfig;
94
+
95
+#define KVM_MISA_CFG(_bit, _reg_id) \
96
+ {.offset = _bit, .kvm_reg_id = _reg_id}
97
+
98
+/* KVM ISA extensions */
99
+static KVMCPUConfig kvm_misa_ext_cfgs[] = {
100
+ KVM_MISA_CFG(RVA, KVM_RISCV_ISA_EXT_A),
101
+ KVM_MISA_CFG(RVC, KVM_RISCV_ISA_EXT_C),
102
+ KVM_MISA_CFG(RVD, KVM_RISCV_ISA_EXT_D),
103
+ KVM_MISA_CFG(RVF, KVM_RISCV_ISA_EXT_F),
104
+ KVM_MISA_CFG(RVH, KVM_RISCV_ISA_EXT_H),
105
+ KVM_MISA_CFG(RVI, KVM_RISCV_ISA_EXT_I),
106
+ KVM_MISA_CFG(RVM, KVM_RISCV_ISA_EXT_M),
107
+};
108
+
109
+static void kvm_cpu_set_misa_ext_cfg(Object *obj, Visitor *v,
110
+ const char *name,
111
+ void *opaque, Error **errp)
112
+{
95
+{
113
+ KVMCPUConfig *misa_ext_cfg = opaque;
96
+ kvm_set_irq(kvm_state, irq, !!level);
114
+ target_ulong misa_bit = misa_ext_cfg->offset;
115
+ RISCVCPU *cpu = RISCV_CPU(obj);
116
+ CPURISCVState *env = &cpu->env;
117
+ bool value, host_bit;
118
+
119
+ if (!visit_type_bool(v, name, &value, errp)) {
120
+ return;
121
+ }
122
+
123
+ host_bit = env->misa_ext_mask & misa_bit;
124
+
125
+ if (value == host_bit) {
126
+ return;
127
+ }
128
+
129
+ if (!value) {
130
+ misa_ext_cfg->user_set = true;
131
+ return;
132
+ }
133
+
134
+ /*
135
+ * Forbid users to enable extensions that aren't
136
+ * available in the hart.
137
+ */
138
+ error_setg(errp, "Enabling MISA bit '%s' is not allowed: it's not "
139
+ "enabled in the host", misa_ext_cfg->name);
140
+}
97
+}
141
+
98
+
142
+static void kvm_riscv_add_cpu_user_properties(Object *cpu_obj)
99
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
143
+{
100
uint64_t idx)
144
+ int i;
145
+
146
+ for (i = 0; i < ARRAY_SIZE(kvm_misa_ext_cfgs); i++) {
147
+ KVMCPUConfig *misa_cfg = &kvm_misa_ext_cfgs[i];
148
+ int bit = misa_cfg->offset;
149
+
150
+ misa_cfg->name = riscv_get_misa_ext_name(bit);
151
+ misa_cfg->description = riscv_get_misa_ext_description(bit);
152
+
153
+ object_property_add(cpu_obj, misa_cfg->name, "bool",
154
+ NULL,
155
+ kvm_cpu_set_misa_ext_cfg,
156
+ NULL, misa_cfg);
157
+ object_property_set_description(cpu_obj, misa_cfg->name,
158
+ misa_cfg->description);
159
+ }
160
+}
161
+
162
static int kvm_riscv_get_regs_core(CPUState *cs)
163
{
101
{
164
int ret = 0;
165
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_init_user_properties(Object *cpu_obj)
166
return;
167
}
168
169
+ kvm_riscv_add_cpu_user_properties(cpu_obj);
170
kvm_riscv_init_machine_ids(cpu, &kvmcpu);
171
kvm_riscv_init_misa_ext_mask(cpu, &kvmcpu);
172
173
--
102
--
174
2.40.1
103
2.41.0
104
105
diff view generated by jsdifflib
1
From: Robbin Ehn <rehn@rivosinc.com>
1
From: Robbin Ehn <rehn@rivosinc.com>
2
2
3
This patch adds the new syscall for the
3
This patch adds the new extensions in
4
"RISC-V Hardware Probing Interface"
4
linux 6.5 to the hwprobe syscall.
5
(https://docs.kernel.org/riscv/hwprobe.html).
6
5
7
Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com>
6
And fixes RVC check to OR with correct value.
7
The previous variable contains 0 therefore it
8
did work.
9
8
Signed-off-by: Robbin Ehn <rehn@rivosinc.com>
10
Signed-off-by: Robbin Ehn <rehn@rivosinc.com>
9
Message-Id: <06a4543df2aa6101ca9a48f21a3198064b4f1f87.camel@rivosinc.com>
11
Acked-by: Richard Henderson <richard.henderson@linaro.org>
12
Acked-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <bc82203b72d7efb30f1b4a8f9eb3d94699799dc8.camel@rivosinc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
15
---
12
linux-user/riscv/syscall32_nr.h | 1 +
16
linux-user/syscall.c | 14 +++++++++++++-
13
linux-user/riscv/syscall64_nr.h | 1 +
17
1 file changed, 13 insertions(+), 1 deletion(-)
14
linux-user/syscall.c | 146 ++++++++++++++++++++++++++++++++
15
3 files changed, 148 insertions(+)
16
18
17
diff --git a/linux-user/riscv/syscall32_nr.h b/linux-user/riscv/syscall32_nr.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/linux-user/riscv/syscall32_nr.h
20
+++ b/linux-user/riscv/syscall32_nr.h
21
@@ -XXX,XX +XXX,XX @@
22
#define TARGET_NR_accept4 242
23
#define TARGET_NR_arch_specific_syscall 244
24
#define TARGET_NR_riscv_flush_icache (TARGET_NR_arch_specific_syscall + 15)
25
+#define TARGET_NR_riscv_hwprobe (TARGET_NR_arch_specific_syscall + 14)
26
#define TARGET_NR_prlimit64 261
27
#define TARGET_NR_fanotify_init 262
28
#define TARGET_NR_fanotify_mark 263
29
diff --git a/linux-user/riscv/syscall64_nr.h b/linux-user/riscv/syscall64_nr.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/linux-user/riscv/syscall64_nr.h
32
+++ b/linux-user/riscv/syscall64_nr.h
33
@@ -XXX,XX +XXX,XX @@
34
#define TARGET_NR_recvmmsg 243
35
#define TARGET_NR_arch_specific_syscall 244
36
#define TARGET_NR_riscv_flush_icache (TARGET_NR_arch_specific_syscall + 15)
37
+#define TARGET_NR_riscv_hwprobe (TARGET_NR_arch_specific_syscall + 14)
38
#define TARGET_NR_wait4 260
39
#define TARGET_NR_prlimit64 261
40
#define TARGET_NR_fanotify_init 262
41
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
19
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
42
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
43
--- a/linux-user/syscall.c
21
--- a/linux-user/syscall.c
44
+++ b/linux-user/syscall.c
22
+++ b/linux-user/syscall.c
45
@@ -XXX,XX +XXX,XX @@ static int do_getdents64(abi_long dirfd, abi_long arg2, abi_long count)
23
@@ -XXX,XX +XXX,XX @@ static int do_getdents64(abi_long dirfd, abi_long arg2, abi_long count)
46
}
24
#define RISCV_HWPROBE_KEY_IMA_EXT_0 4
47
#endif /* TARGET_NR_getdents64 */
25
#define RISCV_HWPROBE_IMA_FD (1 << 0)
48
26
#define RISCV_HWPROBE_IMA_C (1 << 1)
49
+#if defined(TARGET_NR_riscv_hwprobe)
27
+#define RISCV_HWPROBE_IMA_V (1 << 2)
50
+
28
+#define RISCV_HWPROBE_EXT_ZBA (1 << 3)
51
+#define RISCV_HWPROBE_KEY_MVENDORID 0
29
+#define RISCV_HWPROBE_EXT_ZBB (1 << 4)
52
+#define RISCV_HWPROBE_KEY_MARCHID 1
30
+#define RISCV_HWPROBE_EXT_ZBS (1 << 5)
53
+#define RISCV_HWPROBE_KEY_MIMPID 2
31
54
+
32
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
55
+#define RISCV_HWPROBE_KEY_BASE_BEHAVIOR 3
33
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
56
+#define RISCV_HWPROBE_BASE_BEHAVIOR_IMA (1 << 0)
34
@@ -XXX,XX +XXX,XX @@ static void risc_hwprobe_fill_pairs(CPURISCVState *env,
57
+
35
riscv_has_ext(env, RVD) ?
58
+#define RISCV_HWPROBE_KEY_IMA_EXT_0 4
36
RISCV_HWPROBE_IMA_FD : 0;
59
+#define RISCV_HWPROBE_IMA_FD (1 << 0)
37
value |= riscv_has_ext(env, RVC) ?
60
+#define RISCV_HWPROBE_IMA_C (1 << 1)
38
- RISCV_HWPROBE_IMA_C : pair->value;
61
+
39
+ RISCV_HWPROBE_IMA_C : 0;
62
+#define RISCV_HWPROBE_KEY_CPUPERF_0 5
40
+ value |= riscv_has_ext(env, RVV) ?
63
+#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
41
+ RISCV_HWPROBE_IMA_V : 0;
64
+#define RISCV_HWPROBE_MISALIGNED_EMULATED (1 << 0)
42
+ value |= cfg->ext_zba ?
65
+#define RISCV_HWPROBE_MISALIGNED_SLOW (2 << 0)
43
+ RISCV_HWPROBE_EXT_ZBA : 0;
66
+#define RISCV_HWPROBE_MISALIGNED_FAST (3 << 0)
44
+ value |= cfg->ext_zbb ?
67
+#define RISCV_HWPROBE_MISALIGNED_UNSUPPORTED (4 << 0)
45
+ RISCV_HWPROBE_EXT_ZBB : 0;
68
+#define RISCV_HWPROBE_MISALIGNED_MASK (7 << 0)
46
+ value |= cfg->ext_zbs ?
69
+
47
+ RISCV_HWPROBE_EXT_ZBS : 0;
70
+struct riscv_hwprobe {
48
__put_user(value, &pair->value);
71
+ abi_llong key;
49
break;
72
+ abi_ullong value;
50
case RISCV_HWPROBE_KEY_CPUPERF_0:
73
+};
74
+
75
+static void risc_hwprobe_fill_pairs(CPURISCVState *env,
76
+ struct riscv_hwprobe *pair,
77
+ size_t pair_count)
78
+{
79
+ const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
80
+
81
+ for (; pair_count > 0; pair_count--, pair++) {
82
+ abi_llong key;
83
+ abi_ullong value;
84
+ __put_user(0, &pair->value);
85
+ __get_user(key, &pair->key);
86
+ switch (key) {
87
+ case RISCV_HWPROBE_KEY_MVENDORID:
88
+ __put_user(cfg->mvendorid, &pair->value);
89
+ break;
90
+ case RISCV_HWPROBE_KEY_MARCHID:
91
+ __put_user(cfg->marchid, &pair->value);
92
+ break;
93
+ case RISCV_HWPROBE_KEY_MIMPID:
94
+ __put_user(cfg->mimpid, &pair->value);
95
+ break;
96
+ case RISCV_HWPROBE_KEY_BASE_BEHAVIOR:
97
+ value = riscv_has_ext(env, RVI) &&
98
+ riscv_has_ext(env, RVM) &&
99
+ riscv_has_ext(env, RVA) ?
100
+ RISCV_HWPROBE_BASE_BEHAVIOR_IMA : 0;
101
+ __put_user(value, &pair->value);
102
+ break;
103
+ case RISCV_HWPROBE_KEY_IMA_EXT_0:
104
+ value = riscv_has_ext(env, RVF) &&
105
+ riscv_has_ext(env, RVD) ?
106
+ RISCV_HWPROBE_IMA_FD : 0;
107
+ value |= riscv_has_ext(env, RVC) ?
108
+ RISCV_HWPROBE_IMA_C : pair->value;
109
+ __put_user(value, &pair->value);
110
+ break;
111
+ case RISCV_HWPROBE_KEY_CPUPERF_0:
112
+ __put_user(RISCV_HWPROBE_MISALIGNED_FAST, &pair->value);
113
+ break;
114
+ default:
115
+ __put_user(-1, &pair->key);
116
+ break;
117
+ }
118
+ }
119
+}
120
+
121
+static int cpu_set_valid(abi_long arg3, abi_long arg4)
122
+{
123
+ int ret, i, tmp;
124
+ size_t host_mask_size, target_mask_size;
125
+ unsigned long *host_mask;
126
+
127
+ /*
128
+ * cpu_set_t represent CPU masks as bit masks of type unsigned long *.
129
+ * arg3 contains the cpu count.
130
+ */
131
+ tmp = (8 * sizeof(abi_ulong));
132
+ target_mask_size = ((arg3 + tmp - 1) / tmp) * sizeof(abi_ulong);
133
+ host_mask_size = (target_mask_size + (sizeof(*host_mask) - 1)) &
134
+ ~(sizeof(*host_mask) - 1);
135
+
136
+ host_mask = alloca(host_mask_size);
137
+
138
+ ret = target_to_host_cpu_mask(host_mask, host_mask_size,
139
+ arg4, target_mask_size);
140
+ if (ret != 0) {
141
+ return ret;
142
+ }
143
+
144
+ for (i = 0 ; i < host_mask_size / sizeof(*host_mask); i++) {
145
+ if (host_mask[i] != 0) {
146
+ return 0;
147
+ }
148
+ }
149
+ return -TARGET_EINVAL;
150
+}
151
+
152
+static abi_long do_riscv_hwprobe(CPUArchState *cpu_env, abi_long arg1,
153
+ abi_long arg2, abi_long arg3,
154
+ abi_long arg4, abi_long arg5)
155
+{
156
+ int ret;
157
+ struct riscv_hwprobe *host_pairs;
158
+
159
+ /* flags must be 0 */
160
+ if (arg5 != 0) {
161
+ return -TARGET_EINVAL;
162
+ }
163
+
164
+ /* check cpu_set */
165
+ if (arg3 != 0) {
166
+ ret = cpu_set_valid(arg3, arg4);
167
+ if (ret != 0) {
168
+ return ret;
169
+ }
170
+ } else if (arg4 != 0) {
171
+ return -TARGET_EINVAL;
172
+ }
173
+
174
+ /* no pairs */
175
+ if (arg2 == 0) {
176
+ return 0;
177
+ }
178
+
179
+ host_pairs = lock_user(VERIFY_WRITE, arg1,
180
+ sizeof(*host_pairs) * (size_t)arg2, 0);
181
+ if (host_pairs == NULL) {
182
+ return -TARGET_EFAULT;
183
+ }
184
+ risc_hwprobe_fill_pairs(cpu_env, host_pairs, arg2);
185
+ unlock_user(host_pairs, arg1, sizeof(*host_pairs) * (size_t)arg2);
186
+ return 0;
187
+}
188
+#endif /* TARGET_NR_riscv_hwprobe */
189
+
190
#if defined(TARGET_NR_pivot_root) && defined(__NR_pivot_root)
191
_syscall2(int, pivot_root, const char *, new_root, const char *, put_old)
192
#endif
193
@@ -XXX,XX +XXX,XX @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
194
return ret;
195
#endif
196
197
+#if defined(TARGET_NR_riscv_hwprobe)
198
+ case TARGET_NR_riscv_hwprobe:
199
+ return do_riscv_hwprobe(cpu_env, arg1, arg2, arg3, arg4, arg5);
200
+#endif
201
+
202
default:
203
qemu_log_mask(LOG_UNIMP, "Unsupported syscall: %d\n", num);
204
return -TARGET_ENOSYS;
205
--
51
--
206
2.40.1
52
2.41.0
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Ard Biesheuvel <ardb@kernel.org>
2
2
3
Support for emulating XThead* instruction has been added recently.
3
Use the accelerated SubBytes/ShiftRows/AddRoundKey AES helper to
4
This patch adds support for these instructions to the RISC-V disassembler.
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
Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
Cc: Richard Henderson <richard.henderson@linaro.org>
7
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
10
Cc: Palmer Dabbelt <palmer@dabbelt.com>
9
Message-Id: <20230612111034.3955227-9-christoph.muellner@vrull.eu>
11
Cc: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-ID: <20230831154118.138727-1-ardb@kernel.org>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
17
---
12
disas/riscv-xthead.h | 28 ++
18
target/riscv/crypto_helper.c | 17 +++++------------
13
disas/riscv.h | 12 +
19
1 file changed, 5 insertions(+), 12 deletions(-)
14
target/riscv/cpu_cfg.h | 11 +
15
disas/riscv-xthead.c | 707 +++++++++++++++++++++++++++++++++++++++++
16
disas/riscv.c | 69 ++++
17
disas/meson.build | 1 +
18
6 files changed, 828 insertions(+)
19
create mode 100644 disas/riscv-xthead.h
20
create mode 100644 disas/riscv-xthead.c
21
20
22
diff --git a/disas/riscv-xthead.h b/disas/riscv-xthead.h
21
diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c
23
new file mode 100644
24
index XXXXXXX..XXXXXXX
25
--- /dev/null
26
+++ b/disas/riscv-xthead.h
27
@@ -XXX,XX +XXX,XX @@
28
+/*
29
+ * QEMU disassembler -- RISC-V specific header (xthead*).
30
+ *
31
+ * Copyright (c) 2023 VRULL GmbH
32
+ *
33
+ * SPDX-License-Identifier: GPL-2.0-or-later
34
+ */
35
+
36
+#ifndef DISAS_RISCV_XTHEAD_H
37
+#define DISAS_RISCV_XTHEAD_H
38
+
39
+#include "disas/riscv.h"
40
+
41
+extern const rv_opcode_data xthead_opcode_data[];
42
+
43
+void decode_xtheadba(rv_decode *, rv_isa);
44
+void decode_xtheadbb(rv_decode *, rv_isa);
45
+void decode_xtheadbs(rv_decode *, rv_isa);
46
+void decode_xtheadcmo(rv_decode *, rv_isa);
47
+void decode_xtheadcondmov(rv_decode *, rv_isa);
48
+void decode_xtheadfmemidx(rv_decode *, rv_isa);
49
+void decode_xtheadfmv(rv_decode *, rv_isa);
50
+void decode_xtheadmac(rv_decode *, rv_isa);
51
+void decode_xtheadmemidx(rv_decode *, rv_isa);
52
+void decode_xtheadmempair(rv_decode *, rv_isa);
53
+void decode_xtheadsync(rv_decode *, rv_isa);
54
+
55
+#endif /* DISAS_RISCV_XTHEAD_H */
56
diff --git a/disas/riscv.h b/disas/riscv.h
57
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
58
--- a/disas/riscv.h
23
--- a/target/riscv/crypto_helper.c
59
+++ b/disas/riscv.h
24
+++ b/target/riscv/crypto_helper.c
60
@@ -XXX,XX +XXX,XX @@ typedef enum {
25
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(aes64ks1i)(target_ulong rs1, target_ulong rnum)
61
rv_codec_zcmp_cm_pushpop,
26
62
rv_codec_zcmp_cm_mv,
27
uint8_t enc_rnum = rnum;
63
rv_codec_zcmt_jt,
28
uint32_t temp = (RS1 >> 32) & 0xFFFFFFFF;
64
+ rv_codec_r2_imm5,
29
- uint8_t rcon_ = 0;
65
+ rv_codec_r2,
30
- target_ulong result;
66
+ rv_codec_r2_imm6,
31
+ AESState t, rc = {};
67
+ rv_codec_r_imm2,
32
68
+ rv_codec_r2_immhl,
33
if (enc_rnum != 0xA) {
69
+ rv_codec_r2_imm2_imm5,
34
temp = ror32(temp, 8); /* Rotate right by 8 */
70
} rv_codec;
35
- rcon_ = round_consts[enc_rnum];
71
36
+ rc.w[0] = rc.w[1] = round_consts[enc_rnum];
72
/* structures */
73
@@ -XXX,XX +XXX,XX @@ typedef struct {
74
uint64_t inst;
75
const rv_opcode_data *opcode_data;
76
int32_t imm;
77
+ int32_t imm1;
78
uint16_t op;
79
uint8_t codec;
80
uint8_t rd;
81
@@ -XXX,XX +XXX,XX @@ enum {
82
#define rv_fmt_push_rlist "O\tx,-i"
83
#define rv_fmt_pop_rlist "O\tx,i"
84
#define rv_fmt_zcmt_index "O\ti"
85
+#define rv_fmt_rd_rs1_rs2_imm "O\t0,1,2,i"
86
+#define rv_fmt_frd_rs1_rs2_imm "O\t3,1,2,i"
87
+#define rv_fmt_rd_rs1_immh_imml "O\t0,1,i,j"
88
+#define rv_fmt_rd_rs1_immh_imml_addr "O\t0,(1),i,j"
89
+#define rv_fmt_rd2_imm "O\t0,2,(1),i"
90
91
#endif /* DISAS_RISCV_H */
92
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
93
index XXXXXXX..XXXXXXX 100644
94
--- a/target/riscv/cpu_cfg.h
95
+++ b/target/riscv/cpu_cfg.h
96
@@ -XXX,XX +XXX,XX @@ static inline bool has_xthead_p(const RISCVCPUConfig *cfg)
97
return cfg->ext_ ## ext ; \
98
}
37
}
99
38
100
+MATERIALISE_EXT_PREDICATE(xtheadba)
39
- temp = ((uint32_t)AES_sbox[(temp >> 24) & 0xFF] << 24) |
101
+MATERIALISE_EXT_PREDICATE(xtheadbb)
40
- ((uint32_t)AES_sbox[(temp >> 16) & 0xFF] << 16) |
102
+MATERIALISE_EXT_PREDICATE(xtheadbs)
41
- ((uint32_t)AES_sbox[(temp >> 8) & 0xFF] << 8) |
103
+MATERIALISE_EXT_PREDICATE(xtheadcmo)
42
- ((uint32_t)AES_sbox[(temp >> 0) & 0xFF] << 0);
104
+MATERIALISE_EXT_PREDICATE(xtheadcondmov)
43
+ t.w[0] = t.w[1] = t.w[2] = t.w[3] = temp;
105
+MATERIALISE_EXT_PREDICATE(xtheadfmemidx)
44
+ aesenc_SB_SR_AK(&t, &t, &rc, false);
106
+MATERIALISE_EXT_PREDICATE(xtheadfmv)
45
107
+MATERIALISE_EXT_PREDICATE(xtheadmac)
46
- temp ^= rcon_;
108
+MATERIALISE_EXT_PREDICATE(xtheadmemidx)
47
-
109
+MATERIALISE_EXT_PREDICATE(xtheadmempair)
48
- result = ((uint64_t)temp << 32) | temp;
110
+MATERIALISE_EXT_PREDICATE(xtheadsync)
49
-
111
MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
50
- return result;
112
51
+ return t.d[0];
113
#endif
114
diff --git a/disas/riscv-xthead.c b/disas/riscv-xthead.c
115
new file mode 100644
116
index XXXXXXX..XXXXXXX
117
--- /dev/null
118
+++ b/disas/riscv-xthead.c
119
@@ -XXX,XX +XXX,XX @@
120
+/*
121
+ * QEMU RISC-V Disassembler for xthead.
122
+ *
123
+ * SPDX-License-Identifier: GPL-2.0-or-later
124
+ */
125
+
126
+#include "disas/riscv.h"
127
+#include "disas/riscv-xthead.h"
128
+
129
+typedef enum {
130
+ /* 0 is reserved for rv_op_illegal. */
131
+ /* XTheadBa */
132
+ rv_op_th_addsl = 1,
133
+ /* XTheadBb */
134
+ rv_op_th_srri,
135
+ rv_op_th_srriw,
136
+ rv_op_th_ext,
137
+ rv_op_th_extu,
138
+ rv_op_th_ff0,
139
+ rv_op_th_ff1,
140
+ rv_op_th_rev,
141
+ rv_op_th_revw,
142
+ rv_op_th_tstnbz,
143
+ /* XTheadBs */
144
+ rv_op_th_tst,
145
+ /* XTheadCmo */
146
+ rv_op_th_dcache_call,
147
+ rv_op_th_dcache_ciall,
148
+ rv_op_th_dcache_iall,
149
+ rv_op_th_dcache_cpa,
150
+ rv_op_th_dcache_cipa,
151
+ rv_op_th_dcache_ipa,
152
+ rv_op_th_dcache_cva,
153
+ rv_op_th_dcache_civa,
154
+ rv_op_th_dcache_iva,
155
+ rv_op_th_dcache_csw,
156
+ rv_op_th_dcache_cisw,
157
+ rv_op_th_dcache_isw,
158
+ rv_op_th_dcache_cpal1,
159
+ rv_op_th_dcache_cval1,
160
+ rv_op_th_icache_iall,
161
+ rv_op_th_icache_ialls,
162
+ rv_op_th_icache_ipa,
163
+ rv_op_th_icache_iva,
164
+ rv_op_th_l2cache_call,
165
+ rv_op_th_l2cache_ciall,
166
+ rv_op_th_l2cache_iall,
167
+ /* XTheadCondMov */
168
+ rv_op_th_mveqz,
169
+ rv_op_th_mvnez,
170
+ /* XTheadFMemIdx */
171
+ rv_op_th_flrd,
172
+ rv_op_th_flrw,
173
+ rv_op_th_flurd,
174
+ rv_op_th_flurw,
175
+ rv_op_th_fsrd,
176
+ rv_op_th_fsrw,
177
+ rv_op_th_fsurd,
178
+ rv_op_th_fsurw,
179
+ /* XTheadFmv */
180
+ rv_op_th_fmv_hw_x,
181
+ rv_op_th_fmv_x_hw,
182
+ /* XTheadMac */
183
+ rv_op_th_mula,
184
+ rv_op_th_mulah,
185
+ rv_op_th_mulaw,
186
+ rv_op_th_muls,
187
+ rv_op_th_mulsw,
188
+ rv_op_th_mulsh,
189
+ /* XTheadMemIdx */
190
+ rv_op_th_lbia,
191
+ rv_op_th_lbib,
192
+ rv_op_th_lbuia,
193
+ rv_op_th_lbuib,
194
+ rv_op_th_lhia,
195
+ rv_op_th_lhib,
196
+ rv_op_th_lhuia,
197
+ rv_op_th_lhuib,
198
+ rv_op_th_lwia,
199
+ rv_op_th_lwib,
200
+ rv_op_th_lwuia,
201
+ rv_op_th_lwuib,
202
+ rv_op_th_ldia,
203
+ rv_op_th_ldib,
204
+ rv_op_th_sbia,
205
+ rv_op_th_sbib,
206
+ rv_op_th_shia,
207
+ rv_op_th_shib,
208
+ rv_op_th_swia,
209
+ rv_op_th_swib,
210
+ rv_op_th_sdia,
211
+ rv_op_th_sdib,
212
+ rv_op_th_lrb,
213
+ rv_op_th_lrbu,
214
+ rv_op_th_lrh,
215
+ rv_op_th_lrhu,
216
+ rv_op_th_lrw,
217
+ rv_op_th_lrwu,
218
+ rv_op_th_lrd,
219
+ rv_op_th_srb,
220
+ rv_op_th_srh,
221
+ rv_op_th_srw,
222
+ rv_op_th_srd,
223
+ rv_op_th_lurb,
224
+ rv_op_th_lurbu,
225
+ rv_op_th_lurh,
226
+ rv_op_th_lurhu,
227
+ rv_op_th_lurw,
228
+ rv_op_th_lurwu,
229
+ rv_op_th_lurd,
230
+ rv_op_th_surb,
231
+ rv_op_th_surh,
232
+ rv_op_th_surw,
233
+ rv_op_th_surd,
234
+ /* XTheadMemPair */
235
+ rv_op_th_ldd,
236
+ rv_op_th_lwd,
237
+ rv_op_th_lwud,
238
+ rv_op_th_sdd,
239
+ rv_op_th_swd,
240
+ /* XTheadSync */
241
+ rv_op_th_sfence_vmas,
242
+ rv_op_th_sync,
243
+ rv_op_th_sync_i,
244
+ rv_op_th_sync_is,
245
+ rv_op_th_sync_s,
246
+} rv_xthead_op;
247
+
248
+const rv_opcode_data xthead_opcode_data[] = {
249
+ { "th.illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
250
+ /* XTheadBa */
251
+ { "th.addsl", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
252
+ /* XTheadBb */
253
+ { "th.srri", rv_codec_r2_imm6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
254
+ { "th.srriw", rv_codec_r2_imm5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
255
+ { "th.ext", rv_codec_r2_immhl, rv_fmt_rd_rs1_immh_imml, NULL, 0, 0, 0 },
256
+ { "th.extu", rv_codec_r2_immhl, rv_fmt_rd_rs1_immh_imml, NULL, 0, 0, 0 },
257
+ { "th.ff0", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
258
+ { "th.ff1", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
259
+ { "th.rev", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
260
+ { "th.revw", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
261
+ { "th.tstnbz", rv_codec_r2, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
262
+ /* XTheadBs */
263
+ { "th.tst", rv_codec_r2_imm6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
264
+ /* XTheadCmo */
265
+ { "th.dcache.call", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
266
+ { "th.dcache.ciall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
267
+ { "th.dcache.iall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
268
+ { "th.dcache.cpa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
269
+ { "th.dcache.cipa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
270
+ { "th.dcache.ipa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
271
+ { "th.dcache.cva", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
272
+ { "th.dcache.civa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
273
+ { "th.dcache.iva", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
274
+ { "th.dcache.csw", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
275
+ { "th.dcache.cisw", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
276
+ { "th.dcache.isw", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
277
+ { "th.dcache.cpal1", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
278
+ { "th.dcache.cval1", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
279
+ { "th.icache.iall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
280
+ { "th.icache.ialls", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
281
+ { "th.icache.ipa", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
282
+ { "th.icache.iva", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
283
+ { "th.l2cache.call", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
284
+ { "th.l2cache.ciall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
285
+ { "th.l2cache.iall", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
286
+ /* XTheadCondMov */
287
+ { "th.mveqz", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
288
+ { "th.mvnez", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
289
+ /* XTheadFMemIdx */
290
+ { "th.flrd", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
291
+ { "th.flrw", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
292
+ { "th.flurd", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
293
+ { "th.flurw", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
294
+ { "th.fsrd", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
295
+ { "th.fsrw", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
296
+ { "th.fsurd", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
297
+ { "th.fsurw", rv_codec_r_imm2, rv_fmt_frd_rs1_rs2_imm, NULL, 0, 0, 0 },
298
+ /* XTheadFmv */
299
+ { "th.fmv.hw.x", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
300
+ { "th.fmv.x.hw", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
301
+ /* XTheadMac */
302
+ { "th.mula", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
303
+ { "th.mulaw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
304
+ { "th.mulah", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
305
+ { "th.muls", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
306
+ { "th.mulsw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
307
+ { "th.mulsh", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
308
+ /* XTheadMemIdx */
309
+ { "th.lbia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
310
+ { "th.lbib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml, NULL, 0, 0, 0 },
311
+ { "th.lbuia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
312
+ { "th.lbuib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
313
+ { "th.lhia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
314
+ { "th.lhib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
315
+ { "th.lhuia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
316
+ { "th.lhuib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
317
+ { "th.lwia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
318
+ { "th.lwib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
319
+ { "th.lwuia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
320
+ { "th.lwuib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
321
+ { "th.ldia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
322
+ { "th.ldib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
323
+ { "th.sbia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
324
+ { "th.sbib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
325
+ { "th.shia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
326
+ { "th.shib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
327
+ { "th.swia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
328
+ { "th.swib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
329
+ { "th.sdia", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
330
+ { "th.sdib", rv_codec_r2_imm2_imm5, rv_fmt_rd_rs1_immh_imml_addr, NULL, 0, 0, 0 },
331
+ { "th.lrb", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
332
+ { "th.lrbu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
333
+ { "th.lrh", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
334
+ { "th.lrhu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
335
+ { "th.lrw", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
336
+ { "th.lrwu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
337
+ { "th.lrd", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
338
+ { "th.srb", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
339
+ { "th.srh", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
340
+ { "th.srw", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
341
+ { "th.srd", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
342
+ { "th.lurb", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
343
+ { "th.lurbu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
344
+ { "th.lurh", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
345
+ { "th.lurhu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
346
+ { "th.lurw", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
347
+ { "th.lurwu", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
348
+ { "th.lurd", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
349
+ { "th.surb", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
350
+ { "th.surh", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
351
+ { "th.surw", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
352
+ { "th.surd", rv_codec_r_imm2, rv_fmt_rd_rs1_rs2_imm, NULL, 0, 0, 0 },
353
+ /* XTheadMemPair */
354
+ { "th.ldd", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 },
355
+ { "th.lwd", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 },
356
+ { "th.lwud", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 },
357
+ { "th.sdd", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 },
358
+ { "th.swd", rv_codec_r_imm2, rv_fmt_rd2_imm, NULL, 0, 0, 0 },
359
+ /* XTheadSync */
360
+ { "th.sfence.vmas", rv_codec_r, rv_fmt_rs1_rs2, NULL, 0, 0, 0 },
361
+ { "th.sync", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
362
+ { "th.sync.i", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
363
+ { "th.sync.is", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
364
+ { "th.sync.s", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 },
365
+};
366
+
367
+void decode_xtheadba(rv_decode *dec, rv_isa isa)
368
+{
369
+ rv_inst inst = dec->inst;
370
+ rv_opcode op = rv_op_illegal;
371
+
372
+ switch (((inst >> 0) & 0b11)) {
373
+ case 3:
374
+ switch (((inst >> 2) & 0b11111)) {
375
+ case 2:
376
+ /* custom-0 */
377
+ switch ((inst >> 12) & 0b111) {
378
+ case 1:
379
+ switch ((inst >> 25) & 0b1111111) {
380
+ case 0b0000000:
381
+ case 0b0000001:
382
+ case 0b0000010:
383
+ case 0b0000011: op = rv_op_th_addsl; break;
384
+ }
385
+ break;
386
+ }
387
+ break;
388
+ /* custom-0 */
389
+ }
390
+ break;
391
+ }
392
+
393
+ dec->op = op;
394
+}
395
+
396
+void decode_xtheadbb(rv_decode *dec, rv_isa isa)
397
+{
398
+ rv_inst inst = dec->inst;
399
+ rv_opcode op = rv_op_illegal;
400
+
401
+ switch (((inst >> 0) & 0b11)) {
402
+ case 3:
403
+ switch (((inst >> 2) & 0b11111)) {
404
+ case 2:
405
+ /* custom-0 */
406
+ switch ((inst >> 12) & 0b111) {
407
+ case 1:
408
+ switch ((inst >> 25) & 0b1111111) {
409
+ case 0b0001010: op = rv_op_th_srriw; break;
410
+ case 0b1000000:
411
+ if (((inst >> 20) & 0b11111) == 0) {
412
+ op = rv_op_th_tstnbz;
413
+ }
414
+ break;
415
+ case 0b1000001:
416
+ if (((inst >> 20) & 0b11111) == 0) {
417
+ op = rv_op_th_rev;
418
+ }
419
+ break;
420
+ case 0b1000010:
421
+ if (((inst >> 20) & 0b11111) == 0) {
422
+ op = rv_op_th_ff0;
423
+ }
424
+ break;
425
+ case 0b1000011:
426
+ if (((inst >> 20) & 0b11111) == 0) {
427
+ op = rv_op_th_ff1;
428
+ }
429
+ break;
430
+ case 0b1000100:
431
+ case 0b1001000:
432
+ if (((inst >> 20) & 0b11111) == 0) {
433
+ op = rv_op_th_revw;
434
+ }
435
+ break;
436
+ case 0b0000100:
437
+ case 0b0000101: op = rv_op_th_srri; break;
438
+ }
439
+ break;
440
+ case 2: op = rv_op_th_ext; break;
441
+ case 3: op = rv_op_th_extu; break;
442
+ }
443
+ break;
444
+ /* custom-0 */
445
+ }
446
+ break;
447
+ }
448
+
449
+ dec->op = op;
450
+}
451
+
452
+void decode_xtheadbs(rv_decode *dec, rv_isa isa)
453
+{
454
+ rv_inst inst = dec->inst;
455
+ rv_opcode op = rv_op_illegal;
456
+
457
+ switch (((inst >> 0) & 0b11)) {
458
+ case 3:
459
+ switch (((inst >> 2) & 0b11111)) {
460
+ case 2:
461
+ /* custom-0 */
462
+ switch ((inst >> 12) & 0b111) {
463
+ case 1:
464
+ switch ((inst >> 26) & 0b111111) {
465
+ case 0b100010: op = rv_op_th_tst; break;
466
+ }
467
+ break;
468
+ }
469
+ break;
470
+ /* custom-0 */
471
+ }
472
+ break;
473
+ }
474
+
475
+ dec->op = op;
476
+}
477
+
478
+void decode_xtheadcmo(rv_decode *dec, rv_isa isa)
479
+{
480
+ rv_inst inst = dec->inst;
481
+ rv_opcode op = rv_op_illegal;
482
+
483
+ switch (((inst >> 0) & 0b11)) {
484
+ case 3:
485
+ switch (((inst >> 2) & 0b11111)) {
486
+ case 2:
487
+ /* custom-0 */
488
+ switch ((inst >> 12) & 0b111) {
489
+ case 0:
490
+ switch ((inst >> 20 & 0b111111111111)) {
491
+ case 0b000000000001:
492
+ if (((inst >> 20) & 0b11111) == 0) {
493
+ op = rv_op_th_dcache_call;
494
+ }
495
+ break;
496
+ case 0b000000000011:
497
+ if (((inst >> 20) & 0b11111) == 0) {
498
+ op = rv_op_th_dcache_ciall;
499
+ }
500
+ break;
501
+ case 0b000000000010:
502
+ if (((inst >> 20) & 0b11111) == 0) {
503
+ op = rv_op_th_dcache_iall;
504
+ }
505
+ break;
506
+ case 0b000000101001: op = rv_op_th_dcache_cpa; break;
507
+ case 0b000000101011: op = rv_op_th_dcache_cipa; break;
508
+ case 0b000000101010: op = rv_op_th_dcache_ipa; break;
509
+ case 0b000000100101: op = rv_op_th_dcache_cva; break;
510
+ case 0b000000100111: op = rv_op_th_dcache_civa; break;
511
+ case 0b000000100110: op = rv_op_th_dcache_iva; break;
512
+ case 0b000000100001: op = rv_op_th_dcache_csw; break;
513
+ case 0b000000100011: op = rv_op_th_dcache_cisw; break;
514
+ case 0b000000100010: op = rv_op_th_dcache_isw; break;
515
+ case 0b000000101000: op = rv_op_th_dcache_cpal1; break;
516
+ case 0b000000100100: op = rv_op_th_dcache_cval1; break;
517
+ case 0b000000010000:
518
+ if (((inst >> 20) & 0b11111) == 0) {
519
+ op = rv_op_th_icache_iall;
520
+ }
521
+ break;
522
+ case 0b000000010001:
523
+ if (((inst >> 20) & 0b11111) == 0) {
524
+ op = rv_op_th_icache_ialls;
525
+ }
526
+ break;
527
+ case 0b000000111000: op = rv_op_th_icache_ipa; break;
528
+ case 0b000000110000: op = rv_op_th_icache_iva; break;
529
+ case 0b000000010101:
530
+ if (((inst >> 20) & 0b11111) == 0) {
531
+ op = rv_op_th_l2cache_call;
532
+ }
533
+ break;
534
+ case 0b000000010111:
535
+ if (((inst >> 20) & 0b11111) == 0) {
536
+ op = rv_op_th_l2cache_ciall;
537
+ }
538
+ break;
539
+ case 0b000000010110:
540
+ if (((inst >> 20) & 0b11111) == 0) {
541
+ op = rv_op_th_l2cache_iall;
542
+ }
543
+ break;
544
+ }
545
+ break;
546
+ }
547
+ break;
548
+ /* custom-0 */
549
+ }
550
+ break;
551
+ }
552
+
553
+ dec->op = op;
554
+}
555
+
556
+void decode_xtheadcondmov(rv_decode *dec, rv_isa isa)
557
+{
558
+ rv_inst inst = dec->inst;
559
+ rv_opcode op = rv_op_illegal;
560
+
561
+ switch (((inst >> 0) & 0b11)) {
562
+ case 3:
563
+ switch (((inst >> 2) & 0b11111)) {
564
+ case 2:
565
+ /* custom-0 */
566
+ switch ((inst >> 12) & 0b111) {
567
+ case 1:
568
+ switch ((inst >> 25) & 0b1111111) {
569
+ case 0b0100000: op = rv_op_th_mveqz; break;
570
+ case 0b0100001: op = rv_op_th_mvnez; break;
571
+ }
572
+ break;
573
+ }
574
+ break;
575
+ /* custom-0 */
576
+ }
577
+ break;
578
+ }
579
+
580
+ dec->op = op;
581
+}
582
+
583
+void decode_xtheadfmemidx(rv_decode *dec, rv_isa isa)
584
+{
585
+ rv_inst inst = dec->inst;
586
+ rv_opcode op = rv_op_illegal;
587
+
588
+ switch (((inst >> 0) & 0b11)) {
589
+ case 3:
590
+ switch (((inst >> 2) & 0b11111)) {
591
+ case 2:
592
+ /* custom-0 */
593
+ switch ((inst >> 12) & 0b111) {
594
+ case 6:
595
+ switch ((inst >> 27) & 0b11111) {
596
+ case 8: op = rv_op_th_flrw; break;
597
+ case 10: op = rv_op_th_flurw; break;
598
+ case 12: op = rv_op_th_flrd; break;
599
+ case 14: op = rv_op_th_flurd; break;
600
+ }
601
+ break;
602
+ case 7:
603
+ switch ((inst >> 27) & 0b11111) {
604
+ case 8: op = rv_op_th_fsrw; break;
605
+ case 10: op = rv_op_th_fsurw; break;
606
+ case 12: op = rv_op_th_fsrd; break;
607
+ case 14: op = rv_op_th_fsurd; break;
608
+ }
609
+ break;
610
+ }
611
+ break;
612
+ /* custom-0 */
613
+ }
614
+ break;
615
+ }
616
+
617
+ dec->op = op;
618
+}
619
+
620
+void decode_xtheadfmv(rv_decode *dec, rv_isa isa)
621
+{
622
+ rv_inst inst = dec->inst;
623
+ rv_opcode op = rv_op_illegal;
624
+
625
+ switch (((inst >> 0) & 0b11)) {
626
+ case 3:
627
+ switch (((inst >> 2) & 0b11111)) {
628
+ case 2:
629
+ /* custom-0 */
630
+ switch ((inst >> 12) & 0b111) {
631
+ case 1:
632
+ switch ((inst >> 25) & 0b1111111) {
633
+ case 0b1010000:
634
+ if (((inst >> 20) & 0b11111) == 0) {
635
+ op = rv_op_th_fmv_hw_x;
636
+ }
637
+ break;
638
+ case 0b1100000:
639
+ if (((inst >> 20) & 0b11111) == 0) {
640
+ op = rv_op_th_fmv_x_hw;
641
+ }
642
+ break;
643
+ }
644
+ break;
645
+ }
646
+ break;
647
+ /* custom-0 */
648
+ }
649
+ break;
650
+ }
651
+
652
+ dec->op = op;
653
+}
654
+
655
+void decode_xtheadmac(rv_decode *dec, rv_isa isa)
656
+{
657
+ rv_inst inst = dec->inst;
658
+ rv_opcode op = rv_op_illegal;
659
+
660
+ switch (((inst >> 0) & 0b11)) {
661
+ case 3:
662
+ switch (((inst >> 2) & 0b11111)) {
663
+ case 2:
664
+ /* custom-0 */
665
+ switch ((inst >> 12) & 0b111) {
666
+ case 1:
667
+ switch ((inst >> 25) & 0b1111111) {
668
+ case 0b0010000: op = rv_op_th_mula; break;
669
+ case 0b0010001: op = rv_op_th_muls; break;
670
+ case 0b0010010: op = rv_op_th_mulaw; break;
671
+ case 0b0010011: op = rv_op_th_mulsw; break;
672
+ case 0b0010100: op = rv_op_th_mulah; break;
673
+ case 0b0010101: op = rv_op_th_mulsh; break;
674
+ }
675
+ break;
676
+ }
677
+ break;
678
+ /* custom-0 */
679
+ }
680
+ break;
681
+ }
682
+
683
+ dec->op = op;
684
+}
685
+
686
+void decode_xtheadmemidx(rv_decode *dec, rv_isa isa)
687
+{
688
+ rv_inst inst = dec->inst;
689
+ rv_opcode op = rv_op_illegal;
690
+
691
+ switch (((inst >> 0) & 0b11)) {
692
+ case 3:
693
+ switch (((inst >> 2) & 0b11111)) {
694
+ case 2:
695
+ /* custom-0 */
696
+ switch ((inst >> 12) & 0b111) {
697
+ case 4:
698
+ switch ((inst >> 27) & 0b11111) {
699
+ case 0: op = rv_op_th_lrb; break;
700
+ case 1: op = rv_op_th_lbib; break;
701
+ case 2: op = rv_op_th_lurb; break;
702
+ case 3: op = rv_op_th_lbia; break;
703
+ case 4: op = rv_op_th_lrh; break;
704
+ case 5: op = rv_op_th_lhib; break;
705
+ case 6: op = rv_op_th_lurh; break;
706
+ case 7: op = rv_op_th_lhia; break;
707
+ case 8: op = rv_op_th_lrw; break;
708
+ case 9: op = rv_op_th_lwib; break;
709
+ case 10: op = rv_op_th_lurw; break;
710
+ case 11: op = rv_op_th_lwia; break;
711
+ case 12: op = rv_op_th_lrd; break;
712
+ case 13: op = rv_op_th_ldib; break;
713
+ case 14: op = rv_op_th_lurd; break;
714
+ case 15: op = rv_op_th_ldia; break;
715
+ case 16: op = rv_op_th_lrbu; break;
716
+ case 17: op = rv_op_th_lbuib; break;
717
+ case 18: op = rv_op_th_lurbu; break;
718
+ case 19: op = rv_op_th_lbuia; break;
719
+ case 20: op = rv_op_th_lrhu; break;
720
+ case 21: op = rv_op_th_lhuib; break;
721
+ case 22: op = rv_op_th_lurhu; break;
722
+ case 23: op = rv_op_th_lhuia; break;
723
+ case 24: op = rv_op_th_lrwu; break;
724
+ case 25: op = rv_op_th_lwuib; break;
725
+ case 26: op = rv_op_th_lurwu; break;
726
+ case 27: op = rv_op_th_lwuia; break;
727
+ }
728
+ break;
729
+ case 5:
730
+ switch ((inst >> 27) & 0b11111) {
731
+ case 0: op = rv_op_th_srb; break;
732
+ case 1: op = rv_op_th_sbib; break;
733
+ case 2: op = rv_op_th_surb; break;
734
+ case 3: op = rv_op_th_sbia; break;
735
+ case 4: op = rv_op_th_srh; break;
736
+ case 5: op = rv_op_th_shib; break;
737
+ case 6: op = rv_op_th_surh; break;
738
+ case 7: op = rv_op_th_shia; break;
739
+ case 8: op = rv_op_th_srw; break;
740
+ case 9: op = rv_op_th_swib; break;
741
+ case 10: op = rv_op_th_surw; break;
742
+ case 11: op = rv_op_th_swia; break;
743
+ case 12: op = rv_op_th_srd; break;
744
+ case 13: op = rv_op_th_sdib; break;
745
+ case 14: op = rv_op_th_surd; break;
746
+ case 15: op = rv_op_th_sdia; break;
747
+ }
748
+ break;
749
+ break;
750
+ }
751
+ break;
752
+ /* custom-0 */
753
+ }
754
+ break;
755
+ }
756
+
757
+ dec->op = op;
758
+}
759
+
760
+void decode_xtheadmempair(rv_decode *dec, rv_isa isa)
761
+{
762
+ rv_inst inst = dec->inst;
763
+ rv_opcode op = rv_op_illegal;
764
+
765
+ switch (((inst >> 0) & 0b11)) {
766
+ case 3:
767
+ switch (((inst >> 2) & 0b11111)) {
768
+ case 2:
769
+ /* custom-0 */
770
+ switch ((inst >> 12) & 0b111) {
771
+ case 4:
772
+ switch ((inst >> 27) & 0b11111) {
773
+ case 28: op = rv_op_th_lwd; break;
774
+ case 30: op = rv_op_th_lwud; break;
775
+ case 31: op = rv_op_th_ldd; break;
776
+ }
777
+ break;
778
+ case 5:
779
+ switch ((inst >> 27) & 0b11111) {
780
+ case 28: op = rv_op_th_swd; break;
781
+ case 31: op = rv_op_th_sdd; break;
782
+ }
783
+ break;
784
+ }
785
+ break;
786
+ /* custom-0 */
787
+ }
788
+ break;
789
+ }
790
+
791
+ dec->op = op;
792
+}
793
+
794
+void decode_xtheadsync(rv_decode *dec, rv_isa isa)
795
+{
796
+ rv_inst inst = dec->inst;
797
+ rv_opcode op = rv_op_illegal;
798
+
799
+ switch (((inst >> 0) & 0b11)) {
800
+ case 3:
801
+ switch (((inst >> 2) & 0b11111)) {
802
+ case 2:
803
+ /* custom-0 */
804
+ switch ((inst >> 12) & 0b111) {
805
+ case 0:
806
+ switch ((inst >> 25) & 0b1111111) {
807
+ case 0b0000010: op = rv_op_th_sfence_vmas; break;
808
+ case 0b0000000:
809
+ switch ((inst >> 20) & 0b11111) {
810
+ case 0b11000: op = rv_op_th_sync; break;
811
+ case 0b11010: op = rv_op_th_sync_i; break;
812
+ case 0b11011: op = rv_op_th_sync_is; break;
813
+ case 0b11001: op = rv_op_th_sync_s; break;
814
+ }
815
+ break;
816
+ }
817
+ break;
818
+ }
819
+ break;
820
+ /* custom-0 */
821
+ }
822
+ break;
823
+ }
824
+
825
+ dec->op = op;
826
+}
827
diff --git a/disas/riscv.c b/disas/riscv.c
828
index XXXXXXX..XXXXXXX 100644
829
--- a/disas/riscv.c
830
+++ b/disas/riscv.c
831
@@ -XXX,XX +XXX,XX @@
832
*/
833
834
#include "qemu/osdep.h"
835
+#include "qemu/bitops.h"
836
#include "disas/dis-asm.h"
837
#include "target/riscv/cpu_cfg.h"
838
#include "disas/riscv.h"
839
840
/* Vendor extensions */
841
+#include "disas/riscv-xthead.h"
842
#include "disas/riscv-xventana.h"
843
844
typedef enum {
845
@@ -XXX,XX +XXX,XX @@ static uint32_t operand_zcmp_rlist(rv_inst inst)
846
return ((inst << 56) >> 60);
847
}
52
}
848
53
849
+static uint32_t operand_imm6(rv_inst inst)
54
target_ulong HELPER(aes64im)(target_ulong rs1)
850
+{
851
+ return (inst << 38) >> 60;
852
+}
853
+
854
+static uint32_t operand_imm2(rv_inst inst)
855
+{
856
+ return (inst << 37) >> 62;
857
+}
858
+
859
+static uint32_t operand_immh(rv_inst inst)
860
+{
861
+ return (inst << 32) >> 58;
862
+}
863
+
864
+static uint32_t operand_imml(rv_inst inst)
865
+{
866
+ return (inst << 38) >> 58;
867
+}
868
+
869
static uint32_t calculate_stack_adj(rv_isa isa, uint32_t rlist, uint32_t spimm)
870
{
871
int xlen_bytes_log2 = isa == rv64 ? 3 : 2;
872
@@ -XXX,XX +XXX,XX @@ static void decode_inst_operands(rv_decode *dec, rv_isa isa)
873
case rv_codec_zcmt_jt:
874
dec->imm = operand_tbl_index(inst);
875
break;
876
+ case rv_codec_r2_imm5:
877
+ dec->rd = operand_rd(inst);
878
+ dec->rs1 = operand_rs1(inst);
879
+ dec->imm = operand_rs2(inst);
880
+ break;
881
+ case rv_codec_r2:
882
+ dec->rd = operand_rd(inst);
883
+ dec->rs1 = operand_rs1(inst);
884
+ break;
885
+ case rv_codec_r2_imm6:
886
+ dec->rd = operand_rd(inst);
887
+ dec->rs1 = operand_rs1(inst);
888
+ dec->imm = operand_imm6(inst);
889
+ break;
890
+ case rv_codec_r_imm2:
891
+ dec->rd = operand_rd(inst);
892
+ dec->rs1 = operand_rs1(inst);
893
+ dec->rs2 = operand_rs2(inst);
894
+ dec->imm = operand_imm2(inst);
895
+ break;
896
+ case rv_codec_r2_immhl:
897
+ dec->rd = operand_rd(inst);
898
+ dec->rs1 = operand_rs1(inst);
899
+ dec->imm = operand_immh(inst);
900
+ dec->imm1 = operand_imml(inst);
901
+ break;
902
+ case rv_codec_r2_imm2_imm5:
903
+ dec->rd = operand_rd(inst);
904
+ dec->rs1 = operand_rs1(inst);
905
+ dec->imm = sextract32(operand_rs2(inst), 0, 5);
906
+ dec->imm1 = operand_imm2(inst);
907
+ break;
908
};
909
}
910
911
@@ -XXX,XX +XXX,XX @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
912
snprintf(tmp, sizeof(tmp), "%u", ((uint32_t)dec->imm & 0b11111));
913
append(buf, tmp, buflen);
914
break;
915
+ case 'j':
916
+ snprintf(tmp, sizeof(tmp), "%d", dec->imm1);
917
+ append(buf, tmp, buflen);
918
+ break;
919
case 'o':
920
snprintf(tmp, sizeof(tmp), "%d", dec->imm);
921
append(buf, tmp, buflen);
922
@@ -XXX,XX +XXX,XX @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst,
923
void (*decode_func)(rv_decode *, rv_isa);
924
} decoders[] = {
925
{ always_true_p, rvi_opcode_data, decode_inst_opcode },
926
+ { has_xtheadba_p, xthead_opcode_data, decode_xtheadba },
927
+ { has_xtheadbb_p, xthead_opcode_data, decode_xtheadbb },
928
+ { has_xtheadbs_p, xthead_opcode_data, decode_xtheadbs },
929
+ { has_xtheadcmo_p, xthead_opcode_data, decode_xtheadcmo },
930
+ { has_xtheadcondmov_p, xthead_opcode_data, decode_xtheadcondmov },
931
+ { has_xtheadfmemidx_p, xthead_opcode_data, decode_xtheadfmemidx },
932
+ { has_xtheadfmv_p, xthead_opcode_data, decode_xtheadfmv },
933
+ { has_xtheadmac_p, xthead_opcode_data, decode_xtheadmac },
934
+ { has_xtheadmemidx_p, xthead_opcode_data, decode_xtheadmemidx },
935
+ { has_xtheadmempair_p, xthead_opcode_data, decode_xtheadmempair },
936
+ { has_xtheadsync_p, xthead_opcode_data, decode_xtheadsync },
937
{ has_XVentanaCondOps_p, ventana_opcode_data, decode_xventanacondops },
938
};
939
940
diff --git a/disas/meson.build b/disas/meson.build
941
index XXXXXXX..XXXXXXX 100644
942
--- a/disas/meson.build
943
+++ b/disas/meson.build
944
@@ -XXX,XX +XXX,XX @@ common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c', 'nanomips.c'))
945
common_ss.add(when: 'CONFIG_NIOS2_DIS', if_true: files('nios2.c'))
946
common_ss.add(when: 'CONFIG_RISCV_DIS', if_true: files(
947
'riscv.c',
948
+ 'riscv-xthead.c',
949
'riscv-xventana.c'
950
))
951
common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c'))
952
--
55
--
953
2.40.1
56
2.41.0
954
57
955
58
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
Next patch will add KVM specific user properties for both MISA and
3
riscv_trigger_init() had been called on reset events that can happen
4
multi-letter extensions. For MISA extensions we want to make use of what
4
several times for a CPU and it allocated timers for itrigger. If old
5
is already available in misa_ext_cfgs[] to avoid code repetition.
5
timers were present, they were simply overwritten by the new timers,
6
resulting in a memory leak.
6
7
7
misa_ext_info_arr[] array will hold name and description for each MISA
8
Divide riscv_trigger_init() into two functions, namely
8
extension that misa_ext_cfgs[] is declaring. We'll then use this new
9
riscv_trigger_realize() and riscv_trigger_reset() and call them in
9
array in KVM code to avoid duplicating strings. Two getters were added
10
appropriate timing. The timer allocation will happen only once for a
10
to allow KVM to retrieve the 'name' and 'description' for each MISA
11
CPU in riscv_trigger_realize().
11
property.
12
12
13
There's nothing holding us back from doing the same with multi-letter
13
Fixes: 5a4ae64cac ("target/riscv: Add itrigger support when icount is enabled")
14
extensions. For now doing just with MISA extensions is enough.
14
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
15
16
It is worth documenting that even using the __bultin_ctz() directive to
17
populate the misa_ext_info_arr[] we are forced to assign 'name' and
18
'description' during runtime in riscv_cpu_add_misa_properties(). The
19
reason is that some Gitlab runners ('clang-user' and 'tsan-build') will
20
throw errors like this if we fetch 'name' and 'description' from the
21
array in the MISA_CFG() macro:
22
23
../target/riscv/cpu.c:1624:5: error: initializer element is not a
24
compile-time constant
25
MISA_CFG(RVA, true),
26
^~~~~~~~~~~~~~~~~~~
27
../target/riscv/cpu.c:1619:53: note: expanded from macro 'MISA_CFG'
28
{.name = misa_ext_info_arr[MISA_INFO_IDX(_bit)].name, \
29
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
30
31
gcc and others compilers/builders were fine with that change. We can't
32
ignore failures in the Gitlab pipeline though, so code was changed to
33
make every runner happy.
34
35
As a side effect, misa_ext_cfg[] is no longer a 'const' array because
36
it must be set during runtime.
37
38
Suggested-by: Andrew Jones <ajones@ventanamicro.com>
39
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
40
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
41
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
16
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
42
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
43
Message-Id: <20230706101738.460804-12-dbarboza@ventanamicro.com>
18
Message-ID: <20230818034059.9146-1-akihiko.odaki@daynix.com>
44
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
45
---
20
---
46
target/riscv/cpu.h | 7 ++-
21
target/riscv/debug.h | 3 ++-
47
target/riscv/cpu.c | 110 +++++++++++++++++++++++++++++++++------------
22
target/riscv/cpu.c | 8 +++++++-
48
2 files changed, 88 insertions(+), 29 deletions(-)
23
target/riscv/debug.c | 15 ++++++++++++---
24
3 files changed, 21 insertions(+), 5 deletions(-)
49
25
50
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
51
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
52
--- a/target/riscv/cpu.h
28
--- a/target/riscv/debug.h
53
+++ b/target/riscv/cpu.h
29
+++ b/target/riscv/debug.h
54
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_debug_excp_handler(CPUState *cs);
55
31
bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
56
#define RV(x) ((target_ulong)1 << (x - 'A'))
32
bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
57
33
58
-/* Consider updating misa_ext_cfgs[] when adding new MISA bits here */
34
-void riscv_trigger_init(CPURISCVState *env);
59
+/*
35
+void riscv_trigger_realize(CPURISCVState *env);
60
+ * Consider updating misa_ext_info_arr[] and misa_ext_cfgs[]
36
+void riscv_trigger_reset_hold(CPURISCVState *env);
61
+ * when adding new MISA bits here.
37
62
+ */
38
bool riscv_itrigger_enabled(CPURISCVState *env);
63
#define RVI RV('I')
39
void riscv_itrigger_update_priv(CPURISCVState *env);
64
#define RVE RV('E') /* E and I are mutually exclusive */
65
#define RVM RV('M')
66
@@ -XXX,XX +XXX,XX @@
67
#define RVJ RV('J')
68
#define RVG RV('G')
69
70
+const char *riscv_get_misa_ext_name(uint32_t bit);
71
+const char *riscv_get_misa_ext_description(uint32_t bit);
72
73
/* Privileged specification version */
74
enum {
75
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
76
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
77
--- a/target/riscv/cpu.c
42
--- a/target/riscv/cpu.c
78
+++ b/target/riscv/cpu.c
43
+++ b/target/riscv/cpu.c
79
@@ -XXX,XX +XXX,XX @@ static void cpu_get_misa_ext_cfg(Object *obj, Visitor *v, const char *name,
44
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj)
80
visit_type_bool(v, name, &value, errp);
45
46
#ifndef CONFIG_USER_ONLY
47
if (cpu->cfg.debug) {
48
- riscv_trigger_init(env);
49
+ riscv_trigger_reset_hold(env);
50
}
51
52
if (kvm_enabled()) {
53
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
54
55
riscv_cpu_register_gdb_regs_for_features(cs);
56
57
+#ifndef CONFIG_USER_ONLY
58
+ if (cpu->cfg.debug) {
59
+ riscv_trigger_realize(&cpu->env);
60
+ }
61
+#endif
62
+
63
qemu_init_vcpu(cs);
64
cpu_reset(cs);
65
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;
81
}
72
}
82
73
83
-static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
74
-void riscv_trigger_init(CPURISCVState *env)
84
- {.name = "a", .description = "Atomic instructions",
75
+void riscv_trigger_realize(CPURISCVState *env)
85
- .misa_bit = RVA, .enabled = true},
76
+{
86
- {.name = "c", .description = "Compressed instructions",
77
+ int i;
87
- .misa_bit = RVC, .enabled = true},
88
- {.name = "d", .description = "Double-precision float point",
89
- .misa_bit = RVD, .enabled = true},
90
- {.name = "f", .description = "Single-precision float point",
91
- .misa_bit = RVF, .enabled = true},
92
- {.name = "i", .description = "Base integer instruction set",
93
- .misa_bit = RVI, .enabled = true},
94
- {.name = "e", .description = "Base integer instruction set (embedded)",
95
- .misa_bit = RVE, .enabled = false},
96
- {.name = "m", .description = "Integer multiplication and division",
97
- .misa_bit = RVM, .enabled = true},
98
- {.name = "s", .description = "Supervisor-level instructions",
99
- .misa_bit = RVS, .enabled = true},
100
- {.name = "u", .description = "User-level instructions",
101
- .misa_bit = RVU, .enabled = true},
102
- {.name = "h", .description = "Hypervisor",
103
- .misa_bit = RVH, .enabled = true},
104
- {.name = "x-j", .description = "Dynamic translated languages",
105
- .misa_bit = RVJ, .enabled = false},
106
- {.name = "v", .description = "Vector operations",
107
- .misa_bit = RVV, .enabled = false},
108
- {.name = "g", .description = "General purpose (IMAFD_Zicsr_Zifencei)",
109
- .misa_bit = RVG, .enabled = false},
110
+typedef struct misa_ext_info {
111
+ const char *name;
112
+ const char *description;
113
+} MISAExtInfo;
114
+
78
+
115
+#define MISA_INFO_IDX(_bit) \
79
+ for (i = 0; i < RV_MAX_TRIGGERS; i++) {
116
+ __builtin_ctz(_bit)
80
+ env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
117
+
81
+ riscv_itrigger_timer_cb, env);
118
+#define MISA_EXT_INFO(_bit, _propname, _descr) \
82
+ }
119
+ [MISA_INFO_IDX(_bit)] = {.name = _propname, .description = _descr}
120
+
121
+static const MISAExtInfo misa_ext_info_arr[] = {
122
+ MISA_EXT_INFO(RVA, "a", "Atomic instructions"),
123
+ MISA_EXT_INFO(RVC, "c", "Compressed instructions"),
124
+ MISA_EXT_INFO(RVD, "d", "Double-precision float point"),
125
+ MISA_EXT_INFO(RVF, "f", "Single-precision float point"),
126
+ MISA_EXT_INFO(RVI, "i", "Base integer instruction set"),
127
+ MISA_EXT_INFO(RVE, "e", "Base integer instruction set (embedded)"),
128
+ MISA_EXT_INFO(RVM, "m", "Integer multiplication and division"),
129
+ MISA_EXT_INFO(RVS, "s", "Supervisor-level instructions"),
130
+ MISA_EXT_INFO(RVU, "u", "User-level instructions"),
131
+ MISA_EXT_INFO(RVH, "h", "Hypervisor"),
132
+ MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
133
+ MISA_EXT_INFO(RVV, "v", "Vector operations"),
134
+ MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
135
+};
136
+
137
+static int riscv_validate_misa_info_idx(uint32_t bit)
138
+{
139
+ int idx;
140
+
141
+ /*
142
+ * Our lowest valid input (RVA) is 1 and
143
+ * __builtin_ctz() is UB with zero.
144
+ */
145
+ g_assert(bit != 0);
146
+ idx = MISA_INFO_IDX(bit);
147
+
148
+ g_assert(idx < ARRAY_SIZE(misa_ext_info_arr));
149
+ return idx;
150
+}
83
+}
151
+
84
+
152
+const char *riscv_get_misa_ext_name(uint32_t bit)
85
+void riscv_trigger_reset_hold(CPURISCVState *env)
153
+{
86
{
154
+ int idx = riscv_validate_misa_info_idx(bit);
87
target_ulong tdata1 = build_tdata1(env, TRIGGER_TYPE_AD_MATCH, 0, 0);
155
+ const char *val = misa_ext_info_arr[idx].name;
156
+
157
+ g_assert(val != NULL);
158
+ return val;
159
+}
160
+
161
+const char *riscv_get_misa_ext_description(uint32_t bit)
162
+{
163
+ int idx = riscv_validate_misa_info_idx(bit);
164
+ const char *val = misa_ext_info_arr[idx].description;
165
+
166
+ g_assert(val != NULL);
167
+ return val;
168
+}
169
+
170
+#define MISA_CFG(_bit, _enabled) \
171
+ {.misa_bit = _bit, .enabled = _enabled}
172
+
173
+static RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
174
+ MISA_CFG(RVA, true),
175
+ MISA_CFG(RVC, true),
176
+ MISA_CFG(RVD, true),
177
+ MISA_CFG(RVF, true),
178
+ MISA_CFG(RVI, true),
179
+ MISA_CFG(RVE, false),
180
+ MISA_CFG(RVM, true),
181
+ MISA_CFG(RVS, true),
182
+ MISA_CFG(RVU, true),
183
+ MISA_CFG(RVH, true),
184
+ MISA_CFG(RVJ, false),
185
+ MISA_CFG(RVV, false),
186
+ MISA_CFG(RVG, false),
187
};
188
189
static void riscv_cpu_add_misa_properties(Object *cpu_obj)
190
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
191
int i;
88
int i;
192
89
@@ -XXX,XX +XXX,XX @@ void riscv_trigger_init(CPURISCVState *env)
193
for (i = 0; i < ARRAY_SIZE(misa_ext_cfgs); i++) {
90
env->tdata3[i] = 0;
194
- const RISCVCPUMisaExtConfig *misa_cfg = &misa_ext_cfgs[i];
91
env->cpu_breakpoint[i] = NULL;
195
+ RISCVCPUMisaExtConfig *misa_cfg = &misa_ext_cfgs[i];
92
env->cpu_watchpoint[i] = NULL;
196
+ int bit = misa_cfg->misa_bit;
93
- env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
197
+
94
- riscv_itrigger_timer_cb, env);
198
+ misa_cfg->name = riscv_get_misa_ext_name(bit);
95
+ timer_del(env->itrigger_timer[i]);
199
+ misa_cfg->description = riscv_get_misa_ext_description(bit);
96
}
200
97
}
201
object_property_add(cpu_obj, misa_cfg->name, "bool",
202
cpu_get_misa_ext_cfg,
203
--
98
--
204
2.40.1
99
2.41.0
205
100
206
101
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Leon Schuermann <leons@opentitan.org>
2
2
3
We want to keep the ability to distinct between 32/64-bit host.
3
When the rule-lock bypass (RLB) bit is set in the mseccfg CSR, the PMP
4
configuration lock bits must not apply. While this behavior is
5
implemented for the pmpcfgX CSRs, this bit is not respected for
6
changes to the pmpaddrX CSRs. This patch ensures that pmpaddrX CSR
7
writes work even on locked regions when the global rule-lock bypass is
8
enabled.
4
9
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Signed-off-by: Leon Schuermann <leons@opentitan.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Mayuresh Chitale <mchitale@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20230627143235.29947-2-philmd@linaro.org>
13
Message-ID: <20230829215046.1430463-1-leon@is.currently.online>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
15
---
11
meson.build | 11 ++++-------
16
target/riscv/pmp.c | 4 ++++
12
1 file changed, 4 insertions(+), 7 deletions(-)
17
1 file changed, 4 insertions(+)
13
18
14
diff --git a/meson.build b/meson.build
19
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/meson.build
21
--- a/target/riscv/pmp.c
17
+++ b/meson.build
22
+++ b/target/riscv/pmp.c
18
@@ -XXX,XX +XXX,XX @@ qapi_trace_events = []
23
@@ -XXX,XX +XXX,XX @@ static inline uint8_t pmp_get_a_field(uint8_t cfg)
19
24
*/
20
bsd_oses = ['gnu/kfreebsd', 'freebsd', 'netbsd', 'openbsd', 'dragonfly', 'darwin']
25
static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
21
supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
26
{
22
-supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64',
27
+ /* mseccfg.RLB is set */
23
+supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv32', 'riscv64', 'x86', 'x86_64',
28
+ if (MSECCFG_RLB_ISSET(env)) {
24
'arm', 'aarch64', 'loongarch64', 'mips', 'mips64', 'sparc64']
29
+ return 0;
25
30
+ }
26
cpu = host_machine.cpu_family()
31
27
32
if (env->pmp_state.pmp[pmp_index].cfg_reg & PMP_LOCK) {
28
-# Unify riscv* to a single family.
33
return 1;
29
-if cpu in ['riscv32', 'riscv64']
30
- cpu = 'riscv'
31
-endif
32
-
33
target_dirs = config_host['TARGET_DIRS'].split()
34
have_linux_user = false
35
have_bsd_user = false
36
@@ -XXX,XX +XXX,XX @@ elif cpu == 'x86'
37
host_arch = 'i386'
38
elif cpu == 'mips64'
39
host_arch = 'mips'
40
+elif cpu in ['riscv32', 'riscv64']
41
+ host_arch = 'riscv'
42
else
43
host_arch = cpu
44
endif
45
@@ -XXX,XX +XXX,XX @@ elif cpu in ['ppc', 'ppc64']
46
kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
47
elif cpu in ['mips', 'mips64']
48
kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
49
-elif cpu in ['riscv']
50
+elif cpu in ['riscv32', 'riscv64']
51
kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
52
else
53
kvm_targets = []
54
--
34
--
55
2.40.1
35
2.41.0
56
57
diff view generated by jsdifflib
1
From: Tommy Wu <tommy.wu@sifive.com>
1
From: Tommy Wu <tommy.wu@sifive.com>
2
2
3
Add some simple tests of the watchdog timer in the always-on domain device
3
According to the new spec, when vsiselect has a reserved value, attempts
4
of HiFive 1 rev b.
4
from M-mode or HS-mode to access vsireg, or from VS-mode to access
5
sireg, should preferably raise an illegal instruction exception.
5
6
6
Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
7
Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
7
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
Acked-by: Thomas Huth <thuth@redhat.com>
9
Message-ID: <20230816061647.600672-1-tommy.wu@sifive.com>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20230627141216.3962299-4-tommy.wu@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
11
---
13
tests/qtest/sifive-e-aon-watchdog-test.c | 450 +++++++++++++++++++++++
12
target/riscv/csr.c | 7 +++++--
14
tests/qtest/meson.build | 3 +
13
1 file changed, 5 insertions(+), 2 deletions(-)
15
2 files changed, 453 insertions(+)
16
create mode 100644 tests/qtest/sifive-e-aon-watchdog-test.c
17
14
18
diff --git a/tests/qtest/sifive-e-aon-watchdog-test.c b/tests/qtest/sifive-e-aon-watchdog-test.c
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
19
new file mode 100644
20
index XXXXXXX..XXXXXXX
21
--- /dev/null
22
+++ b/tests/qtest/sifive-e-aon-watchdog-test.c
23
@@ -XXX,XX +XXX,XX @@
24
+/*
25
+ * QTest testcase for the watchdog timer of HiFive 1 rev b.
26
+ *
27
+ * Copyright (c) 2023 SiFive, Inc.
28
+ *
29
+ * This program is free software; you can redistribute it and/or modify it
30
+ * under the terms and conditions of the GNU General Public License,
31
+ * version 2 or later, as published by the Free Software Foundation.
32
+ *
33
+ * This program is distributed in the hope it will be useful, but WITHOUT
34
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
36
+ * more details.
37
+ *
38
+ * You should have received a copy of the GNU General Public License along with
39
+ * this program. If not, see <http://www.gnu.org/licenses/>.
40
+ */
41
+
42
+#include "qemu/osdep.h"
43
+#include "qemu/timer.h"
44
+#include "qemu/bitops.h"
45
+#include "libqtest.h"
46
+#include "hw/registerfields.h"
47
+#include "hw/misc/sifive_e_aon.h"
48
+
49
+FIELD(AON_WDT_WDOGCFG, SCALE, 0, 4)
50
+FIELD(AON_WDT_WDOGCFG, RSVD0, 4, 4)
51
+FIELD(AON_WDT_WDOGCFG, RSTEN, 8, 1)
52
+FIELD(AON_WDT_WDOGCFG, ZEROCMP, 9, 1)
53
+FIELD(AON_WDT_WDOGCFG, RSVD1, 10, 2)
54
+FIELD(AON_WDT_WDOGCFG, EN_ALWAYS, 12, 1)
55
+FIELD(AON_WDT_WDOGCFG, EN_CORE_AWAKE, 13, 1)
56
+FIELD(AON_WDT_WDOGCFG, RSVD2, 14, 14)
57
+FIELD(AON_WDT_WDOGCFG, IP0, 28, 1)
58
+FIELD(AON_WDT_WDOGCFG, RSVD3, 29, 3)
59
+
60
+#define WDOG_BASE (0x10000000)
61
+#define WDOGCFG (0x0)
62
+#define WDOGCOUNT (0x8)
63
+#define WDOGS (0x10)
64
+#define WDOGFEED (0x18)
65
+#define WDOGKEY (0x1c)
66
+#define WDOGCMP0 (0x20)
67
+
68
+#define SIFIVE_E_AON_WDOGKEY (0x51F15E)
69
+#define SIFIVE_E_AON_WDOGFEED (0xD09F00D)
70
+#define SIFIVE_E_LFCLK_DEFAULT_FREQ (32768)
71
+
72
+static void test_init(QTestState *qts)
73
+{
74
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
75
+ qtest_writel(qts, WDOG_BASE + WDOGCOUNT, 0);
76
+
77
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
78
+ qtest_writel(qts, WDOG_BASE + WDOGCFG, 0);
79
+
80
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
81
+ qtest_writel(qts, WDOG_BASE + WDOGCMP0, 0xBEEF);
82
+}
83
+
84
+static void test_wdogcount(void)
85
+{
86
+ uint64_t tmp;
87
+ QTestState *qts = qtest_init("-machine sifive_e");
88
+
89
+ test_init(qts);
90
+
91
+ tmp = qtest_readl(qts, WDOG_BASE + WDOGCOUNT);
92
+ qtest_writel(qts, WDOG_BASE + WDOGCOUNT, 0xBEEF);
93
+ g_assert(qtest_readl(qts, WDOG_BASE + WDOGCOUNT) == tmp);
94
+
95
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
96
+ qtest_writel(qts, WDOG_BASE + WDOGCOUNT, 0xBEEF);
97
+ g_assert(0xBEEF == qtest_readl(qts, WDOG_BASE + WDOGCOUNT));
98
+
99
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
100
+ qtest_writel(qts, WDOG_BASE + WDOGCOUNT, 0xAAAAAAAA);
101
+ g_assert(0x2AAAAAAA == qtest_readl(qts, WDOG_BASE + WDOGCOUNT));
102
+
103
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
104
+ qtest_writel(qts, WDOG_BASE + WDOGFEED, 0xAAAAAAAA);
105
+ g_assert(0x2AAAAAAA == qtest_readl(qts, WDOG_BASE + WDOGCOUNT));
106
+
107
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
108
+ qtest_writel(qts, WDOG_BASE + WDOGFEED, SIFIVE_E_AON_WDOGFEED);
109
+ g_assert(0 == qtest_readl(qts, WDOG_BASE + WDOGCOUNT));
110
+
111
+ qtest_quit(qts);
112
+}
113
+
114
+static void test_wdogcfg(void)
115
+{
116
+ uint32_t tmp_cfg;
117
+ QTestState *qts = qtest_init("-machine sifive_e");
118
+
119
+ test_init(qts);
120
+
121
+ tmp_cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
122
+ qtest_writel(qts, WDOG_BASE + WDOGCFG, 0xFFFFFFFF);
123
+ g_assert(qtest_readl(qts, WDOG_BASE + WDOGCFG) == tmp_cfg);
124
+
125
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
126
+ qtest_writel(qts, WDOG_BASE + WDOGCFG, 0xFFFFFFFF);
127
+ g_assert(0xFFFFFFFF == qtest_readl(qts, WDOG_BASE + WDOGCFG));
128
+
129
+ tmp_cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
130
+ g_assert(15 == FIELD_EX32(tmp_cfg, AON_WDT_WDOGCFG, SCALE));
131
+ g_assert(1 == FIELD_EX32(tmp_cfg, AON_WDT_WDOGCFG, RSTEN));
132
+ g_assert(1 == FIELD_EX32(tmp_cfg, AON_WDT_WDOGCFG, ZEROCMP));
133
+ g_assert(1 == FIELD_EX32(tmp_cfg, AON_WDT_WDOGCFG, EN_ALWAYS));
134
+ g_assert(1 == FIELD_EX32(tmp_cfg, AON_WDT_WDOGCFG, EN_CORE_AWAKE));
135
+ g_assert(1 == FIELD_EX32(tmp_cfg, AON_WDT_WDOGCFG, IP0));
136
+
137
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
138
+ qtest_writel(qts, WDOG_BASE + WDOGCFG, 0);
139
+ tmp_cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
140
+ g_assert(0 == FIELD_EX32(tmp_cfg, AON_WDT_WDOGCFG, SCALE));
141
+ g_assert(0 == FIELD_EX32(tmp_cfg, AON_WDT_WDOGCFG, RSTEN));
142
+ g_assert(0 == FIELD_EX32(tmp_cfg, AON_WDT_WDOGCFG, ZEROCMP));
143
+ g_assert(0 == FIELD_EX32(tmp_cfg, AON_WDT_WDOGCFG, EN_ALWAYS));
144
+ g_assert(0 == FIELD_EX32(tmp_cfg, AON_WDT_WDOGCFG, EN_CORE_AWAKE));
145
+ g_assert(0 == FIELD_EX32(tmp_cfg, AON_WDT_WDOGCFG, IP0));
146
+ g_assert(0 == qtest_readl(qts, WDOG_BASE + WDOGCFG));
147
+
148
+ qtest_quit(qts);
149
+}
150
+
151
+static void test_wdogcmp0(void)
152
+{
153
+ uint32_t tmp;
154
+ QTestState *qts = qtest_init("-machine sifive_e");
155
+
156
+ test_init(qts);
157
+
158
+ tmp = qtest_readl(qts, WDOG_BASE + WDOGCMP0);
159
+ qtest_writel(qts, WDOG_BASE + WDOGCMP0, 0xBEEF);
160
+ g_assert(qtest_readl(qts, WDOG_BASE + WDOGCMP0) == tmp);
161
+
162
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
163
+ qtest_writel(qts, WDOG_BASE + WDOGCMP0, 0xBEEF);
164
+ g_assert(0xBEEF == qtest_readl(qts, WDOG_BASE + WDOGCMP0));
165
+
166
+ qtest_quit(qts);
167
+}
168
+
169
+static void test_wdogkey(void)
170
+{
171
+ QTestState *qts = qtest_init("-machine sifive_e");
172
+
173
+ test_init(qts);
174
+
175
+ g_assert(0 == qtest_readl(qts, WDOG_BASE + WDOGKEY));
176
+
177
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, 0xFFFF);
178
+ g_assert(0 == qtest_readl(qts, WDOG_BASE + WDOGKEY));
179
+
180
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
181
+ g_assert(1 == qtest_readl(qts, WDOG_BASE + WDOGKEY));
182
+
183
+ qtest_writel(qts, WDOG_BASE + WDOGFEED, 0xAAAAAAAA);
184
+ g_assert(0 == qtest_readl(qts, WDOG_BASE + WDOGKEY));
185
+
186
+ qtest_quit(qts);
187
+}
188
+
189
+static void test_wdogfeed(void)
190
+{
191
+ QTestState *qts = qtest_init("-machine sifive_e");
192
+
193
+ test_init(qts);
194
+
195
+ g_assert(0 == qtest_readl(qts, WDOG_BASE + WDOGFEED));
196
+
197
+ qtest_writel(qts, WDOG_BASE + WDOGFEED, 0xFFFF);
198
+ g_assert(0 == qtest_readl(qts, WDOG_BASE + WDOGFEED));
199
+
200
+ qtest_quit(qts);
201
+}
202
+
203
+static void test_scaled_wdogs(void)
204
+{
205
+ uint32_t cfg;
206
+ uint32_t fake_count = 0x12345678;
207
+ QTestState *qts = qtest_init("-machine sifive_e");
208
+
209
+ test_init(qts);
210
+
211
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
212
+ qtest_writel(qts, WDOG_BASE + WDOGCOUNT, fake_count);
213
+ g_assert(qtest_readl(qts, WDOG_BASE + WDOGCOUNT) == fake_count);
214
+ g_assert((uint16_t)qtest_readl(qts, WDOG_BASE + WDOGS) ==
215
+ (uint16_t)fake_count);
216
+
217
+ for (int i = 0; i < 16; i++) {
218
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
219
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, SCALE, i);
220
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
221
+ qtest_writel(qts, WDOG_BASE + WDOGCFG, cfg);
222
+ g_assert((uint16_t)qtest_readl(qts, WDOG_BASE + WDOGS) ==
223
+ (uint16_t)(fake_count >>
224
+ FIELD_EX32(cfg, AON_WDT_WDOGCFG, SCALE)));
225
+ }
226
+
227
+ qtest_quit(qts);
228
+}
229
+
230
+static void test_watchdog(void)
231
+{
232
+ uint32_t cfg;
233
+ QTestState *qts = qtest_init("-machine sifive_e");
234
+
235
+ test_init(qts);
236
+
237
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
238
+ qtest_writel(qts, WDOG_BASE + WDOGCMP0, SIFIVE_E_LFCLK_DEFAULT_FREQ);
239
+
240
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
241
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, SCALE, 0);
242
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, EN_ALWAYS, 1);
243
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
244
+ qtest_writel(qts, WDOG_BASE + WDOGCFG, cfg);
245
+
246
+ qtest_clock_step(qts, NANOSECONDS_PER_SECOND);
247
+
248
+ g_assert(qtest_readl(qts, WDOG_BASE + WDOGCOUNT) ==
249
+ SIFIVE_E_LFCLK_DEFAULT_FREQ);
250
+ g_assert(qtest_readl(qts, WDOG_BASE + WDOGS) ==
251
+ SIFIVE_E_LFCLK_DEFAULT_FREQ);
252
+
253
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
254
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, SCALE));
255
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, RSTEN));
256
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, ZEROCMP));
257
+ g_assert(1 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, EN_ALWAYS));
258
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, EN_CORE_AWAKE));
259
+ g_assert(1 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, IP0));
260
+
261
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
262
+ qtest_writel(qts, WDOG_BASE + WDOGCOUNT, 0);
263
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, IP0, 0);
264
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
265
+ qtest_writel(qts, WDOG_BASE + WDOGCFG, cfg);
266
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
267
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, IP0));
268
+
269
+ qtest_quit(qts);
270
+}
271
+
272
+static void test_scaled_watchdog(void)
273
+{
274
+ uint32_t cfg;
275
+ QTestState *qts = qtest_init("-machine sifive_e");
276
+
277
+ test_init(qts);
278
+
279
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
280
+ qtest_writel(qts, WDOG_BASE + WDOGCMP0, 10);
281
+
282
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
283
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, SCALE, 15);
284
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, EN_ALWAYS, 1);
285
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
286
+ qtest_writel(qts, WDOG_BASE + WDOGCFG, cfg);
287
+
288
+ qtest_clock_step(qts, NANOSECONDS_PER_SECOND * 10);
289
+
290
+ g_assert(qtest_readl(qts, WDOG_BASE + WDOGCOUNT) ==
291
+ SIFIVE_E_LFCLK_DEFAULT_FREQ * 10);
292
+
293
+ g_assert(10 == qtest_readl(qts, WDOG_BASE + WDOGS));
294
+
295
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
296
+ g_assert(15 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, SCALE));
297
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, RSTEN));
298
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, ZEROCMP));
299
+ g_assert(1 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, EN_ALWAYS));
300
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, EN_CORE_AWAKE));
301
+ g_assert(1 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, IP0));
302
+
303
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
304
+ qtest_writel(qts, WDOG_BASE + WDOGCOUNT, 0);
305
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, IP0, 0);
306
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
307
+ qtest_writel(qts, WDOG_BASE + WDOGCFG, cfg);
308
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
309
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, IP0));
310
+
311
+ qtest_quit(qts);
312
+}
313
+
314
+static void test_periodic_int(void)
315
+{
316
+ uint32_t cfg;
317
+ QTestState *qts = qtest_init("-machine sifive_e");
318
+
319
+ test_init(qts);
320
+
321
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
322
+ qtest_writel(qts, WDOG_BASE + WDOGCMP0, SIFIVE_E_LFCLK_DEFAULT_FREQ);
323
+
324
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
325
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, SCALE, 0);
326
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, ZEROCMP, 1);
327
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, EN_ALWAYS, 1);
328
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
329
+ qtest_writel(qts, WDOG_BASE + WDOGCFG, cfg);
330
+
331
+ qtest_clock_step(qts, NANOSECONDS_PER_SECOND);
332
+
333
+ g_assert(0 == qtest_readl(qts, WDOG_BASE + WDOGCOUNT));
334
+ g_assert(0 == qtest_readl(qts, WDOG_BASE + WDOGS));
335
+
336
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
337
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, SCALE));
338
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, RSTEN));
339
+ g_assert(1 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, ZEROCMP));
340
+ g_assert(1 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, EN_ALWAYS));
341
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, EN_CORE_AWAKE));
342
+ g_assert(1 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, IP0));
343
+
344
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, IP0, 0);
345
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
346
+ qtest_writel(qts, WDOG_BASE + WDOGCFG, cfg);
347
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
348
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, IP0));
349
+
350
+ qtest_clock_step(qts, NANOSECONDS_PER_SECOND);
351
+
352
+ g_assert(0 == qtest_readl(qts, WDOG_BASE + WDOGCOUNT));
353
+ g_assert(0 == qtest_readl(qts, WDOG_BASE + WDOGS));
354
+
355
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
356
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, SCALE));
357
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, RSTEN));
358
+ g_assert(1 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, ZEROCMP));
359
+ g_assert(1 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, EN_ALWAYS));
360
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, EN_CORE_AWAKE));
361
+ g_assert(1 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, IP0));
362
+
363
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, IP0, 0);
364
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
365
+ qtest_writel(qts, WDOG_BASE + WDOGCFG, cfg);
366
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
367
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, IP0));
368
+
369
+ qtest_quit(qts);
370
+}
371
+
372
+static void test_enable_disable(void)
373
+{
374
+ uint32_t cfg;
375
+ QTestState *qts = qtest_init("-machine sifive_e");
376
+
377
+ test_init(qts);
378
+
379
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
380
+ qtest_writel(qts, WDOG_BASE + WDOGCMP0, 10);
381
+
382
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
383
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, SCALE, 15);
384
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, EN_ALWAYS, 1);
385
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
386
+ qtest_writel(qts, WDOG_BASE + WDOGCFG, cfg);
387
+
388
+ qtest_clock_step(qts, NANOSECONDS_PER_SECOND * 2);
389
+
390
+ g_assert(qtest_readl(qts, WDOG_BASE + WDOGCOUNT) ==
391
+ SIFIVE_E_LFCLK_DEFAULT_FREQ * 2);
392
+ g_assert(2 == qtest_readl(qts, WDOG_BASE + WDOGS));
393
+
394
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
395
+ g_assert(15 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, SCALE));
396
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, RSTEN));
397
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, ZEROCMP));
398
+ g_assert(1 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, EN_ALWAYS));
399
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, EN_CORE_AWAKE));
400
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, IP0));
401
+
402
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
403
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, EN_ALWAYS, 0);
404
+ qtest_writel(qts, WDOG_BASE + WDOGCFG, cfg);
405
+
406
+ qtest_clock_step(qts, NANOSECONDS_PER_SECOND * 8);
407
+
408
+ g_assert(qtest_readl(qts, WDOG_BASE + WDOGCOUNT) ==
409
+ SIFIVE_E_LFCLK_DEFAULT_FREQ * 2);
410
+ g_assert(2 == qtest_readl(qts, WDOG_BASE + WDOGS));
411
+
412
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
413
+ g_assert(15 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, SCALE));
414
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, RSTEN));
415
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, ZEROCMP));
416
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, EN_ALWAYS));
417
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, EN_CORE_AWAKE));
418
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, IP0));
419
+
420
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, EN_ALWAYS, 1);
421
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
422
+ qtest_writel(qts, WDOG_BASE + WDOGCFG, cfg);
423
+
424
+ qtest_clock_step(qts, NANOSECONDS_PER_SECOND * 8);
425
+
426
+ g_assert(qtest_readl(qts, WDOG_BASE + WDOGCOUNT) ==
427
+ SIFIVE_E_LFCLK_DEFAULT_FREQ * 10);
428
+ g_assert(10 == qtest_readl(qts, WDOG_BASE + WDOGS));
429
+
430
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
431
+ g_assert(15 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, SCALE));
432
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, RSTEN));
433
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, ZEROCMP));
434
+ g_assert(1 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, EN_ALWAYS));
435
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, EN_CORE_AWAKE));
436
+ g_assert(1 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, IP0));
437
+
438
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
439
+ qtest_writel(qts, WDOG_BASE + WDOGCOUNT, 0);
440
+ cfg = FIELD_DP32(cfg, AON_WDT_WDOGCFG, IP0, 0);
441
+ qtest_writel(qts, WDOG_BASE + WDOGKEY, SIFIVE_E_AON_WDOGKEY);
442
+ qtest_writel(qts, WDOG_BASE + WDOGCFG, cfg);
443
+ cfg = qtest_readl(qts, WDOG_BASE + WDOGCFG);
444
+ g_assert(0 == FIELD_EX32(cfg, AON_WDT_WDOGCFG, IP0));
445
+
446
+ qtest_quit(qts);
447
+}
448
+
449
+int main(int argc, char *argv[])
450
+{
451
+ g_test_init(&argc, &argv, NULL);
452
+ qtest_add_func("/sifive-e-aon-watchdog-test/wdogcount",
453
+ test_wdogcount);
454
+ qtest_add_func("/sifive-e-aon-watchdog-test/wdogcfg",
455
+ test_wdogcfg);
456
+ qtest_add_func("/sifive-e-aon-watchdog-test/wdogcmp0",
457
+ test_wdogcmp0);
458
+ qtest_add_func("/sifive-e-aon-watchdog-test/wdogkey",
459
+ test_wdogkey);
460
+ qtest_add_func("/sifive-e-aon-watchdog-test/wdogfeed",
461
+ test_wdogfeed);
462
+ qtest_add_func("/sifive-e-aon-watchdog-test/scaled_wdogs",
463
+ test_scaled_wdogs);
464
+ qtest_add_func("/sifive-e-aon-watchdog-test/watchdog",
465
+ test_watchdog);
466
+ qtest_add_func("/sifive-e-aon-watchdog-test/scaled_watchdog",
467
+ test_scaled_watchdog);
468
+ qtest_add_func("/sifive-e-aon-watchdog-test/periodic_int",
469
+ test_periodic_int);
470
+ qtest_add_func("/sifive-e-aon-watchdog-test/enable_disable",
471
+ test_enable_disable);
472
+ return g_test_run();
473
+}
474
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
475
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
476
--- a/tests/qtest/meson.build
17
--- a/target/riscv/csr.c
477
+++ b/tests/qtest/meson.build
18
+++ b/target/riscv/csr.c
478
@@ -XXX,XX +XXX,XX @@ qtests_s390x = \
19
@@ -XXX,XX +XXX,XX @@ static int rmw_iprio(target_ulong xlen,
479
'cpu-plug-test',
20
static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
480
'migration-test']
21
target_ulong new_val, target_ulong wr_mask)
481
22
{
482
+qtests_riscv32 = \
23
- bool virt;
483
+ (config_all_devices.has_key('CONFIG_SIFIVE_E_AON') ? ['sifive-e-aon-watchdog-test'] : [])
24
+ bool virt, isel_reserved;
484
+
25
uint8_t *iprio;
485
qos_test_ss = ss.source_set()
26
int ret = -EINVAL;
486
qos_test_ss.add(
27
target_ulong priv, isel, vgein;
487
'ac97-test.c',
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;
42
}
43
44
done:
45
if (ret) {
46
- return (env->virt_enabled && virt) ?
47
+ return (env->virt_enabled && virt && !isel_reserved) ?
48
RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
49
}
50
return RISCV_EXCP_NONE;
488
--
51
--
489
2.40.1
52
2.41.0
diff view generated by jsdifflib
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
1
From: Nikita Shubin <n.shubin@yadro.com>
2
2
3
MPV and GVA bits are added by hypervisor extension to mstatus
3
As per ISA:
4
and mstatush (if MXLEN=32).
5
4
6
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
5
"For CSRRWI, if rd=x0, then the instruction shall not read the CSR and
7
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
6
shall not cause any of the side effects that might occur on a CSR read."
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
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>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20230603134236.15719-3-liweiwei@iscas.ac.cn>
13
Message-ID: <20230808090914.17634-1-nikita.shubin@maquefel.me>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
15
---
13
target/riscv/csr.c | 10 ++++------
16
target/riscv/csr.c | 24 +++++++++++++++---------
14
1 file changed, 4 insertions(+), 6 deletions(-)
17
1 file changed, 15 insertions(+), 9 deletions(-)
15
18
16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
19
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/csr.c
21
--- a/target/riscv/csr.c
19
+++ b/target/riscv/csr.c
22
+++ b/target/riscv/csr.c
20
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
23
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
24
target_ulong write_mask)
25
{
26
RISCVException ret;
27
- target_ulong old_value;
28
+ target_ulong old_value = 0;
29
30
/* execute combined read/write operation if it exists */
31
if (csr_ops[csrno].op) {
32
return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
21
}
33
}
22
34
23
if (xl != MXL_RV32 || env->debugger) {
35
- /* if no accessor exists then return failure */
24
- /*
36
- if (!csr_ops[csrno].read) {
25
- * RV32: MPV and GVA are not in mstatus. The current plan is to
37
- return RISCV_EXCP_ILLEGAL_INST;
26
- * add them to mstatush. For now, we just don't support it.
38
- }
27
- */
39
- /* read old value */
28
- mask |= MSTATUS_MPV | MSTATUS_GVA;
40
- ret = csr_ops[csrno].read(env, csrno, &old_value);
29
+ if (riscv_has_ext(env, RVH)) {
41
- if (ret != RISCV_EXCP_NONE) {
30
+ mask |= MSTATUS_MPV | MSTATUS_GVA;
42
- return ret;
43
+ /*
44
+ * ret_value == NULL means that rd=x0 and we're coming from helper_csrw()
45
+ * and we can't throw side effects caused by CSR reads.
46
+ */
47
+ if (ret_value) {
48
+ /* if no accessor exists then return failure */
49
+ if (!csr_ops[csrno].read) {
50
+ return RISCV_EXCP_ILLEGAL_INST;
31
+ }
51
+ }
32
if ((val & MSTATUS64_UXL) != 0) {
52
+ /* read old value */
33
mask |= MSTATUS64_UXL;
53
+ ret = csr_ops[csrno].read(env, csrno, &old_value);
34
}
54
+ if (ret != RISCV_EXCP_NONE) {
35
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatush(CPURISCVState *env, int csrno,
55
+ return ret;
36
target_ulong val)
56
+ }
37
{
57
}
38
uint64_t valh = (uint64_t)val << 32;
58
39
- uint64_t mask = MSTATUS_MPV | MSTATUS_GVA;
59
/* write value if writable and write mask set, otherwise drop writes */
40
+ uint64_t mask = riscv_has_ext(env, RVH) ? MSTATUS_MPV | MSTATUS_GVA : 0;
41
42
env->mstatus = (env->mstatus & ~mask) | (valh & mask);
43
44
--
60
--
45
2.40.1
61
2.41.0
diff view generated by jsdifflib
Deleted patch
1
From: Bin Meng <bmeng@tinylab.org>
2
1
3
Upgrade OpenSBI from v1.2 to v1.3 and the pre-built bios images.
4
5
The v1.3 release includes the following commits:
6
7
440fa81 treewide: Replace TRUE/FALSE with true/false
8
6509127 Makefile: Remove -N ldflag to prevent linker RWX warning
9
65638f8 lib: utils/sys: Allow custom HTIF base address for RV32
10
f14595a lib: sbi: Allow platform to influence cold boot HART selection
11
6957ae0 platform: generic: Allow platform_override to select cold boot HART
12
cb7e7c3 platform: generic: Allow platform_override to perform firmware init
13
8020df8 generic/starfive: Add Starfive JH7110 platform implementation
14
6997552 lib: sbi_hsm: Rename 'priv' argument to 'arg1'
15
9e397e3 docs: domain_support: Use capital letter for privilege modes
16
9e0ba09 include: sbi: Fine grain the permissions for M and SU modes
17
aace1e1 lib: sbi: Use finer permission semantics for address validation
18
22dbdb3 lib: sbi: Add permissions for the firmware start till end
19
1ac14f1 lib: sbi: Use finer permission sematics to decide on PMP bits
20
44f736c lib: sbi: Modify the boot time region flag prints
21
20646e0 lib: utils: Use SU-{R/W/X} flags for region permissions during parsing
22
3e2f573 lib: utils: Disallow non-root domains from adding M-mode regions
23
59a08cd lib: utils: Add M-mode {R/W} flags to the MMIO regions
24
001106d docs: Update domain's region permissions and requirements
25
da5594b platform: generic: allwinner: Fix PLIC array bounds
26
ce2a834 docs: generic.md: fix typo of andes-ae350
27
8ecbe6d lib: sbi_hsm: handle failure when hart_stop returns SBI_ENOTSUPP
28
b1818ee include: types: add always inline compiler attribute
29
9c4eb35 lib: utils: atcsmu: Add Andes System Management Unit support
30
787296a platform: andes/ae350: Implement hart hotplug using HSM extension
31
7aaeeab lib: reset/fdt_reset_atcwdt200: Use defined macros and function in atcsmu.h
32
a990309 lib: utils: Fix reserved memory node for firmware memory
33
fefa548 firmware: Split RO/RX and RW sections
34
2f40a99 firmware: Move dynsym and reladyn sections to RX section
35
c10e3fe firmware: Add RW section offset in scratch
36
b666760 lib: sbi: Print the RW section offset
37
230278d lib: sbi: Add separate entries for firmware RX and RW regions
38
dea0922 platform: renesas/rzfive: Configure Local memory regions as part of root domain
39
33bf917 lib: utils: Add fdt_add_cpu_idle_states() helper function
40
c45992c platform: generic: allwinner: Advertise nonretentive suspend
41
c8ea836 firmware: Fix fw_rw_offset computation in fw_base.S
42
8050081 firmware: Not to clear all the MIP
43
84d15f4 lib: sbi_hsm: Use csr_set to restore the MIP
44
199189b lib: utils: Mark only the largest region as reserved in FDT
45
66b0e23 lib: sbi: Ensure domidx_to_domain_table is null-terminated
46
642f3de Makefile: Add missing .dep files for fw_*.elf.ld
47
09b34d8 include: Add support for byteorder/endianness conversion
48
680bea0 lib: utils/fdt: Use byteorder conversion functions in libfdt_env.h
49
b224ddb include: types: Add typedefs for endianness
50
aa5dafc include: sbi: Fix BSWAPx() macros for big-endian host
51
e3bf1af include: Add defines for SBI debug console extension
52
0ee3a86 lib: sbi: Add sbi_nputs() function
53
4e0572f lib: sbi: Add sbi_ngets() function
54
eab48c3 lib: sbi: Add sbi_domain_check_addr_range() function
55
5a41a38 lib: sbi: Implement SBI debug console extension
56
c43903c lib: sbi: Add console_puts() callback in the console device
57
29285ae lib: utils/serial: Implement console_puts() for semihosting
58
65c2190 lib: sbi: Speed-up sbi_printf() and friends using nputs()
59
321293c lib: utils/fdt: Fix fdt_pmu.c header dependency
60
aafcc90 platform: generic/allwinner: Fix sun20i-d1.c header dependency
61
745aaec platform: generic/andes: Fix ae350.c header dependency
62
99d09b6 include: fdt/fdt_helper: Change fdt_get_address() to return root.next_arg1
63
6861ee9 lib: utils: fdt_fixup: Fix compile error
64
4f2be40 docs: fix typo in fw.md
65
30ea806 lib: sbi_hart: Enable hcontext and scontext
66
81adc62 lib: sbi: Align SBI vendor extension id with mvendorid CSR
67
31b82e0 include: sbi: Remove extid parameter from vendor_ext_provider() callback
68
c100951 platform: generic: renesas: rzfive: Add support to configure the PMA
69
2491242 platform: generic: renesas: rzfive: Configure the PMA region
70
67b2a40 lib: sbi: sbi_ecall: Check the range of SBI error
71
5a75f53 lib: sbi/sbi_domain: cosmetic style fixes
72
bc06ff6 lib: utils/fdt/fdt_domain: Simplify region access permission check
73
17b3776 docs: domain_support: Update the DT example
74
1364d5a lib: sbi_hsm: Factor out invalid state detection
75
40f16a8 lib: sbi_hsm: Don't try to restore state on failed change
76
c88e039 lib: sbi_hsm: Ensure errors are consistent with spec
77
b1ae6ef lib: sbi_hsm: Move misplaced comment
78
07673fc lib: sbi_hsm: Remove unnecessary include
79
8a40306 lib: sbi_hsm: Export some functions
80
73623a0 lib: sbi: Add system suspend skeleton
81
c9917b6 lib: sbi: Add system_suspend_allowed domain property
82
7c964e2 lib: sbi: Implement system suspend
83
37558dc docs: Correct opensbi-domain property name
84
5ccebf0 platform: generic: Add system suspend test
85
908be1b gpio/starfive: add gpio driver and support gpio reset
86
4b28afc make: Add a command line option for debugging OpenSBI
87
e9d08bd lib: utils/i2c: Add minimal StarFive jh7110 I2C driver
88
568ea49 platform: starfive: add PMIC power ops in JH7110 visionfive2 board
89
506144f lib: serial: Cadence: Enable compatibility for cdns,uart-r1p8
90
1fe8dc9 lib: sbi_pmu: add callback for counter width
91
51951d9 lib: sbi_pmu: Implement sbi_pmu_counter_fw_read_hi
92
60c358e lib: sbi_pmu: Reserve space for implementation specific firmware events
93
548e4b4 lib: sbi_pmu: Rename fw_counter_value
94
b51ddff lib: sbi_pmu: Update sbi_pmu dev ops
95
641d2e9 lib: sbi_pmu: Use dedicated event code for platform firmware events
96
57d3aa3 lib: sbi_pmu: Introduce fw_counter_write_value API
97
c631a7d lib: sbi_pmu: Add hartid parameter PMU device ops
98
d56049e lib: sbi: Refactor the calls to sbi_hart_switch_mode()
99
e8e9ed3 lib: sbi: Set the state of a hart to START_PENDING after the hart is ready
100
c6a092c lib: sbi: Clear IPIs before init_warm_startup in non-boot harts
101
ed88a63 lib: sbi_scratch: Optimize the alignment code for alloc size
102
73ab11d lib: sbi: Fix how to check whether the domain contains fw_region
103
f64dfcd lib: sbi: Introduce sbi_entry_count() function
104
30b9e7e lib: sbi_hsm: Fix sbi_hsm_hart_start() for platform with hart hotplug
105
8e90259 lib: sbi_hart: clear mip csr during hart init
106
45ba2b2 include: Add defines for SBI CPPC extension
107
33caae8 lib: sbi: Implement SBI CPPC extension
108
91767d0 lib: sbi: Print the CPPC device name
109
edc9914 lib: sbi_pmu: Align the event type offset as per SBI specification
110
ee016a7 docs: Correct FW_JUMP_FDT_ADDR calculation example
111
2868f26 lib: utils: fdt_fixup: avoid buffer overrun
112
66fa925 lib: sbi: Optimize sbi_tlb
113
24dde46 lib: sbi: Optimize sbi_ipi
114
80078ab sbi: tlb: Simplify to tlb_process_count/tlb_process function
115
bf40e07 lib: sbi: Optimize sbi_tlb queue waiting
116
eeab500 platform: generic: andes/renesas: Add SBI EXT to check for enabling IOCP errata
117
f692289 firmware: Optimize loading relocation type
118
e41dbb5 firmware: Change to use positive offset to access relocation entries
119
bdb3c42 lib: sbi: Do not clear active_events for cycle/instret when stopping
120
674e019 lib: sbi: Fix counter index calculation for SBI_PMU_CFG_FLAG_SKIP_MATCH
121
f5dfd99 lib: sbi: Don't check SBI error range for legacy console getchar
122
7919530 lib: sbi: Add debug print when sbi_pmu_init fails
123
4e33530 lib: sbi: Remove unnecessary semicolon
124
6bc02de lib: sbi: Simplify sbi_ipi_process remove goto
125
dc1c7db lib: sbi: Simplify BITS_PER_LONG definition
126
f58c140 lib: sbi: Introduce register_extensions extension callback
127
e307ba7 lib: sbi: Narrow vendor extension range
128
042f0c3 lib: sbi: pmu: Remove unnecessary probe function
129
8b952d4 lib: sbi: Only register available extensions
130
767b5fc lib: sbi: Optimize probe of srst/susp
131
c3e31cb lib: sbi: Remove 0/1 probe implementations
132
33f1722 lib: sbi: Document sbi_ecall_extension members
133
d4c46e0 Makefile: Dereference symlinks on install
134
8b99a7f lib: sbi: Fix return of sbi_console_init
135
264d0be lib: utils: Improve fdt_serial_init
136
9a0bdd0 lib: utils: Improve fdt_ipi
137
122f226 lib: utils: Improve fdt_timer
138
df75e09 lib: utils/ipi: buffer overrun aclint_mswi_cold_init
139
bdde2ec lib: sbi: Align system suspend errors with spec
140
aad7a37 include: sbi_scratch: Add helper macros to access data type
141
5cf9a54 platform: Allow platforms to specify heap size
142
40d36a6 lib: sbi: Introduce simple heap allocator
143
2a04f70 lib: sbi: Print scratch size and usage at boot time
144
bbff53f lib: sbi_pmu: Use heap for per-HART PMU state
145
ef4542d lib: sbi: Use heap for root domain creation
146
66daafe lib: sbi: Use scratch space to save per-HART domain pointer
147
fa5ad2e lib: utils/gpio: Use heap in SiFive and StartFive GPIO drivers
148
903e88c lib: utils/i2c: Use heap in DesignWare and SiFive I2C drivers
149
5a8cfcd lib: utils/ipi: Use heap in ACLINT MSWI driver
150
3013716 lib: utils/irqchip: Use heap in PLIC, APLIC and IMSIC drivers
151
7e5636a lib: utils/timer: Use heap in ACLINT MTIMER driver
152
3c1c972 lib: utils/fdt: Use heap in FDT domain parsing
153
acbd8fc lib: utils/ipi: Use scratch space to save per-HART MSWI pointer
154
f0516be lib: utils/timer: Use scratch space to save per-HART MTIMER pointer
155
b3594ac lib: utils/irqchip: Use scratch space to save per-HART PLIC pointer
156
1df52fa lib: utils/irqchip: Don't check hartid in imsic_update_hartid_table()
157
355796c lib: utils/irqchip: Use scratch space to save per-HART IMSIC pointer
158
524feec docs: Add OpenSBI logo and use it in the top-level README.md
159
932be2c README.md: Improve project copyright information
160
8153b26 platform/lib: Set no-map attribute on all PMP regions
161
d64942f firmware: Fix find hart index
162
27c957a lib: reset: Move fdt_reset_init into generic_early_init
163
8bd666a lib: sbi: check A2 register in ecall_dbcn_handler.
164
2552799 include: Bump-up version to 1.3
165
166
Signed-off-by: Bin Meng <bmeng@tinylab.org>
167
Message-Id: <20230630160717.843044-1-bmeng@tinylab.org>
168
Tested-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
169
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
170
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
171
---
172
.../opensbi-riscv32-generic-fw_dynamic.bin | Bin 123072 -> 135344 bytes
173
.../opensbi-riscv64-generic-fw_dynamic.bin | Bin 121800 -> 138304 bytes
174
roms/opensbi | 2 +-
175
3 files changed, 1 insertion(+), 1 deletion(-)
176
177
diff --git a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin
178
index XXXXXXX..XXXXXXX 100644
179
Binary files a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin and b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin differ
180
diff --git a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin
181
index XXXXXXX..XXXXXXX 100644
182
Binary files a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin and b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin differ
183
diff --git a/roms/opensbi b/roms/opensbi
184
index XXXXXXX..XXXXXXX 160000
185
--- a/roms/opensbi
186
+++ b/roms/opensbi
187
@@ -1 +1 @@
188
-Subproject commit 6b5188ca14e59ce7bf71afe4e7d3d557c3d31bf8
189
+Subproject commit 2552799a1df30a3dcd2321a8b75d61d06f5fb9fc
190
--
191
2.40.1
diff view generated by jsdifflib
Deleted patch
1
From: Bin Meng <bmeng@tinylab.org>
2
1
3
The 32-bit Spike boot issue has been fixed in the OpenSBI v1.3.
4
Let's enable the 32-bit Spike OpenSBI boot testing.
5
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Message-Id: <20230630160717.843044-2-bmeng@tinylab.org>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
tests/avocado/riscv_opensbi.py | 2 --
13
1 file changed, 2 deletions(-)
14
15
diff --git a/tests/avocado/riscv_opensbi.py b/tests/avocado/riscv_opensbi.py
16
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/avocado/riscv_opensbi.py
18
+++ b/tests/avocado/riscv_opensbi.py
19
@@ -XXX,XX +XXX,XX @@
20
# later. See the COPYING file in the top-level directory.
21
22
from avocado_qemu import QemuSystemTest
23
-from avocado import skip
24
from avocado_qemu import wait_for_console_pattern
25
26
class RiscvOpenSBI(QemuSystemTest):
27
@@ -XXX,XX +XXX,XX @@ def boot_opensbi(self):
28
wait_for_console_pattern(self, 'Platform Name')
29
wait_for_console_pattern(self, 'Boot HART MEDELEG')
30
31
- @skip("requires OpenSBI fix to work")
32
def test_riscv32_spike(self):
33
"""
34
:avocado: tags=arch:riscv32
35
--
36
2.40.1
diff view generated by jsdifflib
Deleted patch
1
From: Tommy Wu <tommy.wu@sifive.com>
2
1
3
Create the AON device when we realize the sifive_e machine.
4
This patch only implemented the functionality of the watchdog timer,
5
not all the functionality of the AON device.
6
7
Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-Id: <20230627141216.3962299-3-tommy.wu@sifive.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
include/hw/riscv/sifive_e.h | 9 ++++++---
15
hw/riscv/sifive_e.c | 17 +++++++++++++++--
16
hw/riscv/Kconfig | 1 +
17
3 files changed, 22 insertions(+), 5 deletions(-)
18
19
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/riscv/sifive_e.h
22
+++ b/include/hw/riscv/sifive_e.h
23
@@ -XXX,XX +XXX,XX @@
24
#include "hw/riscv/riscv_hart.h"
25
#include "hw/riscv/sifive_cpu.h"
26
#include "hw/gpio/sifive_gpio.h"
27
+#include "hw/misc/sifive_e_aon.h"
28
#include "hw/boards.h"
29
30
#define TYPE_RISCV_E_SOC "riscv.sifive.e.soc"
31
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveESoCState {
32
/*< public >*/
33
RISCVHartArrayState cpus;
34
DeviceState *plic;
35
+ SiFiveEAONState aon;
36
SIFIVEGPIOState gpio;
37
MemoryRegion xip_mem;
38
MemoryRegion mask_rom;
39
@@ -XXX,XX +XXX,XX @@ enum {
40
};
41
42
enum {
43
- SIFIVE_E_UART0_IRQ = 3,
44
- SIFIVE_E_UART1_IRQ = 4,
45
- SIFIVE_E_GPIO0_IRQ0 = 8
46
+ SIFIVE_E_AON_WDT_IRQ = 1,
47
+ SIFIVE_E_UART0_IRQ = 3,
48
+ SIFIVE_E_UART1_IRQ = 4,
49
+ SIFIVE_E_GPIO0_IRQ0 = 8
50
};
51
52
#define SIFIVE_E_PLIC_HART_CONFIG "M"
53
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/riscv/sifive_e.c
56
+++ b/hw/riscv/sifive_e.c
57
@@ -XXX,XX +XXX,XX @@
58
#include "hw/intc/riscv_aclint.h"
59
#include "hw/intc/sifive_plic.h"
60
#include "hw/misc/sifive_e_prci.h"
61
+#include "hw/misc/sifive_e_aon.h"
62
#include "chardev/char.h"
63
#include "sysemu/sysemu.h"
64
65
@@ -XXX,XX +XXX,XX @@ static void sifive_e_soc_init(Object *obj)
66
object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x1004, &error_abort);
67
object_initialize_child(obj, "riscv.sifive.e.gpio0", &s->gpio,
68
TYPE_SIFIVE_GPIO);
69
+ object_initialize_child(obj, "riscv.sifive.e.aon", &s->aon,
70
+ TYPE_SIFIVE_E_AON);
71
}
72
73
static void sifive_e_soc_realize(DeviceState *dev, Error **errp)
74
@@ -XXX,XX +XXX,XX @@ static void sifive_e_soc_realize(DeviceState *dev, Error **errp)
75
RISCV_ACLINT_DEFAULT_MTIMER_SIZE, 0, ms->smp.cpus,
76
RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME,
77
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, false);
78
- create_unimplemented_device("riscv.sifive.e.aon",
79
- memmap[SIFIVE_E_DEV_AON].base, memmap[SIFIVE_E_DEV_AON].size);
80
sifive_e_prci_create(memmap[SIFIVE_E_DEV_PRCI].base);
81
82
+ /* AON */
83
+
84
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->aon), errp)) {
85
+ return;
86
+ }
87
+
88
+ /* Map AON registers */
89
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->aon), 0, memmap[SIFIVE_E_DEV_AON].base);
90
+
91
/* GPIO */
92
93
if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) {
94
@@ -XXX,XX +XXX,XX @@ static void sifive_e_soc_realize(DeviceState *dev, Error **errp)
95
qdev_get_gpio_in(DEVICE(s->plic),
96
SIFIVE_E_GPIO0_IRQ0 + i));
97
}
98
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->aon), 0,
99
+ qdev_get_gpio_in(DEVICE(s->plic),
100
+ SIFIVE_E_AON_WDT_IRQ));
101
102
sifive_uart_create(sys_mem, memmap[SIFIVE_E_DEV_UART0].base,
103
serial_hd(0), qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_E_UART0_IRQ));
104
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
105
index XXXXXXX..XXXXXXX 100644
106
--- a/hw/riscv/Kconfig
107
+++ b/hw/riscv/Kconfig
108
@@ -XXX,XX +XXX,XX @@ config SIFIVE_E
109
select SIFIVE_PLIC
110
select SIFIVE_UART
111
select SIFIVE_E_PRCI
112
+ select SIFIVE_E_AON
113
select UNIMP
114
115
config SIFIVE_U
116
--
117
2.40.1
118
119
diff view generated by jsdifflib