1
From: Alistair Francis <alistair.francis@wdc.com>
1
The following changes since commit c5ea91da443b458352c1b629b490ee6631775cb4:
2
2
3
The following changes since commit 222059a0fccf4af3be776fe35a5ea2d6a68f9a0b:
3
Merge tag 'pull-trivial-patches' of https://gitlab.com/mjt0k/qemu into staging (2023-09-08 10:06:25 -0400)
4
5
Merge tag 'pull-ppc-20221221' of https://gitlab.com/danielhb/qemu into staging (2022-12-21 18:08:09 +0000)
6
4
7
are available in the Git repository at:
5
are available in the Git repository at:
8
6
9
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20221222-1
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20230911
10
8
11
for you to fetch changes up to 71a9bc59728a054036f3db7dd82dab8f8bd2baf9:
9
for you to fetch changes up to e7a03409f29e2da59297d55afbaec98c96e43e3a:
12
10
13
hw/intc: sifive_plic: Fix the pending register range check (2022-12-22 08:36:30 +1000)
11
target/riscv: don't read CSR in riscv_csrrw_do64 (2023-09-11 11:45:55 +1000)
14
12
15
----------------------------------------------------------------
13
----------------------------------------------------------------
16
First RISC-V PR for QEMU 8.0
14
First RISC-V PR for 8.2
17
15
18
* Fix PMP propagation for tlb
16
* Remove 'host' CPU from TCG
19
* Collection of bug fixes
17
* riscv_htif Fixup printing on big endian hosts
20
* Add the `FIELDx_1CLEAR()` macro
18
* Add zmmul isa string
21
* Bump the OpenTitan supported version
19
* Add smepmp isa string
22
* Add smstateen support
20
* Fix page_check_range use in fault-only-first
23
* Support native debug icount trigger
21
* Use existing lookup tables for MixColumns
24
* Remove the redundant ipi-id property in the virt machine
22
* Add RISC-V vector cryptographic instruction set support
25
* Support cache-related PMU events in virtual mode
23
* Implement WARL behaviour for mcountinhibit/mcounteren
26
* Add some missing PolarFire SoC io regions
24
* Add Zihintntl extension ISA string to DTS
27
* Fix mret exception cause when no pmp rule is configured
25
* Fix zfa fleq.d and fltq.d
28
* Fix bug where disabling compressed instructions would crash QEMU
26
* Fix upper/lower mtime write calculation
29
* Add Zawrs ISA extension support
27
* Make rtc variable names consistent
30
* A range of code refactoring and cleanups
28
* Use abi type for linux-user target_ucontext
29
* Add RISC-V KVM AIA Support
30
* Fix riscv,pmu DT node path in the virt machine
31
* Update CSR bits name for svadu extension
32
* Mark zicond non-experimental
33
* Fix satp_mode_finalize() when satp_mode.supported = 0
34
* Fix non-KVM --enable-debug build
35
* Add new extensions to hwprobe
36
* Use accelerated helper for AES64KS1I
37
* Allocate itrigger timers only once
38
* Respect mseccfg.RLB for pmpaddrX changes
39
* Align the AIA model to v1.0 ratified spec
40
* Don't read the CSR in riscv_csrrw_do64
31
41
32
----------------------------------------------------------------
42
----------------------------------------------------------------
33
Anup Patel (1):
43
Akihiko Odaki (1):
34
target/riscv: Typo fix in sstc() predicate
44
target/riscv: Allocate itrigger timers only once
35
45
36
Atish Patra (1):
46
Ard Biesheuvel (2):
37
hw/riscv: virt: Remove the redundant ipi-id property
47
target/riscv: Use existing lookup tables for MixColumns
48
target/riscv: Use accelerated helper for AES64KS1I
38
49
39
Bin Meng (20):
50
Conor Dooley (1):
40
target/riscv: Add some comments for sstatus CSR in riscv_cpu_dump_state()
51
hw/riscv: virt: Fix riscv,pmu DT node path
41
target/riscv: Fix mret exception cause when no pmp rule is configured
42
target/riscv: Simplify helper_sret() a little bit
43
target/riscv: Clear mstatus.MPRV when leaving M-mode for priv spec 1.12+
44
hw/riscv: Select MSI_NONBROKEN in SIFIVE_PLIC
45
hw/intc: Select MSI_NONBROKEN in RISC-V AIA interrupt controllers
46
hw/riscv: Fix opentitan dependency to SIFIVE_PLIC
47
hw/riscv: Sort machines Kconfig options in alphabetical order
48
hw/riscv: spike: Remove misleading comments
49
hw/intc: sifive_plic: Drop PLICMode_H
50
hw/intc: sifive_plic: Improve robustness of the PLIC config parser
51
hw/intc: sifive_plic: Use error_setg() to propagate the error up via errp in sifive_plic_realize()
52
hw/intc: sifive_plic: Update "num-sources" property default value
53
hw/riscv: microchip_pfsoc: Fix the number of interrupt sources of PLIC
54
hw/riscv: sifive_e: Fix the number of interrupt sources of PLIC
55
hw/riscv: sifive_u: Avoid using magic number for "riscv, ndev"
56
hw/riscv: virt: Fix the value of "riscv, ndev" in the dtb
57
hw/intc: sifive_plic: Change "priority-base" to start from interrupt source 0
58
hw/riscv: opentitan: Drop "hartid-base" and "priority-base" initialization
59
hw/intc: sifive_plic: Fix the pending register range check
60
52
61
Christoph Muellner (1):
53
Daniel Henrique Barboza (6):
62
RISC-V: Add Zawrs ISA extension support
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
63
60
64
Conor Dooley (3):
61
Dickon Hood (2):
65
hw/misc: pfsoc: add fabric clocks to ioscb
62
target/riscv: Refactor translation of vector-widening instruction
66
hw/riscv: pfsoc: add missing FICs as unimplemented
63
target/riscv: Add Zvbb ISA extension support
67
hw/{misc, riscv}: pfsoc: add system controller as unimplemented
68
64
69
Frédéric Pétrot (1):
65
Jason Chien (3):
70
hw/intc: sifive_plic: Renumber the S irqs for numa support
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
71
69
72
Jim Shu (2):
70
Kiran Ostrolenk (4):
73
target/riscv: support cache-related PMU events in virtual mode
71
target/riscv: Refactor some of the generic vector functionality
74
hw/intc: sifive_plic: fix out-of-bound access of source_priority array
72
target/riscv: Refactor vector-vector translation macro
73
target/riscv: Refactor some of the generic vector functionality
74
target/riscv: Add Zvknh ISA extension support
75
75
76
LIU Zhiwei (5):
76
LIU Zhiwei (3):
77
target/riscv: Fix PMP propagation for tlb
77
target/riscv: Fix page_check_range use in fault-only-first
78
target/riscv: Add itrigger support when icount is not enabled
78
target/riscv: Fix zfa fleq.d and fltq.d
79
target/riscv: Add itrigger support when icount is enabled
79
linux-user/riscv: Use abi type for target_ucontext
80
target/riscv: Enable native debug itrigger
81
target/riscv: Add itrigger_enabled field to CPURISCVState
82
80
83
Mayuresh Chitale (3):
81
Lawrence Hunter (2):
84
target/riscv: Add smstateen support
82
target/riscv: Add Zvbc ISA extension support
85
target/riscv: smstateen check for h/s/envcfg
83
target/riscv: Add Zvksh ISA extension support
86
target/riscv: generate virtual instruction exception
87
84
88
Richard Henderson (4):
85
Leon Schuermann (1):
89
tcg/riscv: Fix range matched by TCG_CT_CONST_M12
86
target/riscv/pmp.c: respect mseccfg.RLB for pmpaddrX changes
90
tcg/riscv: Fix reg overlap case in tcg_out_addsub2
91
tcg/riscv: Fix base register for user-only qemu_ld/st
92
target/riscv: Set pc_succ_insn for !rvc illegal insn
93
87
94
Wilfred Mallawa (4):
88
Max Chou (3):
95
hw/registerfields: add `FIELDx_1CLEAR()` macro
89
crypto: Create sm4_subword
96
hw/ssi/ibex_spi: implement `FIELD32_1CLEAR` macro
90
crypto: Add SM4 constant parameter CK
97
hw/riscv/opentitan: bump opentitan
91
target/riscv: Add Zvksed ISA extension support
98
hw/riscv/opentitan: add aon_timer base unimpl
99
92
100
include/hw/intc/sifive_plic.h | 1 -
93
Nazar Kazakov (4):
101
include/hw/misc/mchp_pfsoc_ioscb.h | 4 +
94
target/riscv: Remove redundant "cpu_vl == 0" checks
102
include/hw/misc/mchp_pfsoc_sysreg.h | 1 +
95
target/riscv: Move vector translation checks
103
include/hw/registerfields.h | 22 ++
96
target/riscv: Add Zvkned ISA extension support
104
include/hw/riscv/microchip_pfsoc.h | 7 +-
97
target/riscv: Add Zvkg ISA extension support
105
include/hw/riscv/opentitan.h | 10 +-
98
106
include/hw/riscv/shakti_c.h | 2 +-
99
Nikita Shubin (1):
107
include/hw/riscv/sifive_e.h | 9 +-
100
target/riscv: don't read CSR in riscv_csrrw_do64
108
include/hw/riscv/sifive_u.h | 2 +-
101
109
include/hw/riscv/virt.h | 8 +-
102
Rob Bradford (1):
110
target/riscv/cpu.h | 10 +
103
target/riscv: Implement WARL behaviour for mcountinhibit/mcounteren
111
target/riscv/cpu_bits.h | 37 +++
104
112
target/riscv/debug.h | 13 +
105
Robbin Ehn (1):
113
target/riscv/helper.h | 2 +
106
linux-user/riscv: Add new extensions to hwprobe
114
target/riscv/pmp.h | 6 +-
107
115
target/riscv/insn32.decode | 4 +
108
Thomas Huth (2):
116
hw/intc/sifive_plic.c | 66 +++--
109
hw/char/riscv_htif: Fix printing of console characters on big endian hosts
117
hw/misc/mchp_pfsoc_ioscb.c | 78 ++++-
110
hw/char/riscv_htif: Fix the console syscall on big endian hosts
118
hw/misc/mchp_pfsoc_sysreg.c | 18 +-
111
119
hw/riscv/microchip_pfsoc.c | 121 ++++----
112
Tommy Wu (1):
120
hw/riscv/opentitan.c | 26 +-
113
target/riscv: Align the AIA model to v1.0 ratified spec
121
hw/riscv/sifive_u.c | 3 +-
114
122
hw/riscv/spike.c | 1 -
115
Vineet Gupta (1):
123
hw/riscv/virt.c | 7 +-
116
riscv: zicond: make non-experimental
124
hw/ssi/ibex_spi_host.c | 21 +-
117
125
target/riscv/cpu.c | 11 +
118
Weiwei Li (1):
126
target/riscv/cpu_helper.c | 26 +-
119
target/riscv: Update CSR bits name for svadu extension
127
target/riscv/csr.c | 393 ++++++++++++++++++++++++-
120
128
target/riscv/debug.c | 205 +++++++++++++
121
Yong-Xuan Wang (5):
129
target/riscv/machine.c | 36 +++
122
target/riscv: support the AIA device emulation with KVM enabled
130
target/riscv/op_helper.c | 28 +-
123
target/riscv: check the in-kernel irqchip support
131
target/riscv/pmp.c | 90 ++----
124
target/riscv: Create an KVM AIA irqchip
132
target/riscv/translate.c | 54 +++-
125
target/riscv: update APLIC and IMSIC to support KVM AIA
133
target/riscv/insn_trans/trans_privileged.c.inc | 4 +-
126
target/riscv: select KVM AIA in riscv virt machine
134
target/riscv/insn_trans/trans_rvi.c.inc | 8 +-
127
135
target/riscv/insn_trans/trans_rvv.c.inc | 4 +-
128
include/crypto/aes.h | 7 +
136
target/riscv/insn_trans/trans_rvzawrs.c.inc | 51 ++++
129
include/crypto/sm4.h | 9 +
137
tcg/riscv/tcg-target.c.inc | 68 +++--
130
target/riscv/cpu_bits.h | 8 +-
138
hw/intc/Kconfig | 3 +
131
target/riscv/cpu_cfg.h | 9 +
139
hw/riscv/Kconfig | 22 +-
132
target/riscv/debug.h | 3 +-
140
tests/tcg/Makefile.target | 2 +
133
target/riscv/helper.h | 98 +++
141
tests/tcg/riscv64/Makefile.target | 6 +
134
target/riscv/kvm_riscv.h | 5 +
142
tests/tcg/riscv64/test-noc.S | 32 ++
135
target/riscv/vector_internals.h | 228 +++++++
143
43 files changed, 1256 insertions(+), 266 deletions(-)
136
target/riscv/insn32.decode | 58 ++
144
create mode 100644 target/riscv/insn_trans/trans_rvzawrs.c.inc
137
crypto/aes.c | 4 +-
145
create mode 100644 tests/tcg/riscv64/test-noc.S
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: Bin Meng <bmeng@tinylab.org>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
SHAKTI_C machine Kconfig option was inserted in disorder. Fix it.
3
The 'host' CPU is available in a CONFIG_KVM build and it's currently
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:
4
6
5
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
$ ./build/qemu-system-riscv64 -M virt,accel=tcg -cpu host --nographic
8
qemu-system-riscv64: H extension requires priv spec 1.12.0
9
10
This CPU does not have a priv spec because we don't filter its extensions
11
via priv spec. We shouldn't be reaching riscv_cpu_realize_tcg() at all
12
with the 'host' CPU.
13
14
We don't have a way to filter the 'host' CPU out of the available CPU
15
options (-cpu help) if the build includes both KVM and TCG. What we can
16
do is to error out during riscv_cpu_realize_tcg() if the user chooses
17
the 'host' CPU with accel=tcg:
18
19
$ ./build/qemu-system-riscv64 -M virt,accel=tcg -cpu host --nographic
20
qemu-system-riscv64: 'host' CPU is not compatible with TCG acceleration
21
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
24
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
25
Message-Id: <20230721133411.474105-1-dbarboza@ventanamicro.com>
9
Message-Id: <20221211030829.802437-4-bmeng@tinylab.org>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
26
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
27
---
12
hw/riscv/Kconfig | 16 +++++++++-------
28
target/riscv/cpu.c | 5 +++++
13
1 file changed, 9 insertions(+), 7 deletions(-)
29
1 file changed, 5 insertions(+)
14
30
15
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
31
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
16
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/Kconfig
33
--- a/target/riscv/cpu.c
18
+++ b/hw/riscv/Kconfig
34
+++ b/target/riscv/cpu.c
19
@@ -XXX,XX +XXX,XX @@ config RISCV_NUMA
35
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize_tcg(DeviceState *dev, Error **errp)
20
config IBEX
36
CPURISCVState *env = &cpu->env;
21
bool
37
Error *local_err = NULL;
22
38
23
+# RISC-V machines in alphabetical order
39
+ if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_CPU_HOST)) {
40
+ error_setg(errp, "'host' CPU is not compatible with TCG acceleration");
41
+ return;
42
+ }
24
+
43
+
25
config MICROCHIP_PFSOC
44
riscv_cpu_validate_misa_mxl(cpu, &local_err);
26
bool
45
if (local_err != NULL) {
27
select CADENCE_SDHCI
46
error_propagate(errp, local_err);
28
@@ -XXX,XX +XXX,XX @@ config OPENTITAN
29
select SIFIVE_PLIC
30
select UNIMP
31
32
-config SHAKTI_C
33
- bool
34
- select UNIMP
35
- select SHAKTI_UART
36
- select RISCV_ACLINT
37
- select SIFIVE_PLIC
38
-
39
config RISCV_VIRT
40
bool
41
imply PCI_DEVICES
42
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
43
select FW_CFG_DMA
44
select PLATFORM_BUS
45
46
+config SHAKTI_C
47
+ bool
48
+ select RISCV_ACLINT
49
+ select SHAKTI_UART
50
+ select SIFIVE_PLIC
51
+ select UNIMP
52
+
53
config SIFIVE_E
54
bool
55
select RISCV_ACLINT
56
--
47
--
57
2.38.1
48
2.41.0
49
50
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
At present magic number is used to create "riscv,ndev" property
3
The character that should be printed is stored in the 64 bit "payload"
4
in the dtb. Let's use the macro SIFIVE_U_PLIC_NUM_SOURCES that
4
variable. The code currently tries to print it by taking the address
5
is used to instantiate the PLIC model instead.
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.
6
9
7
Signed-off-by: Bin Meng <bmeng@tinylab.org>
10
Fixes: 5033606780 ("RISC-V HTIF Console")
8
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
11
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20221211030829.802437-12-bmeng@tinylab.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>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
18
---
13
hw/riscv/sifive_u.c | 3 ++-
19
hw/char/riscv_htif.c | 3 ++-
14
1 file changed, 2 insertions(+), 1 deletion(-)
20
1 file changed, 2 insertions(+), 1 deletion(-)
15
21
16
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
22
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
17
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/sifive_u.c
24
--- a/hw/char/riscv_htif.c
19
+++ b/hw/riscv/sifive_u.c
25
+++ b/hw/char/riscv_htif.c
20
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
26
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
21
qemu_fdt_setprop_cells(fdt, nodename, "reg",
27
s->tohost = 0; /* clear to indicate we read */
22
0x0, memmap[SIFIVE_U_DEV_PLIC].base,
28
return;
23
0x0, memmap[SIFIVE_U_DEV_PLIC].size);
29
} else if (cmd == HTIF_CONSOLE_CMD_PUTC) {
24
- qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
30
- qemu_chr_fe_write(&s->chr, (uint8_t *)&payload, 1);
25
+ qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev",
31
+ uint8_t ch = (uint8_t)payload;
26
+ SIFIVE_U_PLIC_NUM_SOURCES - 1);
32
+ qemu_chr_fe_write(&s->chr, &ch, 1);
27
qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
33
resp = 0x100 | (uint8_t)payload;
28
plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
34
} else {
29
g_free(cells);
35
qemu_log("HTIF device %d: unknown command\n", device);
30
--
36
--
31
2.38.1
37
2.41.0
38
39
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
"hartid-base" and "priority-base" are zero by default. There is no
3
Values that have been read via cpu_physical_memory_read() from the
4
need to initialize them to zero again.
4
guest's memory have to be swapped in case the host endianess differs
5
from the guest.
5
6
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Fixes: a6e13e31d5 ("riscv_htif: Support console output via proxy syscall")
7
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <20221211030829.802437-15-bmeng@tinylab.org>
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>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
14
---
12
hw/riscv/opentitan.c | 2 --
15
hw/char/riscv_htif.c | 9 +++++----
13
1 file changed, 2 deletions(-)
16
1 file changed, 5 insertions(+), 4 deletions(-)
14
17
15
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
18
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/opentitan.c
20
--- a/hw/char/riscv_htif.c
18
+++ b/hw/riscv/opentitan.c
21
+++ b/hw/char/riscv_htif.c
19
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
22
@@ -XXX,XX +XXX,XX @@
20
23
#include "qemu/timer.h"
21
/* PLIC */
24
#include "qemu/error-report.h"
22
qdev_prop_set_string(DEVICE(&s->plic), "hart-config", "M");
25
#include "exec/address-spaces.h"
23
- qdev_prop_set_uint32(DEVICE(&s->plic), "hartid-base", 0);
26
+#include "exec/tswap.h"
24
qdev_prop_set_uint32(DEVICE(&s->plic), "num-sources", 180);
27
#include "sysemu/dma.h"
25
qdev_prop_set_uint32(DEVICE(&s->plic), "num-priorities", 3);
28
26
- qdev_prop_set_uint32(DEVICE(&s->plic), "priority-base", 0x00);
29
#define RISCV_DEBUG_HTIF 0
27
qdev_prop_set_uint32(DEVICE(&s->plic), "pending-base", 0x1000);
30
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
28
qdev_prop_set_uint32(DEVICE(&s->plic), "enable-base", 0x2000);
31
} else {
29
qdev_prop_set_uint32(DEVICE(&s->plic), "enable-stride", 32);
32
uint64_t syscall[8];
33
cpu_physical_memory_read(payload, syscall, sizeof(syscall));
34
- if (syscall[0] == PK_SYS_WRITE &&
35
- syscall[1] == HTIF_DEV_CONSOLE &&
36
- syscall[3] == HTIF_CONSOLE_CMD_PUTC) {
37
+ if (tswap64(syscall[0]) == PK_SYS_WRITE &&
38
+ tswap64(syscall[1]) == HTIF_DEV_CONSOLE &&
39
+ tswap64(syscall[3]) == HTIF_CONSOLE_CMD_PUTC) {
40
uint8_t ch;
41
- cpu_physical_memory_read(syscall[2], &ch, 1);
42
+ cpu_physical_memory_read(tswap64(syscall[2]), &ch, 1);
43
qemu_chr_fe_write(&s->chr, &ch, 1);
44
resp = 0x100 | (uint8_t)payload;
45
} else {
30
--
46
--
31
2.38.1
47
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Since commit ef6310064820 ("hw/riscv: opentitan: Update to the latest build")
3
zmmul was promoted from experimental to ratified in commit 6d00ffad4e95.
4
the IBEX PLIC model was replaced with the SiFive PLIC model in the
4
Add a riscv,isa string for it.
5
'opentitan' machine but we forgot the add the dependency there.
6
5
7
Signed-off-by: Bin Meng <bmeng@tinylab.org>
6
Fixes: 6d00ffad4e95 ("target/riscv: move zmmul out of the experimental properties")
8
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
7
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20221211030829.802437-3-bmeng@tinylab.org>
10
Message-Id: <20230720132424.371132-2-dbarboza@ventanamicro.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
12
---
13
hw/riscv/Kconfig | 1 +
13
target/riscv/cpu.c | 1 +
14
1 file changed, 1 insertion(+)
14
1 file changed, 1 insertion(+)
15
15
16
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
16
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/Kconfig
18
--- a/target/riscv/cpu.c
19
+++ b/hw/riscv/Kconfig
19
+++ b/target/riscv/cpu.c
20
@@ -XXX,XX +XXX,XX @@ config MICROCHIP_PFSOC
20
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
21
config OPENTITAN
21
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
22
bool
22
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
23
select IBEX
23
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
24
+ select SIFIVE_PLIC
24
+ ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
25
select UNIMP
25
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
26
26
ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
27
config SHAKTI_C
27
ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
28
--
28
--
29
2.38.1
29
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
sstatus register dump is currently missing in riscv_cpu_dump_state().
3
The cpu->cfg.epmp extension is still experimental, but it already has a
4
As sstatus is a copy of mstatus, which is described in the priv spec,
4
'smepmp' riscv,isa string. Add it.
5
it seems redundant to print the same information twice.
6
5
7
Add some comments for this to let people know this is intentional.
6
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
7
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
Signed-off-by: Bin Meng <bmeng@tinylab.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20221125050354.3166023-1-bmeng@tinylab.org>
9
Message-Id: <20230720132424.371132-3-dbarboza@ventanamicro.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
11
---
14
target/riscv/cpu.c | 4 ++++
12
target/riscv/cpu.c | 1 +
15
1 file changed, 4 insertions(+)
13
1 file changed, 1 insertion(+)
16
14
17
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
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu.c
17
--- a/target/riscv/cpu.c
20
+++ b/target/riscv/cpu.c
18
+++ b/target/riscv/cpu.c
21
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
19
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
22
CSR_MHARTID,
20
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
23
CSR_MSTATUS,
21
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
24
CSR_MSTATUSH,
22
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
25
+ /*
23
+ ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, epmp),
26
+ * CSR_SSTATUS is intentionally omitted here as its value
24
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
27
+ * can be figured out by looking at CSR_MSTATUS
25
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
28
+ */
26
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
29
CSR_HSTATUS,
30
CSR_VSSTATUS,
31
CSR_MIP,
32
--
27
--
33
2.38.1
28
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
Avoid calling riscv_itrigger_enabled() when calculate the tbflags.
3
Commit bef6f008b98(accel/tcg: Return bool from page_check_range) converts
4
As the itrigger enable status can only be changed when write
4
integer return value to bool type. However, it wrongly converted the use
5
tdata1, migration load or itrigger fire, update env->itrigger_enabled
5
of the API in riscv fault-only-first, where page_check_range < = 0, should
6
at these places.
6
be converted to !page_check_range.
7
7
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-Id: <20221013062946.7530-5-zhiwei_liu@linux.alibaba.com>
10
Message-ID: <20230729031618.821-1-zhiwei_liu@linux.alibaba.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
12
---
13
target/riscv/cpu.h | 1 +
13
target/riscv/vector_helper.c | 2 +-
14
target/riscv/cpu_helper.c | 3 +--
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
target/riscv/debug.c | 3 +++
16
target/riscv/machine.c | 15 +++++++++++++++
17
4 files changed, 20 insertions(+), 2 deletions(-)
18
15
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
16
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.h
18
--- a/target/riscv/vector_helper.c
22
+++ b/target/riscv/cpu.h
19
+++ b/target/riscv/vector_helper.c
23
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
20
@@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base,
24
struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
21
cpu_mmu_index(env, false));
25
QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
22
if (host) {
26
int64_t last_icount;
23
#ifdef CONFIG_USER_ONLY
27
+ bool itrigger_enabled;
24
- if (page_check_range(addr, offset, PAGE_READ)) {
28
25
+ if (!page_check_range(addr, offset, PAGE_READ)) {
29
/* machine specific rdtime callback */
26
vl = i;
30
uint64_t (*rdtime_fn)(void *);
27
goto ProbeSuccess;
31
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
28
}
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/cpu_helper.c
34
+++ b/target/riscv/cpu_helper.c
35
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
36
get_field(env->mstatus_hs, MSTATUS_VS));
37
}
38
if (riscv_feature(env, RISCV_FEATURE_DEBUG) && !icount_enabled()) {
39
- flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER,
40
- riscv_itrigger_enabled(env));
41
+ flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
42
}
43
#endif
44
45
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/riscv/debug.c
48
+++ b/target/riscv/debug.c
49
@@ -XXX,XX +XXX,XX @@ void helper_itrigger_match(CPURISCVState *env)
50
}
51
itrigger_set_count(env, i, count--);
52
if (!count) {
53
+ env->itrigger_enabled = riscv_itrigger_enabled(env);
54
do_trigger_action(env, i);
55
}
56
}
57
@@ -XXX,XX +XXX,XX @@ static void itrigger_reg_write(CPURISCVState *env, target_ulong index,
58
/* set the count to timer */
59
timer_mod(env->itrigger_timer[index],
60
env->last_icount + itrigger_get_count(env, index));
61
+ } else {
62
+ env->itrigger_enabled = riscv_itrigger_enabled(env);
63
}
64
}
65
break;
66
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/machine.c
69
+++ b/target/riscv/machine.c
70
@@ -XXX,XX +XXX,XX @@
71
#include "qemu/error-report.h"
72
#include "sysemu/kvm.h"
73
#include "migration/cpu.h"
74
+#include "sysemu/cpu-timers.h"
75
+#include "debug.h"
76
77
static bool pmp_needed(void *opaque)
78
{
79
@@ -XXX,XX +XXX,XX @@ static bool debug_needed(void *opaque)
80
return riscv_feature(env, RISCV_FEATURE_DEBUG);
81
}
82
83
+static int debug_post_load(void *opaque, int version_id)
84
+{
85
+ RISCVCPU *cpu = opaque;
86
+ CPURISCVState *env = &cpu->env;
87
+
88
+ if (icount_enabled()) {
89
+ env->itrigger_enabled = riscv_itrigger_enabled(env);
90
+ }
91
+
92
+ return 0;
93
+}
94
+
95
static const VMStateDescription vmstate_debug = {
96
.name = "cpu/debug",
97
.version_id = 2,
98
.minimum_version_id = 2,
99
.needed = debug_needed,
100
+ .post_load = debug_post_load,
101
.fields = (VMStateField[]) {
102
VMSTATE_UINTTL(env.trigger_cur, RISCVCPU),
103
VMSTATE_UINTTL_ARRAY(env.tdata1, RISCVCPU, RV_MAX_TRIGGERS),
104
--
29
--
105
2.38.1
30
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Ard Biesheuvel <ardb@kernel.org>
2
2
3
At present the SiFive PLIC model "priority-base" expects interrupt
3
The AES MixColumns and InvMixColumns operations are relatively
4
priority register base starting from source 1 instead source 0,
4
expensive 4x4 matrix multiplications in GF(2^8), which is why C
5
that's why on most platforms "priority-base" is set to 0x04 except
5
implementations usually rely on precomputed lookup tables rather than
6
'opentitan' machine. 'opentitan' should have set "priority-base"
6
performing the calculations on demand.
7
to 0x04 too.
8
7
9
Note the irq number calculation in sifive_plic_{read,write} is
8
Given that we already carry those tables in QEMU, we can just grab the
10
correct as the codes make up for the irq number by adding 1.
9
right value in the implementation of the RISC-V AES32 instructions. Note
10
that the tables in question are permuted according to the respective
11
Sbox, so we can omit the Sbox lookup as well in this case.
11
12
12
Let's simply update "priority-base" to start from interrupt source
13
Cc: Richard Henderson <richard.henderson@linaro.org>
13
0 and add a comment to make it crystal clear.
14
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
14
15
Cc: Zewen Ye <lustrew@foxmail.com>
15
Signed-off-by: Bin Meng <bmeng@tinylab.org>
16
Cc: Weiwei Li <liweiwei@iscas.ac.cn>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Cc: Junqiang Wang <wangjunqiang@iscas.ac.cn>
17
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
18
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
18
Message-Id: <20221211030829.802437-14-bmeng@tinylab.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-ID: <20230731084043.1791984-1-ardb@kernel.org>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
22
---
21
include/hw/riscv/microchip_pfsoc.h | 2 +-
23
include/crypto/aes.h | 7 +++++++
22
include/hw/riscv/shakti_c.h | 2 +-
24
crypto/aes.c | 4 ++--
23
include/hw/riscv/sifive_e.h | 2 +-
25
target/riscv/crypto_helper.c | 34 ++++------------------------------
24
include/hw/riscv/sifive_u.h | 2 +-
26
3 files changed, 13 insertions(+), 32 deletions(-)
25
include/hw/riscv/virt.h | 2 +-
26
hw/intc/sifive_plic.c | 5 +++--
27
6 files changed, 8 insertions(+), 7 deletions(-)
28
27
29
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
28
diff --git a/include/crypto/aes.h b/include/crypto/aes.h
30
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/riscv/microchip_pfsoc.h
30
--- a/include/crypto/aes.h
32
+++ b/include/hw/riscv/microchip_pfsoc.h
31
+++ b/include/crypto/aes.h
33
@@ -XXX,XX +XXX,XX @@ enum {
32
@@ -XXX,XX +XXX,XX @@ void AES_decrypt(const unsigned char *in, unsigned char *out,
34
33
extern const uint8_t AES_sbox[256];
35
#define MICROCHIP_PFSOC_PLIC_NUM_SOURCES 187
34
extern const uint8_t AES_isbox[256];
36
#define MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES 7
35
37
-#define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE 0x04
36
+/*
38
+#define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE 0x00
37
+AES_Te0[x] = S [x].[02, 01, 01, 03];
39
#define MICROCHIP_PFSOC_PLIC_PENDING_BASE 0x1000
38
+AES_Td0[x] = Si[x].[0e, 09, 0d, 0b];
40
#define MICROCHIP_PFSOC_PLIC_ENABLE_BASE 0x2000
39
+*/
41
#define MICROCHIP_PFSOC_PLIC_ENABLE_STRIDE 0x80
40
+
42
diff --git a/include/hw/riscv/shakti_c.h b/include/hw/riscv/shakti_c.h
41
+extern const uint32_t AES_Te0[256], AES_Td0[256];
42
+
43
#endif
44
diff --git a/crypto/aes.c b/crypto/aes.c
43
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
44
--- a/include/hw/riscv/shakti_c.h
46
--- a/crypto/aes.c
45
+++ b/include/hw/riscv/shakti_c.h
47
+++ b/crypto/aes.c
46
@@ -XXX,XX +XXX,XX @@ enum {
48
@@ -XXX,XX +XXX,XX @@ AES_Td3[x] = Si[x].[09, 0d, 0b, 0e];
47
#define SHAKTI_C_PLIC_NUM_SOURCES 28
49
AES_Td4[x] = Si[x].[01, 01, 01, 01];
48
/* Excluding Priority 0 */
50
*/
49
#define SHAKTI_C_PLIC_NUM_PRIORITIES 2
51
50
-#define SHAKTI_C_PLIC_PRIORITY_BASE 0x04
52
-static const uint32_t AES_Te0[256] = {
51
+#define SHAKTI_C_PLIC_PRIORITY_BASE 0x00
53
+const uint32_t AES_Te0[256] = {
52
#define SHAKTI_C_PLIC_PENDING_BASE 0x1000
54
0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
53
#define SHAKTI_C_PLIC_ENABLE_BASE 0x2000
55
0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
54
#define SHAKTI_C_PLIC_ENABLE_STRIDE 0x80
56
0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
55
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
57
@@ -XXX,XX +XXX,XX @@ static const uint32_t AES_Te4[256] = {
58
0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
59
};
60
61
-static const uint32_t AES_Td0[256] = {
62
+const uint32_t AES_Td0[256] = {
63
0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
64
0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
65
0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
66
diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c
56
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
57
--- a/include/hw/riscv/sifive_e.h
68
--- a/target/riscv/crypto_helper.c
58
+++ b/include/hw/riscv/sifive_e.h
69
+++ b/target/riscv/crypto_helper.c
59
@@ -XXX,XX +XXX,XX @@ enum {
70
@@ -XXX,XX +XXX,XX @@
60
*/
71
#include "crypto/aes-round.h"
61
#define SIFIVE_E_PLIC_NUM_SOURCES 53
72
#include "crypto/sm4.h"
62
#define SIFIVE_E_PLIC_NUM_PRIORITIES 7
73
63
-#define SIFIVE_E_PLIC_PRIORITY_BASE 0x04
74
-#define AES_XTIME(a) \
64
+#define SIFIVE_E_PLIC_PRIORITY_BASE 0x00
75
- ((a << 1) ^ ((a & 0x80) ? 0x1b : 0))
65
#define SIFIVE_E_PLIC_PENDING_BASE 0x1000
76
-
66
#define SIFIVE_E_PLIC_ENABLE_BASE 0x2000
77
-#define AES_GFMUL(a, b) (( \
67
#define SIFIVE_E_PLIC_ENABLE_STRIDE 0x80
78
- (((b) & 0x1) ? (a) : 0) ^ \
68
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
79
- (((b) & 0x2) ? AES_XTIME(a) : 0) ^ \
69
index XXXXXXX..XXXXXXX 100644
80
- (((b) & 0x4) ? AES_XTIME(AES_XTIME(a)) : 0) ^ \
70
--- a/include/hw/riscv/sifive_u.h
81
- (((b) & 0x8) ? AES_XTIME(AES_XTIME(AES_XTIME(a))) : 0)) & 0xFF)
71
+++ b/include/hw/riscv/sifive_u.h
82
-
72
@@ -XXX,XX +XXX,XX @@ enum {
83
-static inline uint32_t aes_mixcolumn_byte(uint8_t x, bool fwd)
73
84
-{
74
#define SIFIVE_U_PLIC_NUM_SOURCES 54
85
- uint32_t u;
75
#define SIFIVE_U_PLIC_NUM_PRIORITIES 7
86
-
76
-#define SIFIVE_U_PLIC_PRIORITY_BASE 0x04
87
- if (fwd) {
77
+#define SIFIVE_U_PLIC_PRIORITY_BASE 0x00
88
- u = (AES_GFMUL(x, 3) << 24) | (x << 16) | (x << 8) |
78
#define SIFIVE_U_PLIC_PENDING_BASE 0x1000
89
- (AES_GFMUL(x, 2) << 0);
79
#define SIFIVE_U_PLIC_ENABLE_BASE 0x2000
90
- } else {
80
#define SIFIVE_U_PLIC_ENABLE_STRIDE 0x80
91
- u = (AES_GFMUL(x, 0xb) << 24) | (AES_GFMUL(x, 0xd) << 16) |
81
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
92
- (AES_GFMUL(x, 0x9) << 8) | (AES_GFMUL(x, 0xe) << 0);
82
index XXXXXXX..XXXXXXX 100644
93
- }
83
--- a/include/hw/riscv/virt.h
94
- return u;
84
+++ b/include/hw/riscv/virt.h
95
-}
85
@@ -XXX,XX +XXX,XX @@ enum {
96
-
86
#define VIRT_IRQCHIP_MAX_GUESTS_BITS 3
97
#define sext32_xlen(x) (target_ulong)(int32_t)(x)
87
#define VIRT_IRQCHIP_MAX_GUESTS ((1U << VIRT_IRQCHIP_MAX_GUESTS_BITS) - 1U)
98
88
99
static inline target_ulong aes32_operation(target_ulong shamt,
89
-#define VIRT_PLIC_PRIORITY_BASE 0x04
100
@@ -XXX,XX +XXX,XX @@ static inline target_ulong aes32_operation(target_ulong shamt,
90
+#define VIRT_PLIC_PRIORITY_BASE 0x00
101
bool enc, bool mix)
91
#define VIRT_PLIC_PENDING_BASE 0x1000
102
{
92
#define VIRT_PLIC_ENABLE_BASE 0x2000
103
uint8_t si = rs2 >> shamt;
93
#define VIRT_PLIC_ENABLE_STRIDE 0x80
104
- uint8_t so;
94
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
105
uint32_t mixed;
95
index XXXXXXX..XXXXXXX 100644
106
target_ulong res;
96
--- a/hw/intc/sifive_plic.c
107
97
+++ b/hw/intc/sifive_plic.c
108
if (enc) {
98
@@ -XXX,XX +XXX,XX @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size)
109
- so = AES_sbox[si];
99
SiFivePLICState *plic = opaque;
110
if (mix) {
100
111
- mixed = aes_mixcolumn_byte(so, true);
101
if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) {
112
+ mixed = be32_to_cpu(AES_Te0[si]);
102
- uint32_t irq = ((addr - plic->priority_base) >> 2) + 1;
113
} else {
103
+ uint32_t irq = (addr - plic->priority_base) >> 2;
114
- mixed = so;
104
115
+ mixed = AES_sbox[si];
105
return plic->source_priority[irq];
116
}
106
} else if (addr_between(addr, plic->pending_base, plic->num_sources >> 3)) {
117
} else {
107
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_write(void *opaque, hwaddr addr, uint64_t value,
118
- so = AES_isbox[si];
108
SiFivePLICState *plic = opaque;
119
if (mix) {
109
120
- mixed = aes_mixcolumn_byte(so, false);
110
if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) {
121
+ mixed = be32_to_cpu(AES_Td0[si]);
111
- uint32_t irq = ((addr - plic->priority_base) >> 2) + 1;
122
} else {
112
+ uint32_t irq = (addr - plic->priority_base) >> 2;
123
- mixed = so;
113
124
+ mixed = AES_isbox[si];
114
if (((plic->num_priorities + 1) & plic->num_priorities) == 0) {
125
}
115
/*
126
}
116
@@ -XXX,XX +XXX,XX @@ static Property sifive_plic_properties[] = {
127
mixed = rol32(mixed, shamt);
117
/* number of interrupt sources including interrupt source 0 */
118
DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 1),
119
DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
120
+ /* interrupt priority register base starting from source 0 */
121
DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
122
DEFINE_PROP_UINT32("pending-base", SiFivePLICState, pending_base, 0),
123
DEFINE_PROP_UINT32("enable-base", SiFivePLICState, enable_base, 0),
124
--
128
--
125
2.38.1
129
2.41.0
130
131
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
Failure to set pc_succ_insn may result in a TB covering zero bytes,
3
Take some functions/macros out of `vector_helper` and put them in a new
4
which triggers an assert within the code generator.
4
module called `vector_internals`. This ensures they can be used by both
5
vector and vector-crypto helpers (latter implemented in proceeding
6
commits).
5
7
6
Cc: qemu-stable@nongnu.org
8
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1224
9
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Max Chou <max.chou@sifive.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Acked-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-ID: <20230711165917.2629866-2-max.chou@sifive.com>
11
Message-Id: <20221203175744.151365-1-richard.henderson@linaro.org>
12
[ Changes by AF:
13
- Add missing run-plugin-test-noc-% line
14
]
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
14
---
17
target/riscv/translate.c | 12 ++++--------
15
target/riscv/vector_internals.h | 182 +++++++++++++++++++++++++++++
18
tests/tcg/Makefile.target | 2 ++
16
target/riscv/vector_helper.c | 201 +-------------------------------
19
tests/tcg/riscv64/Makefile.target | 6 ++++++
17
target/riscv/vector_internals.c | 81 +++++++++++++
20
tests/tcg/riscv64/test-noc.S | 32 +++++++++++++++++++++++++++++++
18
target/riscv/meson.build | 1 +
21
4 files changed, 44 insertions(+), 8 deletions(-)
19
4 files changed, 265 insertions(+), 200 deletions(-)
22
create mode 100644 tests/tcg/riscv64/test-noc.S
20
create mode 100644 target/riscv/vector_internals.h
21
create mode 100644 target/riscv/vector_internals.c
23
22
24
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
23
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/translate.c
27
+++ b/target/riscv/translate.c
28
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
29
ctx->virt_inst_excp = false;
30
/* Check for compressed insn */
31
if (insn_len(opcode) == 2) {
32
- if (!has_ext(ctx, RVC)) {
33
- gen_exception_illegal(ctx);
34
- } else {
35
- ctx->opcode = opcode;
36
- ctx->pc_succ_insn = ctx->base.pc_next + 2;
37
- if (decode_insn16(ctx, opcode)) {
38
- return;
39
- }
40
+ ctx->opcode = opcode;
41
+ ctx->pc_succ_insn = ctx->base.pc_next + 2;
42
+ if (has_ext(ctx, RVC) && decode_insn16(ctx, opcode)) {
43
+ return;
44
}
45
} else {
46
uint32_t opcode32 = opcode;
47
diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target
48
index XXXXXXX..XXXXXXX 100644
49
--- a/tests/tcg/Makefile.target
50
+++ b/tests/tcg/Makefile.target
51
@@ -XXX,XX +XXX,XX @@ endif
52
53
%: %.c
54
    $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
55
+%: %.S
56
+    $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
57
else
58
# For softmmu targets we include a different Makefile fragement as the
59
# build options for bare programs are usually pretty different. They
60
diff --git a/tests/tcg/riscv64/Makefile.target b/tests/tcg/riscv64/Makefile.target
61
index XXXXXXX..XXXXXXX 100644
62
--- a/tests/tcg/riscv64/Makefile.target
63
+++ b/tests/tcg/riscv64/Makefile.target
64
@@ -XXX,XX +XXX,XX @@
65
VPATH += $(SRC_PATH)/tests/tcg/riscv64
66
TESTS += test-div
67
TESTS += noexec
68
+
69
+# Disable compressed instructions for test-noc
70
+TESTS += test-noc
71
+test-noc: LDFLAGS = -nostdlib -static
72
+run-test-noc: QEMU_OPTS += -cpu rv64,c=false
73
+run-plugin-test-noc-%: QEMU_OPTS += -cpu rv64,c=false
74
diff --git a/tests/tcg/riscv64/test-noc.S b/tests/tcg/riscv64/test-noc.S
75
new file mode 100644
24
new file mode 100644
76
index XXXXXXX..XXXXXXX
25
index XXXXXXX..XXXXXXX
77
--- /dev/null
26
--- /dev/null
78
+++ b/tests/tcg/riscv64/test-noc.S
27
+++ b/target/riscv/vector_internals.h
79
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
80
+#include <asm/unistd.h>
29
+/*
81
+
30
+ * RISC-V Vector Extension Internals
82
+    .text
31
+ *
83
+    .globl _start
32
+ * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
84
+_start:
33
+ *
85
+    .option    norvc
34
+ * This program is free software; you can redistribute it and/or modify it
86
+    li    a0, 4        /* SIGILL */
35
+ * under the terms and conditions of the GNU General Public License,
87
+    la    a1, sa
36
+ * version 2 or later, as published by the Free Software Foundation.
88
+    li    a2, 0
37
+ *
89
+    li    a3, 8
38
+ * This program is distributed in the hope it will be useful, but WITHOUT
90
+    li    a7, __NR_rt_sigaction
39
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
91
+    scall
40
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
92
+
41
+ * more details.
93
+    .option    rvc
42
+ *
94
+    li    a0, 1
43
+ * You should have received a copy of the GNU General Public License along with
95
+    j    exit
44
+ * this program. If not, see <http://www.gnu.org/licenses/>.
96
+    .option    norvc
45
+ */
97
+
46
+
98
+pass:
47
+#ifndef TARGET_RISCV_VECTOR_INTERNALS_H
99
+    li    a0, 0
48
+#define TARGET_RISCV_VECTOR_INTERNALS_H
100
+exit:
49
+
101
+    li    a7, __NR_exit
50
+#include "qemu/osdep.h"
102
+    scall
51
+#include "qemu/bitops.h"
103
+
52
+#include "cpu.h"
104
+    .data
53
+#include "tcg/tcg-gvec-desc.h"
105
+    /* struct kernel_sigaction sa = { .sa_handler = pass }; */
54
+#include "internals.h"
106
+    .type    sa, @object
55
+
107
+    .size    sa, 32
56
+static inline uint32_t vext_nf(uint32_t desc)
108
+sa:
57
+{
109
+    .dword    pass
58
+ return FIELD_EX32(simd_data(desc), VDATA, NF);
110
+    .zero    24
59
+}
111
+
60
+
61
+/*
62
+ * Note that vector data is stored in host-endian 64-bit chunks,
63
+ * so addressing units smaller than that needs a host-endian fixup.
64
+ */
65
+#if HOST_BIG_ENDIAN
66
+#define H1(x) ((x) ^ 7)
67
+#define H1_2(x) ((x) ^ 6)
68
+#define H1_4(x) ((x) ^ 4)
69
+#define H2(x) ((x) ^ 3)
70
+#define H4(x) ((x) ^ 1)
71
+#define H8(x) ((x))
72
+#else
73
+#define H1(x) (x)
74
+#define H1_2(x) (x)
75
+#define H1_4(x) (x)
76
+#define H2(x) (x)
77
+#define H4(x) (x)
78
+#define H8(x) (x)
79
+#endif
80
+
81
+/*
82
+ * Encode LMUL to lmul as following:
83
+ * LMUL vlmul lmul
84
+ * 1 000 0
85
+ * 2 001 1
86
+ * 4 010 2
87
+ * 8 011 3
88
+ * - 100 -
89
+ * 1/8 101 -3
90
+ * 1/4 110 -2
91
+ * 1/2 111 -1
92
+ */
93
+static inline int32_t vext_lmul(uint32_t desc)
94
+{
95
+ return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3);
96
+}
97
+
98
+static inline uint32_t vext_vm(uint32_t desc)
99
+{
100
+ return FIELD_EX32(simd_data(desc), VDATA, VM);
101
+}
102
+
103
+static inline uint32_t vext_vma(uint32_t desc)
104
+{
105
+ return FIELD_EX32(simd_data(desc), VDATA, VMA);
106
+}
107
+
108
+static inline uint32_t vext_vta(uint32_t desc)
109
+{
110
+ return FIELD_EX32(simd_data(desc), VDATA, VTA);
111
+}
112
+
113
+static inline uint32_t vext_vta_all_1s(uint32_t desc)
114
+{
115
+ return FIELD_EX32(simd_data(desc), VDATA, VTA_ALL_1S);
116
+}
117
+
118
+/*
119
+ * Earlier designs (pre-0.9) had a varying number of bits
120
+ * per mask value (MLEN). In the 0.9 design, MLEN=1.
121
+ * (Section 4.5)
122
+ */
123
+static inline int vext_elem_mask(void *v0, int index)
124
+{
125
+ int idx = index / 64;
126
+ int pos = index % 64;
127
+ return (((uint64_t *)v0)[idx] >> pos) & 1;
128
+}
129
+
130
+/*
131
+ * Get number of total elements, including prestart, body and tail elements.
132
+ * Note that when LMUL < 1, the tail includes the elements past VLMAX that
133
+ * are held in the same vector register.
134
+ */
135
+static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t desc,
136
+ uint32_t esz)
137
+{
138
+ uint32_t vlenb = simd_maxsz(desc);
139
+ uint32_t sew = 1 << FIELD_EX64(env->vtype, VTYPE, VSEW);
140
+ int8_t emul = ctzl(esz) - ctzl(sew) + vext_lmul(desc) < 0 ? 0 :
141
+ ctzl(esz) - ctzl(sew) + vext_lmul(desc);
142
+ return (vlenb << emul) / esz;
143
+}
144
+
145
+/* set agnostic elements to 1s */
146
+void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
147
+ uint32_t tot);
148
+
149
+/* expand macro args before macro */
150
+#define RVVCALL(macro, ...) macro(__VA_ARGS__)
151
+
152
+/* (TD, T1, T2, TX1, TX2) */
153
+#define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
154
+#define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t
155
+#define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t
156
+#define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t
157
+
158
+/* operation of two vector elements */
159
+typedef void opivv2_fn(void *vd, void *vs1, void *vs2, int i);
160
+
161
+#define OPIVV2(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP) \
162
+static void do_##NAME(void *vd, void *vs1, void *vs2, int i) \
163
+{ \
164
+ TX1 s1 = *((T1 *)vs1 + HS1(i)); \
165
+ TX2 s2 = *((T2 *)vs2 + HS2(i)); \
166
+ *((TD *)vd + HD(i)) = OP(s2, s1); \
167
+}
168
+
169
+void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
170
+ CPURISCVState *env, uint32_t desc,
171
+ opivv2_fn *fn, uint32_t esz);
172
+
173
+/* generate the helpers for OPIVV */
174
+#define GEN_VEXT_VV(NAME, ESZ) \
175
+void HELPER(NAME)(void *vd, void *v0, void *vs1, \
176
+ void *vs2, CPURISCVState *env, \
177
+ uint32_t desc) \
178
+{ \
179
+ do_vext_vv(vd, v0, vs1, vs2, env, desc, \
180
+ do_##NAME, ESZ); \
181
+}
182
+
183
+typedef void opivx2_fn(void *vd, target_long s1, void *vs2, int i);
184
+
185
+/*
186
+ * (T1)s1 gives the real operator type.
187
+ * (TX1)(T1)s1 expands the operator type of widen or narrow operations.
188
+ */
189
+#define OPIVX2(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \
190
+static void do_##NAME(void *vd, target_long s1, void *vs2, int i) \
191
+{ \
192
+ TX2 s2 = *((T2 *)vs2 + HS2(i)); \
193
+ *((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1); \
194
+}
195
+
196
+void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
197
+ CPURISCVState *env, uint32_t desc,
198
+ opivx2_fn fn, uint32_t esz);
199
+
200
+/* generate the helpers for OPIVX */
201
+#define GEN_VEXT_VX(NAME, ESZ) \
202
+void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
203
+ void *vs2, CPURISCVState *env, \
204
+ uint32_t desc) \
205
+{ \
206
+ do_vext_vx(vd, v0, s1, vs2, env, desc, \
207
+ do_##NAME, ESZ); \
208
+}
209
+
210
+#endif /* TARGET_RISCV_VECTOR_INTERNALS_H */
211
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/target/riscv/vector_helper.c
214
+++ b/target/riscv/vector_helper.c
215
@@ -XXX,XX +XXX,XX @@
216
#include "fpu/softfloat.h"
217
#include "tcg/tcg-gvec-desc.h"
218
#include "internals.h"
219
+#include "vector_internals.h"
220
#include <math.h>
221
222
target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
223
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
224
return vl;
225
}
226
227
-/*
228
- * Note that vector data is stored in host-endian 64-bit chunks,
229
- * so addressing units smaller than that needs a host-endian fixup.
230
- */
231
-#if HOST_BIG_ENDIAN
232
-#define H1(x) ((x) ^ 7)
233
-#define H1_2(x) ((x) ^ 6)
234
-#define H1_4(x) ((x) ^ 4)
235
-#define H2(x) ((x) ^ 3)
236
-#define H4(x) ((x) ^ 1)
237
-#define H8(x) ((x))
238
-#else
239
-#define H1(x) (x)
240
-#define H1_2(x) (x)
241
-#define H1_4(x) (x)
242
-#define H2(x) (x)
243
-#define H4(x) (x)
244
-#define H8(x) (x)
245
-#endif
246
-
247
-static inline uint32_t vext_nf(uint32_t desc)
248
-{
249
- return FIELD_EX32(simd_data(desc), VDATA, NF);
250
-}
251
-
252
-static inline uint32_t vext_vm(uint32_t desc)
253
-{
254
- return FIELD_EX32(simd_data(desc), VDATA, VM);
255
-}
256
-
257
-/*
258
- * Encode LMUL to lmul as following:
259
- * LMUL vlmul lmul
260
- * 1 000 0
261
- * 2 001 1
262
- * 4 010 2
263
- * 8 011 3
264
- * - 100 -
265
- * 1/8 101 -3
266
- * 1/4 110 -2
267
- * 1/2 111 -1
268
- */
269
-static inline int32_t vext_lmul(uint32_t desc)
270
-{
271
- return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3);
272
-}
273
-
274
-static inline uint32_t vext_vta(uint32_t desc)
275
-{
276
- return FIELD_EX32(simd_data(desc), VDATA, VTA);
277
-}
278
-
279
-static inline uint32_t vext_vma(uint32_t desc)
280
-{
281
- return FIELD_EX32(simd_data(desc), VDATA, VMA);
282
-}
283
-
284
-static inline uint32_t vext_vta_all_1s(uint32_t desc)
285
-{
286
- return FIELD_EX32(simd_data(desc), VDATA, VTA_ALL_1S);
287
-}
288
-
289
/*
290
* Get the maximum number of elements can be operated.
291
*
292
@@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz)
293
return scale < 0 ? vlenb >> -scale : vlenb << scale;
294
}
295
296
-/*
297
- * Get number of total elements, including prestart, body and tail elements.
298
- * Note that when LMUL < 1, the tail includes the elements past VLMAX that
299
- * are held in the same vector register.
300
- */
301
-static inline uint32_t vext_get_total_elems(CPURISCVState *env, uint32_t desc,
302
- uint32_t esz)
303
-{
304
- uint32_t vlenb = simd_maxsz(desc);
305
- uint32_t sew = 1 << FIELD_EX64(env->vtype, VTYPE, VSEW);
306
- int8_t emul = ctzl(esz) - ctzl(sew) + vext_lmul(desc) < 0 ? 0 :
307
- ctzl(esz) - ctzl(sew) + vext_lmul(desc);
308
- return (vlenb << emul) / esz;
309
-}
310
-
311
static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
312
{
313
return (addr & ~env->cur_pmmask) | env->cur_pmbase;
314
@@ -XXX,XX +XXX,XX @@ static void probe_pages(CPURISCVState *env, target_ulong addr,
315
}
316
}
317
318
-/* set agnostic elements to 1s */
319
-static void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
320
- uint32_t tot)
321
-{
322
- if (is_agnostic == 0) {
323
- /* policy undisturbed */
324
- return;
325
- }
326
- if (tot - cnt == 0) {
327
- return;
328
- }
329
- memset(base + cnt, -1, tot - cnt);
330
-}
331
-
332
static inline void vext_set_elem_mask(void *v0, int index,
333
uint8_t value)
334
{
335
@@ -XXX,XX +XXX,XX @@ static inline void vext_set_elem_mask(void *v0, int index,
336
((uint64_t *)v0)[idx] = deposit64(old, pos, 1, value);
337
}
338
339
-/*
340
- * Earlier designs (pre-0.9) had a varying number of bits
341
- * per mask value (MLEN). In the 0.9 design, MLEN=1.
342
- * (Section 4.5)
343
- */
344
-static inline int vext_elem_mask(void *v0, int index)
345
-{
346
- int idx = index / 64;
347
- int pos = index % 64;
348
- return (((uint64_t *)v0)[idx] >> pos) & 1;
349
-}
350
-
351
/* elements operations for load and store */
352
typedef void vext_ldst_elem_fn(CPURISCVState *env, abi_ptr addr,
353
uint32_t idx, void *vd, uintptr_t retaddr);
354
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
355
* Vector Integer Arithmetic Instructions
356
*/
357
358
-/* expand macro args before macro */
359
-#define RVVCALL(macro, ...) macro(__VA_ARGS__)
360
-
361
/* (TD, T1, T2, TX1, TX2) */
362
#define OP_SSS_B int8_t, int8_t, int8_t, int8_t, int8_t
363
#define OP_SSS_H int16_t, int16_t, int16_t, int16_t, int16_t
364
#define OP_SSS_W int32_t, int32_t, int32_t, int32_t, int32_t
365
#define OP_SSS_D int64_t, int64_t, int64_t, int64_t, int64_t
366
-#define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
367
-#define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t
368
-#define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t
369
-#define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t
370
#define OP_SUS_B int8_t, uint8_t, int8_t, uint8_t, int8_t
371
#define OP_SUS_H int16_t, uint16_t, int16_t, uint16_t, int16_t
372
#define OP_SUS_W int32_t, uint32_t, int32_t, uint32_t, int32_t
373
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
374
#define NOP_UUU_H uint16_t, uint16_t, uint32_t, uint16_t, uint32_t
375
#define NOP_UUU_W uint32_t, uint32_t, uint64_t, uint32_t, uint64_t
376
377
-/* operation of two vector elements */
378
-typedef void opivv2_fn(void *vd, void *vs1, void *vs2, int i);
379
-
380
-#define OPIVV2(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP) \
381
-static void do_##NAME(void *vd, void *vs1, void *vs2, int i) \
382
-{ \
383
- TX1 s1 = *((T1 *)vs1 + HS1(i)); \
384
- TX2 s2 = *((T2 *)vs2 + HS2(i)); \
385
- *((TD *)vd + HD(i)) = OP(s2, s1); \
386
-}
387
#define DO_SUB(N, M) (N - M)
388
#define DO_RSUB(N, M) (M - N)
389
390
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vsub_vv_h, OP_SSS_H, H2, H2, H2, DO_SUB)
391
RVVCALL(OPIVV2, vsub_vv_w, OP_SSS_W, H4, H4, H4, DO_SUB)
392
RVVCALL(OPIVV2, vsub_vv_d, OP_SSS_D, H8, H8, H8, DO_SUB)
393
394
-static void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
395
- CPURISCVState *env, uint32_t desc,
396
- opivv2_fn *fn, uint32_t esz)
397
-{
398
- uint32_t vm = vext_vm(desc);
399
- uint32_t vl = env->vl;
400
- uint32_t total_elems = vext_get_total_elems(env, desc, esz);
401
- uint32_t vta = vext_vta(desc);
402
- uint32_t vma = vext_vma(desc);
403
- uint32_t i;
404
-
405
- for (i = env->vstart; i < vl; i++) {
406
- if (!vm && !vext_elem_mask(v0, i)) {
407
- /* set masked-off elements to 1s */
408
- vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
409
- continue;
410
- }
411
- fn(vd, vs1, vs2, i);
412
- }
413
- env->vstart = 0;
414
- /* set tail elements to 1s */
415
- vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
416
-}
417
-
418
-/* generate the helpers for OPIVV */
419
-#define GEN_VEXT_VV(NAME, ESZ) \
420
-void HELPER(NAME)(void *vd, void *v0, void *vs1, \
421
- void *vs2, CPURISCVState *env, \
422
- uint32_t desc) \
423
-{ \
424
- do_vext_vv(vd, v0, vs1, vs2, env, desc, \
425
- do_##NAME, ESZ); \
426
-}
427
-
428
GEN_VEXT_VV(vadd_vv_b, 1)
429
GEN_VEXT_VV(vadd_vv_h, 2)
430
GEN_VEXT_VV(vadd_vv_w, 4)
431
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_VV(vsub_vv_h, 2)
432
GEN_VEXT_VV(vsub_vv_w, 4)
433
GEN_VEXT_VV(vsub_vv_d, 8)
434
435
-typedef void opivx2_fn(void *vd, target_long s1, void *vs2, int i);
436
-
437
-/*
438
- * (T1)s1 gives the real operator type.
439
- * (TX1)(T1)s1 expands the operator type of widen or narrow operations.
440
- */
441
-#define OPIVX2(NAME, TD, T1, T2, TX1, TX2, HD, HS2, OP) \
442
-static void do_##NAME(void *vd, target_long s1, void *vs2, int i) \
443
-{ \
444
- TX2 s2 = *((T2 *)vs2 + HS2(i)); \
445
- *((TD *)vd + HD(i)) = OP(s2, (TX1)(T1)s1); \
446
-}
447
448
RVVCALL(OPIVX2, vadd_vx_b, OP_SSS_B, H1, H1, DO_ADD)
449
RVVCALL(OPIVX2, vadd_vx_h, OP_SSS_H, H2, H2, DO_ADD)
450
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vrsub_vx_h, OP_SSS_H, H2, H2, DO_RSUB)
451
RVVCALL(OPIVX2, vrsub_vx_w, OP_SSS_W, H4, H4, DO_RSUB)
452
RVVCALL(OPIVX2, vrsub_vx_d, OP_SSS_D, H8, H8, DO_RSUB)
453
454
-static void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
455
- CPURISCVState *env, uint32_t desc,
456
- opivx2_fn fn, uint32_t esz)
457
-{
458
- uint32_t vm = vext_vm(desc);
459
- uint32_t vl = env->vl;
460
- uint32_t total_elems = vext_get_total_elems(env, desc, esz);
461
- uint32_t vta = vext_vta(desc);
462
- uint32_t vma = vext_vma(desc);
463
- uint32_t i;
464
-
465
- for (i = env->vstart; i < vl; i++) {
466
- if (!vm && !vext_elem_mask(v0, i)) {
467
- /* set masked-off elements to 1s */
468
- vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
469
- continue;
470
- }
471
- fn(vd, s1, vs2, i);
472
- }
473
- env->vstart = 0;
474
- /* set tail elements to 1s */
475
- vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
476
-}
477
-
478
-/* generate the helpers for OPIVX */
479
-#define GEN_VEXT_VX(NAME, ESZ) \
480
-void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
481
- void *vs2, CPURISCVState *env, \
482
- uint32_t desc) \
483
-{ \
484
- do_vext_vx(vd, v0, s1, vs2, env, desc, \
485
- do_##NAME, ESZ); \
486
-}
487
-
488
GEN_VEXT_VX(vadd_vx_b, 1)
489
GEN_VEXT_VX(vadd_vx_h, 2)
490
GEN_VEXT_VX(vadd_vx_w, 4)
491
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
492
new file mode 100644
493
index XXXXXXX..XXXXXXX
494
--- /dev/null
495
+++ b/target/riscv/vector_internals.c
496
@@ -XXX,XX +XXX,XX @@
497
+/*
498
+ * RISC-V Vector Extension Internals
499
+ *
500
+ * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
501
+ *
502
+ * This program is free software; you can redistribute it and/or modify it
503
+ * under the terms and conditions of the GNU General Public License,
504
+ * version 2 or later, as published by the Free Software Foundation.
505
+ *
506
+ * This program is distributed in the hope it will be useful, but WITHOUT
507
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
508
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
509
+ * more details.
510
+ *
511
+ * You should have received a copy of the GNU General Public License along with
512
+ * this program. If not, see <http://www.gnu.org/licenses/>.
513
+ */
514
+
515
+#include "vector_internals.h"
516
+
517
+/* set agnostic elements to 1s */
518
+void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
519
+ uint32_t tot)
520
+{
521
+ if (is_agnostic == 0) {
522
+ /* policy undisturbed */
523
+ return;
524
+ }
525
+ if (tot - cnt == 0) {
526
+ return ;
527
+ }
528
+ memset(base + cnt, -1, tot - cnt);
529
+}
530
+
531
+void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
532
+ CPURISCVState *env, uint32_t desc,
533
+ opivv2_fn *fn, uint32_t esz)
534
+{
535
+ uint32_t vm = vext_vm(desc);
536
+ uint32_t vl = env->vl;
537
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
538
+ uint32_t vta = vext_vta(desc);
539
+ uint32_t vma = vext_vma(desc);
540
+ uint32_t i;
541
+
542
+ for (i = env->vstart; i < vl; i++) {
543
+ if (!vm && !vext_elem_mask(v0, i)) {
544
+ /* set masked-off elements to 1s */
545
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
546
+ continue;
547
+ }
548
+ fn(vd, vs1, vs2, i);
549
+ }
550
+ env->vstart = 0;
551
+ /* set tail elements to 1s */
552
+ vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
553
+}
554
+
555
+void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
556
+ CPURISCVState *env, uint32_t desc,
557
+ opivx2_fn fn, uint32_t esz)
558
+{
559
+ uint32_t vm = vext_vm(desc);
560
+ uint32_t vl = env->vl;
561
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
562
+ uint32_t vta = vext_vta(desc);
563
+ uint32_t vma = vext_vma(desc);
564
+ uint32_t i;
565
+
566
+ for (i = env->vstart; i < vl; i++) {
567
+ if (!vm && !vext_elem_mask(v0, i)) {
568
+ /* set masked-off elements to 1s */
569
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
570
+ continue;
571
+ }
572
+ fn(vd, s1, vs2, i);
573
+ }
574
+ env->vstart = 0;
575
+ /* set tail elements to 1s */
576
+ vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
577
+}
578
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
579
index XXXXXXX..XXXXXXX 100644
580
--- a/target/riscv/meson.build
581
+++ b/target/riscv/meson.build
582
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(files(
583
'gdbstub.c',
584
'op_helper.c',
585
'vector_helper.c',
586
+ 'vector_internals.c',
587
'bitmanip_helper.c',
588
'translate.c',
589
'm128_helper.c',
112
--
590
--
113
2.38.1
591
2.41.0
diff view generated by jsdifflib
1
From: Conor Dooley <conor.dooley@microchip.com>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
On PolarFire SoC, some peripherals (eg the PCI root port) are clocked by
3
Refactor the non SEW-specific stuff out of `GEN_OPIVV_TRANS` into
4
"Clock Conditioning Circuitry" in the FPGA. The specific clock depends
4
function `opivv_trans` (similar to `opivi_trans`). `opivv_trans` will be
5
on the FPGA bitstream & can be locked to one particular {D,P}LL - in the
5
used in proceeding vector-crypto commits.
6
Icicle Kit Reference Design v2022.09 or later this is/will be the case.
7
6
8
Linux v6.1+ will have a driver for this peripheral and devicetrees that
7
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
9
previously relied on "fixed-frequency" clock nodes have been switched
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
over to clock-controller nodes. The IOSCB region is represented in QEMU,
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
but the specific region of it that the CCCs occupy has not so v6.1-rcN
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
12
kernels fail to boot in QEMU.
11
Signed-off-by: Max Chou <max.chou@sifive.com>
13
12
Message-ID: <20230711165917.2629866-3-max.chou@sifive.com>
14
Add the regions as unimplemented so that the status-quo in terms of boot
15
is maintained.
16
17
Acked-by: Alistair Francis <alistair.francis@wdc.com>
18
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
19
Message-Id: <20221117225518.4102575-2-conor@kernel.org>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
14
---
22
include/hw/misc/mchp_pfsoc_ioscb.h | 1 +
15
target/riscv/insn_trans/trans_rvv.c.inc | 62 +++++++++++++------------
23
hw/misc/mchp_pfsoc_ioscb.c | 6 ++++++
16
1 file changed, 32 insertions(+), 30 deletions(-)
24
2 files changed, 7 insertions(+)
25
17
26
diff --git a/include/hw/misc/mchp_pfsoc_ioscb.h b/include/hw/misc/mchp_pfsoc_ioscb.h
18
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
27
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/misc/mchp_pfsoc_ioscb.h
20
--- a/target/riscv/insn_trans/trans_rvv.c.inc
29
+++ b/include/hw/misc/mchp_pfsoc_ioscb.h
21
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
30
@@ -XXX,XX +XXX,XX @@ typedef struct MchpPfSoCIoscbState {
22
@@ -XXX,XX +XXX,XX @@ GEN_OPIWX_WIDEN_TRANS(vwadd_wx)
31
MemoryRegion lane23;
23
GEN_OPIWX_WIDEN_TRANS(vwsubu_wx)
32
MemoryRegion ctrl;
24
GEN_OPIWX_WIDEN_TRANS(vwsub_wx)
33
MemoryRegion cfg;
25
34
+ MemoryRegion ccc;
26
+static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
35
MemoryRegion pll_mss;
27
+ gen_helper_gvec_4_ptr *fn, DisasContext *s)
36
MemoryRegion cfm_mss;
28
+{
37
MemoryRegion pll_ddr;
29
+ uint32_t data = 0;
38
diff --git a/hw/misc/mchp_pfsoc_ioscb.c b/hw/misc/mchp_pfsoc_ioscb.c
30
+ TCGLabel *over = gen_new_label();
39
index XXXXXXX..XXXXXXX 100644
31
+ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
40
--- a/hw/misc/mchp_pfsoc_ioscb.c
32
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
41
+++ b/hw/misc/mchp_pfsoc_ioscb.c
33
+
42
@@ -XXX,XX +XXX,XX @@
34
+ data = FIELD_DP32(data, VDATA, VM, vm);
43
*/
35
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
44
#define IOSCB_WHOLE_REG_SIZE 0x10000000
36
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
45
#define IOSCB_SUBMOD_REG_SIZE 0x1000
37
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
46
+#define IOSCB_CCC_REG_SIZE 0x2000000
38
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
39
+ tcg_gen_gvec_4_ptr(vreg_ofs(s, vd), vreg_ofs(s, 0), vreg_ofs(s, vs1),
40
+ vreg_ofs(s, vs2), cpu_env, s->cfg_ptr->vlen / 8,
41
+ s->cfg_ptr->vlen / 8, data, fn);
42
+ mark_vs_dirty(s);
43
+ gen_set_label(over);
44
+ return true;
45
+}
46
+
47
/* Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions */
48
/* OPIVV without GVEC IR */
49
-#define GEN_OPIVV_TRANS(NAME, CHECK) \
50
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
51
-{ \
52
- if (CHECK(s, a)) { \
53
- uint32_t data = 0; \
54
- static gen_helper_gvec_4_ptr * const fns[4] = { \
55
- gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
56
- gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
57
- }; \
58
- TCGLabel *over = gen_new_label(); \
59
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
60
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
61
- \
62
- data = FIELD_DP32(data, VDATA, VM, a->vm); \
63
- data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
64
- data = FIELD_DP32(data, VDATA, VTA, s->vta); \
65
- data = \
66
- FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
67
- data = FIELD_DP32(data, VDATA, VMA, s->vma); \
68
- tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
69
- vreg_ofs(s, a->rs1), \
70
- vreg_ofs(s, a->rs2), cpu_env, \
71
- s->cfg_ptr->vlen / 8, \
72
- s->cfg_ptr->vlen / 8, data, \
73
- fns[s->sew]); \
74
- mark_vs_dirty(s); \
75
- gen_set_label(over); \
76
- return true; \
77
- } \
78
- return false; \
79
+#define GEN_OPIVV_TRANS(NAME, CHECK) \
80
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
81
+{ \
82
+ if (CHECK(s, a)) { \
83
+ static gen_helper_gvec_4_ptr * const fns[4] = { \
84
+ gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
85
+ gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
86
+ }; \
87
+ return opivv_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s);\
88
+ } \
89
+ return false; \
90
}
47
91
48
/*
92
/*
49
* There are many sub-modules in the IOSCB module.
50
@@ -XXX,XX +XXX,XX @@
51
#define IOSCB_LANE23_BASE 0x06510000
52
#define IOSCB_CTRL_BASE 0x07020000
53
#define IOSCB_CFG_BASE 0x07080000
54
+#define IOSCB_CCC_BASE 0x08000000
55
#define IOSCB_PLL_MSS_BASE 0x0E001000
56
#define IOSCB_CFM_MSS_BASE 0x0E002000
57
#define IOSCB_PLL_DDR_BASE 0x0E010000
58
@@ -XXX,XX +XXX,XX @@ static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp)
59
"mchp.pfsoc.ioscb.cfg", IOSCB_SUBMOD_REG_SIZE);
60
memory_region_add_subregion(&s->container, IOSCB_CFG_BASE, &s->cfg);
61
62
+ memory_region_init_io(&s->ccc, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
63
+ "mchp.pfsoc.ioscb.ccc", IOSCB_CCC_REG_SIZE);
64
+ memory_region_add_subregion(&s->container, IOSCB_CCC_BASE, &s->ccc);
65
+
66
memory_region_init_io(&s->pll_mss, OBJECT(s), &mchp_pfsoc_pll_ops, s,
67
"mchp.pfsoc.ioscb.pll_mss", IOSCB_SUBMOD_REG_SIZE);
68
memory_region_add_subregion(&s->container, IOSCB_PLL_MSS_BASE, &s->pll_mss);
69
--
93
--
70
2.38.1
94
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
The realize() callback has an errp for us to propagate the error up.
3
Remove the redundant "vl == 0" check which is already included within the vstart >= vl check, when vl == 0.
4
While we are here, correct the wrong multi-line comment format.
5
4
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
5
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Max Chou <max.chou@sifive.com>
9
Message-Id: <20221211030829.802437-8-bmeng@tinylab.org>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20230711165917.2629866-4-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
11
---
12
hw/intc/sifive_plic.c | 7 ++++---
12
target/riscv/insn_trans/trans_rvv.c.inc | 31 +------------------------
13
1 file changed, 4 insertions(+), 3 deletions(-)
13
1 file changed, 1 insertion(+), 30 deletions(-)
14
14
15
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/sifive_plic.c
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/hw/intc/sifive_plic.c
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
19
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
20
s->m_external_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
20
TCGv_i32 desc;
21
qdev_init_gpio_out(dev, s->m_external_irqs, s->num_harts);
21
22
22
TCGLabel *over = gen_new_label();
23
- /* We can't allow the supervisor to control SEIP as this would allow the
23
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
24
+ /*
24
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
25
+ * We can't allow the supervisor to control SEIP as this would allow the
25
26
* supervisor to clear a pending external interrupt which will result in
26
dest = tcg_temp_new_ptr();
27
* lost a interrupt in the case a PLIC is attached. The SEIP bit must be
27
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
28
* hardware controlled when a PLIC is attached.
28
TCGv_i32 desc;
29
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
29
30
for (i = 0; i < s->num_harts; i++) {
30
TCGLabel *over = gen_new_label();
31
RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i));
31
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
32
if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
32
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
33
- error_report("SEIP already claimed");
33
34
- exit(1);
34
dest = tcg_temp_new_ptr();
35
+ error_setg(errp, "SEIP already claimed");
35
@@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
36
+ return;
36
TCGv_i32 desc;
37
}
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;
38
}
53
}
39
54
55
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
56
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
57
58
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
59
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
60
uint32_t data = 0;
61
62
TCGLabel *over = gen_new_label();
63
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
64
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
65
66
dest = tcg_temp_new_ptr();
67
@@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
68
uint32_t data = 0;
69
70
TCGLabel *over = gen_new_label();
71
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
72
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
73
74
dest = tcg_temp_new_ptr();
75
@@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
76
if (checkfn(s, a)) {
77
uint32_t data = 0;
78
TCGLabel *over = gen_new_label();
79
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
80
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
81
82
data = FIELD_DP32(data, VDATA, VM, a->vm);
83
@@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
84
if (opiwv_widen_check(s, a)) {
85
uint32_t data = 0;
86
TCGLabel *over = gen_new_label();
87
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
88
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
89
90
data = FIELD_DP32(data, VDATA, VM, a->vm);
91
@@ -XXX,XX +XXX,XX @@ static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
92
{
93
uint32_t data = 0;
94
TCGLabel *over = gen_new_label();
95
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
96
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
97
98
data = FIELD_DP32(data, VDATA, VM, vm);
99
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
100
gen_helper_##NAME##_w, \
101
}; \
102
TCGLabel *over = gen_new_label(); \
103
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
104
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
105
\
106
data = FIELD_DP32(data, VDATA, VM, a->vm); \
107
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
108
gen_helper_vmv_v_v_w, gen_helper_vmv_v_v_d,
109
};
110
TCGLabel *over = gen_new_label();
111
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
112
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
113
114
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
115
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
116
vext_check_ss(s, a->rd, 0, 1)) {
117
TCGv s1;
118
TCGLabel *over = gen_new_label();
119
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
120
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
121
122
s1 = get_gpr(s, a->rs1, EXT_SIGN);
123
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
124
gen_helper_vmv_v_x_w, gen_helper_vmv_v_x_d,
125
};
126
TCGLabel *over = gen_new_label();
127
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
128
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
129
130
s1 = tcg_constant_i64(simm);
131
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
132
}; \
133
TCGLabel *over = gen_new_label(); \
134
gen_set_rm(s, RISCV_FRM_DYN); \
135
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
136
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
137
\
138
data = FIELD_DP32(data, VDATA, VM, a->vm); \
139
@@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
140
TCGv_i64 t1;
141
142
TCGLabel *over = gen_new_label();
143
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
144
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
145
146
dest = tcg_temp_new_ptr();
147
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
148
}; \
149
TCGLabel *over = gen_new_label(); \
150
gen_set_rm(s, RISCV_FRM_DYN); \
151
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
152
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);\
153
\
154
data = FIELD_DP32(data, VDATA, VM, a->vm); \
155
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
156
}; \
157
TCGLabel *over = gen_new_label(); \
158
gen_set_rm(s, RISCV_FRM_DYN); \
159
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
160
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
161
\
162
data = FIELD_DP32(data, VDATA, VM, a->vm); \
163
@@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
164
uint32_t data = 0;
165
TCGLabel *over = gen_new_label();
166
gen_set_rm_chkfrm(s, rm);
167
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
168
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
169
170
data = FIELD_DP32(data, VDATA, VM, a->vm);
171
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
172
gen_helper_vmv_v_x_d,
173
};
174
TCGLabel *over = gen_new_label();
175
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
176
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
177
178
t1 = tcg_temp_new_i64();
179
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
180
}; \
181
TCGLabel *over = gen_new_label(); \
182
gen_set_rm_chkfrm(s, FRM); \
183
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
184
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
185
\
186
data = FIELD_DP32(data, VDATA, VM, a->vm); \
187
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
188
}; \
189
TCGLabel *over = gen_new_label(); \
190
gen_set_rm(s, RISCV_FRM_DYN); \
191
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
192
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
193
\
194
data = FIELD_DP32(data, VDATA, VM, a->vm); \
195
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
196
}; \
197
TCGLabel *over = gen_new_label(); \
198
gen_set_rm_chkfrm(s, FRM); \
199
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
200
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
201
\
202
data = FIELD_DP32(data, VDATA, VM, a->vm); \
203
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
204
}; \
205
TCGLabel *over = gen_new_label(); \
206
gen_set_rm_chkfrm(s, FRM); \
207
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
208
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
209
\
210
data = FIELD_DP32(data, VDATA, VM, a->vm); \
211
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \
212
uint32_t data = 0; \
213
gen_helper_gvec_4_ptr *fn = gen_helper_##NAME; \
214
TCGLabel *over = gen_new_label(); \
215
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
216
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
217
\
218
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
219
@@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
220
require_vm(a->vm, a->rd)) {
221
uint32_t data = 0;
222
TCGLabel *over = gen_new_label();
223
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
224
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
225
226
data = FIELD_DP32(data, VDATA, VM, a->vm);
227
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
228
TCGv s1;
229
TCGLabel *over = gen_new_label();
230
231
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
232
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
233
234
t1 = tcg_temp_new_i64();
235
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
236
TCGv_i64 t1;
237
TCGLabel *over = gen_new_label();
238
239
- /* if vl == 0 or vstart >= vl, skip vector register write back */
240
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
241
+ /* if vstart >= vl, skip vector register write back */
242
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
243
244
/* NaN-box f[rs1] */
245
@@ -XXX,XX +XXX,XX @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
246
uint32_t data = 0;
247
gen_helper_gvec_3_ptr *fn;
248
TCGLabel *over = gen_new_label();
249
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
250
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
251
252
static gen_helper_gvec_3_ptr * const fns[6][4] = {
40
--
253
--
41
2.38.1
254
2.41.0
diff view generated by jsdifflib
1
From: Christoph Muellner <christoph.muellner@vrull.eu>
1
From: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
2
2
3
This patch adds support for the Zawrs ISA extension.
3
This commit adds support for the Zvbc vector-crypto extension, which
4
Given the current (incomplete) implementation of reservation sets
4
consists of the following instructions:
5
there seems to be no way to provide a full emulation of the WRS
5
6
instruction (wake on reservation set invalidation or timeout or
6
* vclmulh.[vx,vv]
7
interrupt). Therefore, we just exit the TB and return to the main loop.
7
* vclmul.[vx,vv]
8
8
9
The specification can be found here:
9
Translation functions are defined in
10
https://github.com/riscv/riscv-zawrs/blob/main/zawrs.adoc
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
11
`target/riscv/vcrypto_helper.c`.
12
Note, that the Zawrs extension is frozen, but not ratified yet.
12
13
13
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
14
Changes since v3:
14
Co-authored-by: Max Chou <max.chou@sifive.com>
15
* Remove "RFC" since the extension is frozen
15
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
16
* Rebase on master and fix integration issues
16
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
17
* Fix entry ordering in extension list
17
Signed-off-by: Max Chou <max.chou@sifive.com>
18
18
[max.chou@sifive.com: Exposed x-zvbc property]
19
Changes since v2:
19
Message-ID: <20230711165917.2629866-5-max.chou@sifive.com>
20
* Rebase on master and resolve conflicts
21
* Adjustments according to a specification change
22
* Inline REQUIRE_ZAWRS() since it has only one user
23
24
Changes since v1:
25
* Adding zawrs to the ISA string that is passed to the kernel
26
27
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
28
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
29
Message-Id: <20221005144948.3421504-1-christoph.muellner@vrull.eu>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
31
---
21
---
32
target/riscv/cpu.h | 1 +
22
target/riscv/cpu_cfg.h | 1 +
33
target/riscv/insn32.decode | 4 ++
23
target/riscv/helper.h | 6 +++
34
target/riscv/cpu.c | 7 +++
24
target/riscv/insn32.decode | 6 +++
35
target/riscv/translate.c | 1 +
25
target/riscv/cpu.c | 9 ++++
36
target/riscv/insn_trans/trans_rvzawrs.c.inc | 51 +++++++++++++++++++++
26
target/riscv/translate.c | 1 +
37
5 files changed, 64 insertions(+)
27
target/riscv/vcrypto_helper.c | 59 ++++++++++++++++++++++
38
create mode 100644 target/riscv/insn_trans/trans_rvzawrs.c.inc
28
target/riscv/insn_trans/trans_rvvk.c.inc | 62 ++++++++++++++++++++++++
39
29
target/riscv/meson.build | 3 +-
40
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
30
8 files changed, 146 insertions(+), 1 deletion(-)
41
index XXXXXXX..XXXXXXX 100644
31
create mode 100644 target/riscv/vcrypto_helper.c
42
--- a/target/riscv/cpu.h
32
create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc
43
+++ b/target/riscv/cpu.h
33
34
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/riscv/cpu_cfg.h
37
+++ b/target/riscv/cpu_cfg.h
44
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
38
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
45
bool ext_svnapot;
39
bool ext_zve32f;
46
bool ext_svpbmt;
40
bool ext_zve64f;
47
bool ext_zdinx;
41
bool ext_zve64d;
48
+ bool ext_zawrs;
42
+ bool ext_zvbc;
49
bool ext_zfh;
43
bool ext_zmmul;
50
bool ext_zfhmin;
44
bool ext_zvfbfmin;
51
bool ext_zfinx;
45
bool ext_zvfbfwma;
46
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/helper.h
49
+++ b/target/riscv/helper.h
50
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vfwcvtbf16_f_f_v, void, ptr, ptr, ptr, env, i32)
51
52
DEF_HELPER_6(vfwmaccbf16_vv, void, ptr, ptr, ptr, ptr, env, i32)
53
DEF_HELPER_6(vfwmaccbf16_vf, void, ptr, ptr, i64, ptr, env, i32)
54
+
55
+/* Vector crypto functions */
56
+DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
57
+DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
58
+DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
59
+DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
52
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
53
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
54
--- a/target/riscv/insn32.decode
62
--- a/target/riscv/insn32.decode
55
+++ b/target/riscv/insn32.decode
63
+++ b/target/riscv/insn32.decode
56
@@ -XXX,XX +XXX,XX @@ vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm11
64
@@ -XXX,XX +XXX,XX @@ vfwcvtbf16_f_f_v 010010 . ..... 01101 001 ..... 1010111 @r2_vm
57
vsetivli 11 .......... ..... 111 ..... 1010111 @r2_zimm10
65
# *** Zvfbfwma Standard Extension ***
58
vsetvl 1000000 ..... ..... 111 ..... 1010111 @r
66
vfwmaccbf16_vv 111011 . ..... ..... 001 ..... 1010111 @r_vm
59
67
vfwmaccbf16_vf 111011 . ..... ..... 101 ..... 1010111 @r_vm
60
+# *** Zawrs Standard Extension ***
68
+
61
+wrs_nto 000000001101 00000 000 00000 1110011
69
+# *** Zvbc vector crypto extension ***
62
+wrs_sto 000000011101 00000 000 00000 1110011
70
+vclmul_vv 001100 . ..... ..... 010 ..... 1010111 @r_vm
63
+
71
+vclmul_vx 001100 . ..... ..... 110 ..... 1010111 @r_vm
64
# *** RV32 Zba Standard Extension ***
72
+vclmulh_vv 001101 . ..... ..... 010 ..... 1010111 @r_vm
65
sh1add 0010000 .......... 010 ..... 0110011 @r
73
+vclmulh_vx 001101 . ..... ..... 110 ..... 1010111 @r_vm
66
sh2add 0010000 .......... 100 ..... 0110011 @r
67
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
68
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
69
--- a/target/riscv/cpu.c
76
--- a/target/riscv/cpu.c
70
+++ b/target/riscv/cpu.c
77
+++ b/target/riscv/cpu.c
71
@@ -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[] = {
72
ISA_EXT_DATA_ENTRY(zicsr, true, PRIV_VERSION_1_10_0, ext_icsr),
79
ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
73
ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei),
80
ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
74
ISA_EXT_DATA_ENTRY(zihintpause, true, PRIV_VERSION_1_10_0, ext_zihintpause),
81
ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
75
+ ISA_EXT_DATA_ENTRY(zawrs, true, PRIV_VERSION_1_12_0, ext_zawrs),
82
+ ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
76
ISA_EXT_DATA_ENTRY(zfh, true, PRIV_VERSION_1_12_0, ext_zfh),
83
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
77
ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
84
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
78
ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
85
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
79
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
86
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
80
return;
87
return;
81
}
88
}
82
89
83
+ if ((cpu->cfg.ext_zawrs) && !cpu->cfg.ext_a) {
90
+ if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
84
+ error_setg(errp, "Zawrs extension requires A extension");
91
+ error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
85
+ return;
92
+ return;
86
+ }
93
+ }
87
+
94
+
88
if ((cpu->cfg.ext_zfh || cpu->cfg.ext_zfhmin) && !cpu->cfg.ext_f) {
95
if (cpu->cfg.ext_zk) {
89
error_setg(errp, "Zfh/Zfhmin extensions require F extension");
96
cpu->cfg.ext_zkn = true;
90
return;
97
cpu->cfg.ext_zkr = true;
91
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
98
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
92
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
99
DEFINE_PROP_BOOL("x-zvfbfmin", RISCVCPU, cfg.ext_zvfbfmin, false),
93
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
100
DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
94
DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
101
95
+ DEFINE_PROP_BOOL("Zawrs", RISCVCPU, cfg.ext_zawrs, true),
102
+ /* Vector cryptography extensions */
96
DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
103
+ DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
97
DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
104
+
98
DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false),
105
DEFINE_PROP_END_OF_LIST(),
106
};
107
99
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
100
index XXXXXXX..XXXXXXX 100644
109
index XXXXXXX..XXXXXXX 100644
101
--- a/target/riscv/translate.c
110
--- a/target/riscv/translate.c
102
+++ b/target/riscv/translate.c
111
+++ b/target/riscv/translate.c
103
@@ -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)
104
#include "insn_trans/trans_rvh.c.inc"
113
#include "insn_trans/trans_rvzfa.c.inc"
105
#include "insn_trans/trans_rvv.c.inc"
106
#include "insn_trans/trans_rvb.c.inc"
107
+#include "insn_trans/trans_rvzawrs.c.inc"
108
#include "insn_trans/trans_rvzfh.c.inc"
114
#include "insn_trans/trans_rvzfh.c.inc"
109
#include "insn_trans/trans_rvk.c.inc"
115
#include "insn_trans/trans_rvk.c.inc"
116
+#include "insn_trans/trans_rvvk.c.inc"
110
#include "insn_trans/trans_privileged.c.inc"
117
#include "insn_trans/trans_privileged.c.inc"
111
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc b/target/riscv/insn_trans/trans_rvzawrs.c.inc
118
#include "insn_trans/trans_svinval.c.inc"
119
#include "insn_trans/trans_rvbf16.c.inc"
120
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
112
new file mode 100644
121
new file mode 100644
113
index XXXXXXX..XXXXXXX
122
index XXXXXXX..XXXXXXX
114
--- /dev/null
123
--- /dev/null
115
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
124
+++ b/target/riscv/vcrypto_helper.c
116
@@ -XXX,XX +XXX,XX @@
125
@@ -XXX,XX +XXX,XX @@
117
+/*
126
+/*
118
+ * RISC-V translation routines for the RISC-V Zawrs Extension.
127
+ * RISC-V Vector Crypto Extension Helpers for QEMU.
119
+ *
128
+ *
120
+ * Copyright (c) 2022 Christoph Muellner, christoph.muellner@vrull.io
129
+ * Copyright (C) 2023 SiFive, Inc.
130
+ * Written by Codethink Ltd and SiFive.
121
+ *
131
+ *
122
+ * 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
123
+ * under the terms and conditions of the GNU General Public License,
133
+ * under the terms and conditions of the GNU General Public License,
124
+ * version 2 or later, as published by the Free Software Foundation.
134
+ * version 2 or later, as published by the Free Software Foundation.
125
+ *
135
+ *
...
...
130
+ *
140
+ *
131
+ * 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
132
+ * this program. If not, see <http://www.gnu.org/licenses/>.
142
+ * this program. If not, see <http://www.gnu.org/licenses/>.
133
+ */
143
+ */
134
+
144
+
135
+static bool trans_wrs(DisasContext *ctx)
145
+#include "qemu/osdep.h"
136
+{
146
+#include "qemu/host-utils.h"
137
+ if (!ctx->cfg_ptr->ext_zawrs) {
147
+#include "qemu/bitops.h"
138
+ return false;
148
+#include "cpu.h"
139
+ }
149
+#include "exec/memop.h"
140
+
150
+#include "exec/exec-all.h"
141
+ /*
151
+#include "exec/helper-proto.h"
142
+ * The specification says:
152
+#include "internals.h"
143
+ * While stalled, an implementation is permitted to occasionally
153
+#include "vector_internals.h"
144
+ * terminate the stall and complete execution for any reason.
154
+
145
+ *
155
+static uint64_t clmul64(uint64_t y, uint64_t x)
146
+ * So let's just exit TB and return to the main loop.
156
+{
147
+ */
157
+ uint64_t result = 0;
148
+
158
+ for (int j = 63; j >= 0; j--) {
149
+ /* Clear the load reservation (if any). */
159
+ if ((y >> j) & 1) {
150
+ tcg_gen_movi_tl(load_res, -1);
160
+ result ^= (x << j);
151
+
161
+ }
152
+ gen_set_pc_imm(ctx, ctx->pc_succ_insn);
162
+ }
153
+ tcg_gen_exit_tb(NULL, 0);
163
+ return result;
154
+ ctx->base.is_jmp = DISAS_NORETURN;
164
+}
155
+
165
+
156
+ return true;
166
+static uint64_t clmulh64(uint64_t y, uint64_t x)
157
+}
167
+{
158
+
168
+ uint64_t result = 0;
159
+#define GEN_TRANS_WRS(insn) \
169
+ for (int j = 63; j >= 1; j--) {
160
+static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn *a) \
170
+ if ((y >> j) & 1) {
161
+{ \
171
+ result ^= (x >> (64 - j));
162
+ (void)a; \
172
+ }
163
+ return trans_wrs(ctx); \
173
+ }
164
+}
174
+ return result;
165
+
175
+}
166
+GEN_TRANS_WRS(wrs_nto)
176
+
167
+GEN_TRANS_WRS(wrs_sto)
177
+RVVCALL(OPIVV2, vclmul_vv, OP_UUU_D, H8, H8, H8, clmul64)
178
+GEN_VEXT_VV(vclmul_vv, 8)
179
+RVVCALL(OPIVX2, vclmul_vx, OP_UUU_D, H8, H8, clmul64)
180
+GEN_VEXT_VX(vclmul_vx, 8)
181
+RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64)
182
+GEN_VEXT_VV(vclmulh_vv, 8)
183
+RVVCALL(OPIVX2, vclmulh_vx, OP_UUU_D, H8, H8, clmulh64)
184
+GEN_VEXT_VX(vclmulh_vx, 8)
185
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
186
new file mode 100644
187
index XXXXXXX..XXXXXXX
188
--- /dev/null
189
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
190
@@ -XXX,XX +XXX,XX @@
191
+/*
192
+ * RISC-V translation routines for the vector crypto extension.
193
+ *
194
+ * Copyright (C) 2023 SiFive, Inc.
195
+ * Written by Codethink Ltd and SiFive.
196
+ *
197
+ * This program is free software; you can redistribute it and/or modify it
198
+ * under the terms and conditions of the GNU General Public License,
199
+ * version 2 or later, as published by the Free Software Foundation.
200
+ *
201
+ * This program is distributed in the hope it will be useful, but WITHOUT
202
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
203
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
204
+ * more details.
205
+ *
206
+ * You should have received a copy of the GNU General Public License along with
207
+ * this program. If not, see <http://www.gnu.org/licenses/>.
208
+ */
209
+
210
+/*
211
+ * Zvbc
212
+ */
213
+
214
+#define GEN_VV_MASKED_TRANS(NAME, CHECK) \
215
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
216
+ { \
217
+ if (CHECK(s, a)) { \
218
+ return opivv_trans(a->rd, a->rs1, a->rs2, a->vm, \
219
+ gen_helper_##NAME, s); \
220
+ } \
221
+ return false; \
222
+ }
223
+
224
+static bool vclmul_vv_check(DisasContext *s, arg_rmrr *a)
225
+{
226
+ return opivv_check(s, a) &&
227
+ s->cfg_ptr->ext_zvbc == true &&
228
+ s->sew == MO_64;
229
+}
230
+
231
+GEN_VV_MASKED_TRANS(vclmul_vv, vclmul_vv_check)
232
+GEN_VV_MASKED_TRANS(vclmulh_vv, vclmul_vv_check)
233
+
234
+#define GEN_VX_MASKED_TRANS(NAME, CHECK) \
235
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
236
+ { \
237
+ if (CHECK(s, a)) { \
238
+ return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, \
239
+ gen_helper_##NAME, s); \
240
+ } \
241
+ return false; \
242
+ }
243
+
244
+static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a)
245
+{
246
+ return opivx_check(s, a) &&
247
+ s->cfg_ptr->ext_zvbc == true &&
248
+ s->sew == MO_64;
249
+}
250
+
251
+GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check)
252
+GEN_VX_MASKED_TRANS(vclmulh_vx, vclmul_vx_check)
253
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
254
index XXXXXXX..XXXXXXX 100644
255
--- a/target/riscv/meson.build
256
+++ b/target/riscv/meson.build
257
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(files(
258
'translate.c',
259
'm128_helper.c',
260
'crypto_helper.c',
261
- 'zce_helper.c'
262
+ 'zce_helper.c',
263
+ 'vcrypto_helper.c'
264
))
265
riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c'))
266
168
--
267
--
169
2.38.1
268
2.41.0
diff view generated by jsdifflib
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
Only the pmp index that be checked by pmp_hart_has_privs can be used
3
Move the checks out of `do_opiv{v,x,i}_gvec{,_shift}` functions
4
by pmp_get_tlb_size to avoid an error pmp index.
4
and into the corresponding macros. This enables the functions to be
5
reused in proceeding commits without check duplication.
5
6
6
Before modification, we may use an error pmp index. For example,
7
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
7
we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
9
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
will return true;
10
Signed-off-by: Max Chou <max.chou@sifive.com>
10
11
Message-ID: <20230711165917.2629866-6-max.chou@sifive.com>
11
However, this checked pmp index is discarded as pmp_hart_has_privs
12
return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
13
rules. The tlb_sa will be 0x0, and tlb_ea will be 0xfff. If there is
14
a pmp rule [0x10, 0x14), it will be misused as it is legal in
15
pmp_get_tlb_size.
16
17
As we have already known the correct pmp index, just remove the
18
remove the pmp_is_range_in_tlb and get tlb size directly from
19
pmp_get_tlb_size.
20
21
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
22
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Message-Id: <20221012060016.30856-1-zhiwei_liu@linux.alibaba.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
13
---
26
target/riscv/pmp.h | 6 +--
14
target/riscv/insn_trans/trans_rvv.c.inc | 28 +++++++++++--------------
27
target/riscv/cpu_helper.c | 16 ++++---
15
1 file changed, 12 insertions(+), 16 deletions(-)
28
target/riscv/pmp.c | 90 +++++++++++++--------------------------
29
3 files changed, 42 insertions(+), 70 deletions(-)
30
16
31
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
17
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
32
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/pmp.h
19
--- a/target/riscv/insn_trans/trans_rvv.c.inc
34
+++ b/target/riscv/pmp.h
20
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
35
@@ -XXX,XX +XXX,XX @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
21
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
36
void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
22
gen_helper_gvec_4_ptr *fn)
37
target_ulong val);
38
target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
39
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
40
+int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
41
target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
42
target_ulong mode);
43
-bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
44
- target_ulong *tlb_size);
45
+target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
46
+ target_ulong tlb_sa, target_ulong tlb_ea);
47
void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
48
void pmp_update_rule_nums(CPURISCVState *env);
49
uint32_t pmp_get_num_rules(CPURISCVState *env);
50
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/riscv/cpu_helper.c
53
+++ b/target/riscv/cpu_helper.c
54
@@ -XXX,XX +XXX,XX @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
55
int mode)
56
{
23
{
57
pmp_priv_t pmp_priv;
24
TCGLabel *over = gen_new_label();
58
- target_ulong tlb_size_pmp = 0;
25
- if (!opivv_check(s, a)) {
59
+ int pmp_index = -1;
26
- return false;
60
27
- }
61
if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
28
62
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
29
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
63
return TRANSLATE_SUCCESS;
30
64
}
31
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
65
32
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
66
- if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
33
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
67
- mode)) {
34
}; \
68
+ pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type,
35
+ if (!opivv_check(s, a)) { \
69
+ &pmp_priv, mode);
36
+ return false; \
70
+ if (pmp_index < 0) {
37
+ } \
71
*prot = 0;
38
return do_opivv_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
72
return TRANSLATE_PMP_FAIL;
39
}
73
}
40
74
41
@@ -XXX,XX +XXX,XX @@ static inline bool
75
*prot = pmp_priv_to_page_prot(pmp_priv);
42
do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
76
- if (tlb_size != NULL) {
43
gen_helper_opivx *fn)
77
- if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
78
- *tlb_size = tlb_size_pmp;
79
- }
80
+ if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
81
+ target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1);
82
+ target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1;
83
+
84
+ *tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea);
85
}
86
87
return TRANSLATE_SUCCESS;
88
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/riscv/pmp.c
91
+++ b/target/riscv/pmp.c
92
@@ -XXX,XX +XXX,XX @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
93
94
/*
95
* Check if the address has required RWX privs to complete desired operation
96
+ * Return PMP rule index if a pmp rule match
97
+ * Return MAX_RISCV_PMPS if default match
98
+ * Return negtive value if no match
99
*/
100
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
101
+int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
102
target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
103
target_ulong mode)
104
{
44
{
105
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
45
- if (!opivx_check(s, a)) {
106
46
- return false;
107
/* Short cut if no rules */
108
if (0 == pmp_get_num_rules(env)) {
109
- return pmp_hart_has_privs_default(env, addr, size, privs,
110
- allowed_privs, mode);
111
+ if (pmp_hart_has_privs_default(env, addr, size, privs,
112
+ allowed_privs, mode)) {
113
+ ret = MAX_RISCV_PMPS;
114
+ }
115
}
116
117
if (size == 0) {
118
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
119
if ((s + e) == 1) {
120
qemu_log_mask(LOG_GUEST_ERROR,
121
"pmp violation - access is partially inside\n");
122
- ret = 0;
123
+ ret = -1;
124
break;
125
}
126
127
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
128
}
129
}
130
131
- ret = ((privs & *allowed_privs) == privs);
132
+ if ((privs & *allowed_privs) == privs) {
133
+ ret = i;
134
+ }
135
break;
136
}
137
}
138
139
/* No rule matched */
140
if (ret == -1) {
141
- return pmp_hart_has_privs_default(env, addr, size, privs,
142
- allowed_privs, mode);
143
+ if (pmp_hart_has_privs_default(env, addr, size, privs,
144
+ allowed_privs, mode)) {
145
+ ret = MAX_RISCV_PMPS;
146
+ }
147
}
148
149
- return ret == 1 ? true : false;
150
+ return ret;
151
}
152
153
/*
154
@@ -XXX,XX +XXX,XX @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
155
* Calculate the TLB size if the start address or the end address of
156
* PMP entry is presented in the TLB page.
157
*/
158
-static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
159
- target_ulong tlb_sa, target_ulong tlb_ea)
160
+target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
161
+ target_ulong tlb_sa, target_ulong tlb_ea)
162
{
163
target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa;
164
target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea;
165
166
- if (pmp_sa >= tlb_sa && pmp_ea <= tlb_ea) {
167
- return pmp_ea - pmp_sa + 1;
168
- }
47
- }
169
-
48
-
170
- if (pmp_sa >= tlb_sa && pmp_sa <= tlb_ea && pmp_ea >= tlb_ea) {
49
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
171
- return tlb_ea - pmp_sa + 1;
50
TCGv_i64 src1 = tcg_temp_new_i64();
51
52
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
53
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
54
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
55
}; \
56
+ if (!opivx_check(s, a)) { \
57
+ return false; \
58
+ } \
59
return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
60
}
61
62
@@ -XXX,XX +XXX,XX @@ static inline bool
63
do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn,
64
gen_helper_opivx *fn, imm_mode_t imm_mode)
65
{
66
- if (!opivx_check(s, a)) {
67
- return false;
172
- }
68
- }
173
-
69
-
174
- if (pmp_ea <= tlb_ea && pmp_ea >= tlb_sa && pmp_sa <= tlb_sa) {
70
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
175
- return pmp_ea - tlb_sa + 1;
71
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
72
extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s));
73
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
74
gen_helper_##OPIVX##_b, gen_helper_##OPIVX##_h, \
75
gen_helper_##OPIVX##_w, gen_helper_##OPIVX##_d, \
76
}; \
77
+ if (!opivx_check(s, a)) { \
78
+ return false; \
79
+ } \
80
return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, \
81
fns[s->sew], IMM_MODE); \
82
}
83
@@ -XXX,XX +XXX,XX @@ static inline bool
84
do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
85
gen_helper_opivx *fn)
86
{
87
- if (!opivx_check(s, a)) {
88
- return false;
176
- }
89
- }
177
-
90
-
178
- return 0;
91
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
179
-}
92
TCGv_i32 src1 = tcg_temp_new_i32();
180
-
93
181
-/*
94
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
182
- * Check is there a PMP entry which range covers this page. If so,
95
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
183
- * try to find the minimum granularity for the TLB size.
96
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
184
- */
97
}; \
185
-bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
98
- \
186
- target_ulong *tlb_size)
99
+ if (!opivx_check(s, a)) { \
187
-{
100
+ return false; \
188
- int i;
101
+ } \
189
- target_ulong val;
102
return do_opivx_gvec_shift(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
190
- target_ulong tlb_ea = (tlb_sa + TARGET_PAGE_SIZE - 1);
191
-
192
- for (i = 0; i < MAX_RISCV_PMPS; i++) {
193
- val = pmp_get_tlb_size(env, i, tlb_sa, tlb_ea);
194
- if (val) {
195
- if (*tlb_size == 0 || *tlb_size > val) {
196
- *tlb_size = val;
197
- }
198
- }
199
- }
200
-
201
- if (*tlb_size != 0) {
202
+ if (pmp_sa <= tlb_sa && pmp_ea >= tlb_ea) {
203
+ return TARGET_PAGE_SIZE;
204
+ } else {
205
/*
206
- * At this point we have a tlb_size that is the smallest possible size
207
- * That fits within a TARGET_PAGE_SIZE and the PMP region.
208
- *
209
- * If the size is less then TARGET_PAGE_SIZE we drop the size to 1.
210
- * This means the result isn't cached in the TLB and is only used for
211
- * a single translation.
212
- */
213
- if (*tlb_size < TARGET_PAGE_SIZE) {
214
- *tlb_size = 1;
215
- }
216
-
217
- return true;
218
+ * At this point we have a tlb_size that is the smallest possible size
219
+ * That fits within a TARGET_PAGE_SIZE and the PMP region.
220
+ *
221
+ * If the size is less then TARGET_PAGE_SIZE we drop the size to 1.
222
+ * This means the result isn't cached in the TLB and is only used for
223
+ * a single translation.
224
+ */
225
+ return 1;
226
}
227
-
228
- return false;
229
}
103
}
230
104
231
/*
232
--
105
--
233
2.38.1
106
2.41.0
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Dickon Hood <dickon.hood@codethink.co.uk>
2
2
3
When guest_base != 0, we were not coordinating the usage of
3
Zvbb (implemented in later commit) has a widening instruction, which
4
TCG_REG_TMP0 as base properly, leading to a previous zero-extend
4
requires an extra check on the enabled extensions. Refactor
5
of the input address being discarded.
5
GEN_OPIVX_WIDEN_TRANS() to take a check function to avoid reimplementing
6
it.
6
7
7
Shuffle the alignment check to the front, because that does not
8
Signed-off-by: Dickon Hood <dickon.hood@codethink.co.uk>
8
depend on the zero-extend, and it keeps the register usage clear.
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Set base after each step of the address arithmetic instead of before.
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
10
11
Signed-off-by: Max Chou <max.chou@sifive.com>
11
Return the base register used from tcg_out_tlb_load, so as to
12
Message-ID: <20230711165917.2629866-7-max.chou@sifive.com>
12
keep that register choice localized to that function.
13
14
Reported-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-Id: <20221023233337.2846860-1-richard.henderson@linaro.org>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
14
---
21
tcg/riscv/tcg-target.c.inc | 39 +++++++++++++++++++++-----------------
15
target/riscv/insn_trans/trans_rvv.c.inc | 52 +++++++++++--------------
22
1 file changed, 22 insertions(+), 17 deletions(-)
16
1 file changed, 23 insertions(+), 29 deletions(-)
23
17
24
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
18
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
25
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
26
--- a/tcg/riscv/tcg-target.c.inc
20
--- a/target/riscv/insn_trans/trans_rvv.c.inc
27
+++ b/tcg/riscv/tcg-target.c.inc
21
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
28
@@ -XXX,XX +XXX,XX @@ static void tcg_out_goto(TCGContext *s, const tcg_insn_unit *target)
22
@@ -XXX,XX +XXX,XX @@ static bool opivx_widen_check(DisasContext *s, arg_rmrr *a)
29
tcg_debug_assert(ok);
23
vext_check_ds(s, a->rd, a->rs2, a->vm);
30
}
24
}
31
25
32
-static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
26
-static bool do_opivx_widen(DisasContext *s, arg_rmrr *a,
33
- TCGReg addrh, MemOpIdx oi,
27
- gen_helper_opivx *fn)
34
- tcg_insn_unit **label_ptr, bool is_load)
28
-{
35
+static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
29
- if (opivx_widen_check(s, a)) {
36
+ TCGReg addrh, MemOpIdx oi,
30
- return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
37
+ tcg_insn_unit **label_ptr, bool is_load)
31
- }
38
{
32
- return false;
39
MemOp opc = get_memop(oi);
33
-}
40
unsigned s_bits = opc & MO_SIZE;
34
-
41
@@ -XXX,XX +XXX,XX @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
35
-#define GEN_OPIVX_WIDEN_TRANS(NAME) \
42
addrl = TCG_REG_TMP0;
36
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
43
}
37
-{ \
44
tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_REG_TMP2, addrl);
38
- static gen_helper_opivx * const fns[3] = { \
45
+ return TCG_REG_TMP0;
39
- gen_helper_##NAME##_b, \
40
- gen_helper_##NAME##_h, \
41
- gen_helper_##NAME##_w \
42
- }; \
43
- return do_opivx_widen(s, a, fns[s->sew]); \
44
+#define GEN_OPIVX_WIDEN_TRANS(NAME, CHECK) \
45
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
46
+{ \
47
+ if (CHECK(s, a)) { \
48
+ static gen_helper_opivx * const fns[3] = { \
49
+ gen_helper_##NAME##_b, \
50
+ gen_helper_##NAME##_h, \
51
+ gen_helper_##NAME##_w \
52
+ }; \
53
+ return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s); \
54
+ } \
55
+ return false; \
46
}
56
}
47
57
48
static void add_qemu_ldst_label(TCGContext *s, int is_ld, MemOpIdx oi,
58
-GEN_OPIVX_WIDEN_TRANS(vwaddu_vx)
49
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
59
-GEN_OPIVX_WIDEN_TRANS(vwadd_vx)
50
#else
60
-GEN_OPIVX_WIDEN_TRANS(vwsubu_vx)
51
unsigned a_bits;
61
-GEN_OPIVX_WIDEN_TRANS(vwsub_vx)
52
#endif
62
+GEN_OPIVX_WIDEN_TRANS(vwaddu_vx, opivx_widen_check)
53
- TCGReg base = TCG_REG_TMP0;
63
+GEN_OPIVX_WIDEN_TRANS(vwadd_vx, opivx_widen_check)
54
+ TCGReg base;
64
+GEN_OPIVX_WIDEN_TRANS(vwsubu_vx, opivx_widen_check)
55
65
+GEN_OPIVX_WIDEN_TRANS(vwsub_vx, opivx_widen_check)
56
data_regl = *args++;
66
57
data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
67
/* WIDEN OPIVV with WIDEN */
58
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
68
static bool opiwv_widen_check(DisasContext *s, arg_rmrr *a)
59
opc = get_memop(oi);
69
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vrem_vx, opivx_check)
60
70
GEN_OPIVV_WIDEN_TRANS(vwmul_vv, opivv_widen_check)
61
#if defined(CONFIG_SOFTMMU)
71
GEN_OPIVV_WIDEN_TRANS(vwmulu_vv, opivv_widen_check)
62
- tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 1);
72
GEN_OPIVV_WIDEN_TRANS(vwmulsu_vv, opivv_widen_check)
63
+ base = tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 1);
73
-GEN_OPIVX_WIDEN_TRANS(vwmul_vx)
64
tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
74
-GEN_OPIVX_WIDEN_TRANS(vwmulu_vx)
65
add_qemu_ldst_label(s, 1, oi,
75
-GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx)
66
(is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
76
+GEN_OPIVX_WIDEN_TRANS(vwmul_vx, opivx_widen_check)
67
data_regl, data_regh, addr_regl, addr_regh,
77
+GEN_OPIVX_WIDEN_TRANS(vwmulu_vx, opivx_widen_check)
68
s->code_ptr, label_ptr);
78
+GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx, opivx_widen_check)
69
#else
79
70
- if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
80
/* Vector Single-Width Integer Multiply-Add Instructions */
71
- tcg_out_ext32u(s, base, addr_regl);
81
GEN_OPIVV_TRANS(vmacc_vv, opivv_check)
72
- addr_regl = base;
82
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vnmsub_vx, opivx_check)
73
- }
83
GEN_OPIVV_WIDEN_TRANS(vwmaccu_vv, opivv_widen_check)
74
a_bits = get_alignment_bits(opc);
84
GEN_OPIVV_WIDEN_TRANS(vwmacc_vv, opivv_widen_check)
75
if (a_bits) {
85
GEN_OPIVV_WIDEN_TRANS(vwmaccsu_vv, opivv_widen_check)
76
tcg_out_test_alignment(s, true, addr_regl, a_bits);
86
-GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx)
77
}
87
-GEN_OPIVX_WIDEN_TRANS(vwmacc_vx)
78
+ base = addr_regl;
88
-GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx)
79
+ if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
89
-GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx)
80
+ tcg_out_ext32u(s, TCG_REG_TMP0, base);
90
+GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx, opivx_widen_check)
81
+ base = TCG_REG_TMP0;
91
+GEN_OPIVX_WIDEN_TRANS(vwmacc_vx, opivx_widen_check)
82
+ }
92
+GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx, opivx_widen_check)
83
if (guest_base != 0) {
93
+GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx, opivx_widen_check)
84
- tcg_out_opc_reg(s, OPC_ADD, base, TCG_GUEST_BASE_REG, addr_regl);
94
85
+ tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_GUEST_BASE_REG, base);
95
/* Vector Integer Merge and Move Instructions */
86
+ base = TCG_REG_TMP0;
96
static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
87
}
88
tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
89
#endif
90
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
91
#else
92
unsigned a_bits;
93
#endif
94
- TCGReg base = TCG_REG_TMP0;
95
+ TCGReg base;
96
97
data_regl = *args++;
98
data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
99
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
100
opc = get_memop(oi);
101
102
#if defined(CONFIG_SOFTMMU)
103
- tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 0);
104
+ base = tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 0);
105
tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
106
add_qemu_ldst_label(s, 0, oi,
107
(is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
108
data_regl, data_regh, addr_regl, addr_regh,
109
s->code_ptr, label_ptr);
110
#else
111
- if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
112
- tcg_out_ext32u(s, base, addr_regl);
113
- addr_regl = base;
114
- }
115
a_bits = get_alignment_bits(opc);
116
if (a_bits) {
117
tcg_out_test_alignment(s, false, addr_regl, a_bits);
118
}
119
+ base = addr_regl;
120
+ if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
121
+ tcg_out_ext32u(s, TCG_REG_TMP0, base);
122
+ base = TCG_REG_TMP0;
123
+ }
124
if (guest_base != 0) {
125
- tcg_out_opc_reg(s, OPC_ADD, base, TCG_GUEST_BASE_REG, addr_regl);
126
+ tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_GUEST_BASE_REG, base);
127
+ base = TCG_REG_TMP0;
128
}
129
tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
130
#endif
131
--
97
--
132
2.38.1
98
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
H-mode has been removed since priv spec 1.10. Drop it.
3
Move some macros out of `vector_helper` and into `vector_internals`.
4
This ensures they can be used by both vector and vector-crypto helpers
5
(latter implemented in proceeding commits).
4
6
5
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
6
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
8
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Max Chou <max.chou@sifive.com>
8
Message-Id: <20221211030829.802437-6-bmeng@tinylab.org>
10
Message-ID: <20230711165917.2629866-8-max.chou@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
12
---
11
include/hw/intc/sifive_plic.h | 1 -
13
target/riscv/vector_internals.h | 46 +++++++++++++++++++++++++++++++++
12
hw/intc/sifive_plic.c | 1 -
14
target/riscv/vector_helper.c | 42 ------------------------------
13
2 files changed, 2 deletions(-)
15
2 files changed, 46 insertions(+), 42 deletions(-)
14
16
15
diff --git a/include/hw/intc/sifive_plic.h b/include/hw/intc/sifive_plic.h
17
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/intc/sifive_plic.h
19
--- a/target/riscv/vector_internals.h
18
+++ b/include/hw/intc/sifive_plic.h
20
+++ b/target/riscv/vector_internals.h
19
@@ -XXX,XX +XXX,XX @@ DECLARE_INSTANCE_CHECKER(SiFivePLICState, SIFIVE_PLIC,
21
@@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
20
typedef enum PLICMode {
22
/* expand macro args before macro */
21
PLICMode_U,
23
#define RVVCALL(macro, ...) macro(__VA_ARGS__)
22
PLICMode_S,
24
23
- PLICMode_H,
25
+/* (TD, T2, TX2) */
24
PLICMode_M
26
+#define OP_UU_B uint8_t, uint8_t, uint8_t
25
} PLICMode;
27
+#define OP_UU_H uint16_t, uint16_t, uint16_t
26
28
+#define OP_UU_W uint32_t, uint32_t, uint32_t
27
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
29
+#define OP_UU_D uint64_t, uint64_t, uint64_t
30
+
31
/* (TD, T1, T2, TX1, TX2) */
32
#define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
33
#define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t
34
#define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t
35
#define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t
36
37
+#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
38
+static void do_##NAME(void *vd, void *vs2, int i) \
39
+{ \
40
+ TX2 s2 = *((T2 *)vs2 + HS2(i)); \
41
+ *((TD *)vd + HD(i)) = OP(s2); \
42
+}
43
+
44
+#define GEN_VEXT_V(NAME, ESZ) \
45
+void HELPER(NAME)(void *vd, void *v0, void *vs2, \
46
+ CPURISCVState *env, uint32_t desc) \
47
+{ \
48
+ uint32_t vm = vext_vm(desc); \
49
+ uint32_t vl = env->vl; \
50
+ uint32_t total_elems = \
51
+ vext_get_total_elems(env, desc, ESZ); \
52
+ uint32_t vta = vext_vta(desc); \
53
+ uint32_t vma = vext_vma(desc); \
54
+ uint32_t i; \
55
+ \
56
+ for (i = env->vstart; i < vl; i++) { \
57
+ if (!vm && !vext_elem_mask(v0, i)) { \
58
+ /* set masked-off elements to 1s */ \
59
+ vext_set_elems_1s(vd, vma, i * ESZ, \
60
+ (i + 1) * ESZ); \
61
+ continue; \
62
+ } \
63
+ do_##NAME(vd, vs2, i); \
64
+ } \
65
+ env->vstart = 0; \
66
+ /* set tail elements to 1s */ \
67
+ vext_set_elems_1s(vd, vta, vl * ESZ, \
68
+ total_elems * ESZ); \
69
+}
70
+
71
/* operation of two vector elements */
72
typedef void opivv2_fn(void *vd, void *vs1, void *vs2, int i);
73
74
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
75
do_##NAME, ESZ); \
76
}
77
78
+/* Three of the widening shortening macros: */
79
+/* (TD, T1, T2, TX1, TX2) */
80
+#define WOP_UUU_B uint16_t, uint8_t, uint8_t, uint16_t, uint16_t
81
+#define WOP_UUU_H uint32_t, uint16_t, uint16_t, uint32_t, uint32_t
82
+#define WOP_UUU_W uint64_t, uint32_t, uint32_t, uint64_t, uint64_t
83
+
84
#endif /* TARGET_RISCV_VECTOR_INTERNALS_H */
85
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
28
index XXXXXXX..XXXXXXX 100644
86
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/intc/sifive_plic.c
87
--- a/target/riscv/vector_helper.c
30
+++ b/hw/intc/sifive_plic.c
88
+++ b/target/riscv/vector_helper.c
31
@@ -XXX,XX +XXX,XX @@ static PLICMode char_to_mode(char c)
89
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
32
switch (c) {
90
#define OP_SUS_H int16_t, uint16_t, int16_t, uint16_t, int16_t
33
case 'U': return PLICMode_U;
91
#define OP_SUS_W int32_t, uint32_t, int32_t, uint32_t, int32_t
34
case 'S': return PLICMode_S;
92
#define OP_SUS_D int64_t, uint64_t, int64_t, uint64_t, int64_t
35
- case 'H': return PLICMode_H;
93
-#define WOP_UUU_B uint16_t, uint8_t, uint8_t, uint16_t, uint16_t
36
case 'M': return PLICMode_M;
94
-#define WOP_UUU_H uint32_t, uint16_t, uint16_t, uint32_t, uint32_t
37
default:
95
-#define WOP_UUU_W uint64_t, uint32_t, uint32_t, uint64_t, uint64_t
38
error_report("plic: invalid mode '%c'", c);
96
#define WOP_SSS_B int16_t, int8_t, int8_t, int16_t, int16_t
97
#define WOP_SSS_H int32_t, int16_t, int16_t, int32_t, int32_t
98
#define WOP_SSS_W int64_t, int32_t, int32_t, int64_t, int64_t
99
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_VF(vfwnmsac_vf_h, 4)
100
GEN_VEXT_VF(vfwnmsac_vf_w, 8)
101
102
/* Vector Floating-Point Square-Root Instruction */
103
-/* (TD, T2, TX2) */
104
-#define OP_UU_H uint16_t, uint16_t, uint16_t
105
-#define OP_UU_W uint32_t, uint32_t, uint32_t
106
-#define OP_UU_D uint64_t, uint64_t, uint64_t
107
-
108
#define OPFVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
109
static void do_##NAME(void *vd, void *vs2, int i, \
110
CPURISCVState *env) \
111
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_CMP_VF(vmfge_vf_w, uint32_t, H4, vmfge32)
112
GEN_VEXT_CMP_VF(vmfge_vf_d, uint64_t, H8, vmfge64)
113
114
/* Vector Floating-Point Classify Instruction */
115
-#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
116
-static void do_##NAME(void *vd, void *vs2, int i) \
117
-{ \
118
- TX2 s2 = *((T2 *)vs2 + HS2(i)); \
119
- *((TD *)vd + HD(i)) = OP(s2); \
120
-}
121
-
122
-#define GEN_VEXT_V(NAME, ESZ) \
123
-void HELPER(NAME)(void *vd, void *v0, void *vs2, \
124
- CPURISCVState *env, uint32_t desc) \
125
-{ \
126
- uint32_t vm = vext_vm(desc); \
127
- uint32_t vl = env->vl; \
128
- uint32_t total_elems = \
129
- vext_get_total_elems(env, desc, ESZ); \
130
- uint32_t vta = vext_vta(desc); \
131
- uint32_t vma = vext_vma(desc); \
132
- uint32_t i; \
133
- \
134
- for (i = env->vstart; i < vl; i++) { \
135
- if (!vm && !vext_elem_mask(v0, i)) { \
136
- /* set masked-off elements to 1s */ \
137
- vext_set_elems_1s(vd, vma, i * ESZ, \
138
- (i + 1) * ESZ); \
139
- continue; \
140
- } \
141
- do_##NAME(vd, vs2, i); \
142
- } \
143
- env->vstart = 0; \
144
- /* set tail elements to 1s */ \
145
- vext_set_elems_1s(vd, vta, vl * ESZ, \
146
- total_elems * ESZ); \
147
-}
148
-
149
target_ulong fclass_h(uint64_t frs1)
150
{
151
float16 f = frs1;
39
--
152
--
40
2.38.1
153
2.41.0
diff view generated by jsdifflib
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
From: Dickon Hood <dickon.hood@codethink.co.uk>
2
2
3
When icount is not enabled, there is no API in QEMU that can get the
3
This commit adds support for the Zvbb vector-crypto extension, which
4
guest instruction number.
4
consists of the following instructions:
5
5
6
Translate the guest code in a way that each TB only has one instruction.
6
* vrol.[vv,vx]
7
After executing the instruction, decrease the count by 1 until it reaches 0
7
* vror.[vv,vx,vi]
8
where the itrigger fires.
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]
9
16
10
Note that only when priviledge matches the itrigger configuration,
17
Translation functions are defined in
11
the count will decrease.
18
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
19
`target/riscv/vcrypto_helper.c`.
12
20
13
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
21
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
22
Co-authored-by: William Salmon <will.salmon@codethink.co.uk>
15
Message-Id: <20221013062946.7530-2-zhiwei_liu@linux.alibaba.com>
23
Co-authored-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
24
[max.chou@sifive.com: Fix imm mode of vror.vi]
25
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
26
Signed-off-by: William Salmon <will.salmon@codethink.co.uk>
27
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
28
Signed-off-by: Dickon Hood <dickon.hood@codethink.co.uk>
29
Signed-off-by: Max Chou <max.chou@sifive.com>
30
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
31
[max.chou@sifive.com: Exposed x-zvbb property]
32
Message-ID: <20230711165917.2629866-9-max.chou@sifive.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
34
---
18
target/riscv/cpu.h | 2 +
35
target/riscv/cpu_cfg.h | 1 +
19
target/riscv/debug.h | 12 ++++
36
target/riscv/helper.h | 62 +++++++++
20
target/riscv/helper.h | 2 +
37
target/riscv/insn32.decode | 20 +++
21
target/riscv/cpu_helper.c | 6 ++
38
target/riscv/cpu.c | 12 ++
22
target/riscv/debug.c | 71 +++++++++++++++++++
39
target/riscv/vcrypto_helper.c | 138 +++++++++++++++++++
23
target/riscv/translate.c | 33 ++++++++-
40
target/riscv/insn_trans/trans_rvvk.c.inc | 164 +++++++++++++++++++++++
24
.../riscv/insn_trans/trans_privileged.c.inc | 4 +-
41
6 files changed, 397 insertions(+)
25
target/riscv/insn_trans/trans_rvi.c.inc | 8 +--
26
target/riscv/insn_trans/trans_rvv.c.inc | 4 +-
27
9 files changed, 131 insertions(+), 11 deletions(-)
28
42
29
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
43
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
30
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/cpu.h
45
--- a/target/riscv/cpu_cfg.h
32
+++ b/target/riscv/cpu.h
46
+++ b/target/riscv/cpu_cfg.h
33
@@ -XXX,XX +XXX,XX @@ FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
47
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
34
FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
48
bool ext_zve32f;
35
FIELD(TB_FLAGS, VTA, 24, 1)
49
bool ext_zve64f;
36
FIELD(TB_FLAGS, VMA, 25, 1)
50
bool ext_zve64d;
37
+/* Native debug itrigger */
51
+ bool ext_zvbb;
38
+FIELD(TB_FLAGS, ITRIGGER, 26, 1)
52
bool ext_zvbc;
39
53
bool ext_zmmul;
40
#ifdef TARGET_RISCV32
54
bool ext_zvfbfmin;
41
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
42
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/riscv/debug.h
45
+++ b/target/riscv/debug.h
46
@@ -XXX,XX +XXX,XX @@ enum {
47
SIZE_NUM = 16
48
};
49
50
+/* itrigger filed masks */
51
+#define ITRIGGER_ACTION 0x3f
52
+#define ITRIGGER_U BIT(6)
53
+#define ITRIGGER_S BIT(7)
54
+#define ITRIGGER_PENDING BIT(8)
55
+#define ITRIGGER_M BIT(9)
56
+#define ITRIGGER_COUNT (0x3fff << 10)
57
+#define ITRIGGER_HIT BIT(24)
58
+#define ITRIGGER_VU BIT(25)
59
+#define ITRIGGER_VS BIT(26)
60
+
61
bool tdata_available(CPURISCVState *env, int tdata_index);
62
63
target_ulong tselect_csr_read(CPURISCVState *env);
64
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
65
66
void riscv_trigger_init(CPURISCVState *env);
67
68
+bool riscv_itrigger_enabled(CPURISCVState *env);
69
#endif /* RISCV_DEBUG_H */
70
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
55
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
71
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
72
--- a/target/riscv/helper.h
57
--- a/target/riscv/helper.h
73
+++ b/target/riscv/helper.h
58
+++ b/target/riscv/helper.h
74
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(sret, tl, env)
59
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
75
DEF_HELPER_1(mret, tl, env)
60
DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
76
DEF_HELPER_1(wfi, void, env)
61
DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
77
DEF_HELPER_1(tlb_flush, void, env)
62
DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
78
+/* Native Debug */
63
+
79
+DEF_HELPER_1(itrigger_match, void, env)
64
+DEF_HELPER_6(vror_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
80
#endif
65
+DEF_HELPER_6(vror_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
81
66
+DEF_HELPER_6(vror_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
82
/* Hypervisor functions */
67
+DEF_HELPER_6(vror_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
83
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
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
84
index XXXXXXX..XXXXXXX 100644
126
index XXXXXXX..XXXXXXX 100644
85
--- a/target/riscv/cpu_helper.c
127
--- a/target/riscv/insn32.decode
86
+++ b/target/riscv/cpu_helper.c
128
+++ b/target/riscv/insn32.decode
87
@@ -XXX,XX +XXX,XX @@
129
@@ -XXX,XX +XXX,XX @@
88
#include "tcg/tcg-op.h"
130
%imm_u 12:s20 !function=ex_shift_12
89
#include "trace.h"
131
%imm_bs 30:2 !function=ex_shift_3
90
#include "semihosting/common-semi.h"
132
%imm_rnum 20:4
91
+#include "sysemu/cpu-timers.h"
133
+%imm_z6 26:1 15:5
92
#include "cpu_bits.h"
134
93
+#include "debug.h"
135
# Argument sets:
94
136
&empty
95
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
137
@@ -XXX,XX +XXX,XX @@
96
{
138
@r_vm ...... vm:1 ..... ..... ... ..... ....... &rmrr %rs2 %rs1 %rd
97
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
139
@r_vm_1 ...... . ..... ..... ... ..... ....... &rmrr vm=1 %rs2 %rs1 %rd
98
flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
140
@r_vm_0 ...... . ..... ..... ... ..... ....... &rmrr vm=0 %rs2 %rs1 %rd
99
get_field(env->mstatus_hs, MSTATUS_VS));
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
167
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
168
index XXXXXXX..XXXXXXX 100644
169
--- a/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),
179
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
180
return;
100
}
181
}
101
+ if (riscv_feature(env, RISCV_FEATURE_DEBUG) && !icount_enabled()) {
182
102
+ flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER,
183
+ /*
103
+ riscv_itrigger_enabled(env));
184
+ * In principle Zve*x would also suffice here, were they supported
104
+ }
185
+ * in qemu
105
#endif
186
+ */
106
187
+ if (cpu->cfg.ext_zvbb && !cpu->cfg.ext_zve32f) {
107
flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
188
+ error_setg(errp,
108
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
189
+ "Vector crypto extensions require V or Zve* extensions");
190
+ return;
191
+ }
192
+
193
if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
194
error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
195
return;
196
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
197
DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
198
199
/* Vector cryptography extensions */
200
+ DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
201
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
202
203
DEFINE_PROP_END_OF_LIST(),
204
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
109
index XXXXXXX..XXXXXXX 100644
205
index XXXXXXX..XXXXXXX 100644
110
--- a/target/riscv/debug.c
206
--- a/target/riscv/vcrypto_helper.c
111
+++ b/target/riscv/debug.c
207
+++ b/target/riscv/vcrypto_helper.c
112
@@ -XXX,XX +XXX,XX @@
208
@@ -XXX,XX +XXX,XX @@
209
#include "qemu/osdep.h"
210
#include "qemu/host-utils.h"
211
#include "qemu/bitops.h"
212
+#include "qemu/bswap.h"
113
#include "cpu.h"
213
#include "cpu.h"
114
#include "trace.h"
214
#include "exec/memop.h"
115
#include "exec/exec-all.h"
215
#include "exec/exec-all.h"
116
+#include "exec/helper-proto.h"
216
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64)
117
217
GEN_VEXT_VV(vclmulh_vv, 8)
118
/*
218
RVVCALL(OPIVX2, vclmulh_vx, OP_UUU_D, H8, H8, clmulh64)
119
* The following M-mode trigger CSRs are implemented:
219
GEN_VEXT_VX(vclmulh_vx, 8)
120
@@ -XXX,XX +XXX,XX @@ static void type6_reg_write(CPURISCVState *env, target_ulong index,
220
+
121
return;
221
+RVVCALL(OPIVV2, vror_vv_b, OP_UUU_B, H1, H1, H1, ror8)
122
}
222
+RVVCALL(OPIVV2, vror_vv_h, OP_UUU_H, H2, H2, H2, ror16)
123
223
+RVVCALL(OPIVV2, vror_vv_w, OP_UUU_W, H4, H4, H4, ror32)
124
+/* icount trigger type */
224
+RVVCALL(OPIVV2, vror_vv_d, OP_UUU_D, H8, H8, H8, ror64)
125
+static inline int
225
+GEN_VEXT_VV(vror_vv_b, 1)
126
+itrigger_get_count(CPURISCVState *env, int index)
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)
127
+{
258
+{
128
+ return get_field(env->tdata1[index], ITRIGGER_COUNT);
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;
129
+}
267
+}
130
+
268
+
131
+static inline void
269
+RVVCALL(OPIVV1, vbrev8_v_b, OP_UU_B, H1, H1, brev8)
132
+itrigger_set_count(CPURISCVState *env, int index, int value)
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)
133
+{
418
+{
134
+ env->tdata1[index] = set_field(env->tdata1[index],
419
+ return opivv_check(s, a) && s->cfg_ptr->ext_zvbb == true;
135
+ ITRIGGER_COUNT, value);
136
+}
420
+}
137
+
421
+
138
+static bool check_itrigger_priv(CPURISCVState *env, int index)
422
+static bool zvbb_vx_check(DisasContext *s, arg_rmrr *a)
139
+{
423
+{
140
+ target_ulong tdata1 = env->tdata1[index];
424
+ return opivx_check(s, a) && s->cfg_ptr->ext_zvbb == true;
141
+ if (riscv_cpu_virt_enabled(env)) {
142
+ /* check VU/VS bit against current privilege level */
143
+ return (get_field(tdata1, ITRIGGER_VS) == env->priv) ||
144
+ (get_field(tdata1, ITRIGGER_VU) == env->priv);
145
+ } else {
146
+ /* check U/S/M bit against current privilege level */
147
+ return (get_field(tdata1, ITRIGGER_M) == env->priv) ||
148
+ (get_field(tdata1, ITRIGGER_S) == env->priv) ||
149
+ (get_field(tdata1, ITRIGGER_U) == env->priv);
150
+ }
151
+}
425
+}
152
+
426
+
153
+bool riscv_itrigger_enabled(CPURISCVState *env)
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)
154
+{
486
+{
155
+ int count;
487
+ return s->cfg_ptr->ext_zvbb == true &&
156
+ for (int i = 0; i < RV_MAX_TRIGGERS; i++) {
488
+ require_rvv(s) &&
157
+ if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) {
489
+ vext_check_isa_ill(s) &&
158
+ continue;
490
+ vext_check_ss(s, a->rd, a->rs2, a->vm);
159
+ }
160
+ if (check_itrigger_priv(env, i)) {
161
+ continue;
162
+ }
163
+ count = itrigger_get_count(env, i);
164
+ if (!count) {
165
+ continue;
166
+ }
167
+ return true;
168
+ }
169
+
170
+ return false;
171
+}
491
+}
172
+
492
+
173
+void helper_itrigger_match(CPURISCVState *env)
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)
174
+{
501
+{
175
+ int count;
502
+ return s->cfg_ptr->ext_zvbb && opivv_widen_check(s, a);
176
+ for (int i = 0; i < RV_MAX_TRIGGERS; i++) {
177
+ if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) {
178
+ continue;
179
+ }
180
+ if (check_itrigger_priv(env, i)) {
181
+ continue;
182
+ }
183
+ count = itrigger_get_count(env, i);
184
+ if (!count) {
185
+ continue;
186
+ }
187
+ itrigger_set_count(env, i, count--);
188
+ if (!count) {
189
+ do_trigger_action(env, i);
190
+ }
191
+ }
192
+}
503
+}
193
+
504
+
194
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
505
+static bool vwsll_vx_check(DisasContext *s, arg_rmrr *a)
195
{
196
switch (tdata_index) {
197
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
198
index XXXXXXX..XXXXXXX 100644
199
--- a/target/riscv/translate.c
200
+++ b/target/riscv/translate.c
201
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
202
/* PointerMasking extension */
203
bool pm_mask_enabled;
204
bool pm_base_enabled;
205
+ /* Use icount trigger for native debug */
206
+ bool itrigger;
207
/* TCG of the current insn_start */
208
TCGOp *insn_start;
209
} DisasContext;
210
@@ -XXX,XX +XXX,XX @@ static void gen_exception_inst_addr_mis(DisasContext *ctx)
211
generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
212
}
213
214
+static void lookup_and_goto_ptr(DisasContext *ctx)
215
+{
506
+{
216
+#ifndef CONFIG_USER_ONLY
507
+ return s->cfg_ptr->ext_zvbb && opivx_widen_check(s, a);
217
+ if (ctx->itrigger) {
218
+ gen_helper_itrigger_match(cpu_env);
219
+ }
220
+#endif
221
+ tcg_gen_lookup_and_goto_ptr();
222
+}
508
+}
223
+
509
+
224
+static void exit_tb(DisasContext *ctx)
510
+/* OPIVI without GVEC IR */
225
+{
511
+#define GEN_OPIVI_WIDEN_TRANS(NAME, IMM_MODE, OPIVX, CHECK) \
226
+#ifndef CONFIG_USER_ONLY
512
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
227
+ if (ctx->itrigger) {
513
+ { \
228
+ gen_helper_itrigger_match(cpu_env);
514
+ if (CHECK(s, a)) { \
229
+ }
515
+ static gen_helper_opivx *const fns[3] = { \
230
+#endif
516
+ gen_helper_##OPIVX##_b, \
231
+ tcg_gen_exit_tb(NULL, 0);
517
+ gen_helper_##OPIVX##_h, \
232
+}
518
+ gen_helper_##OPIVX##_w, \
233
+
519
+ }; \
234
static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
520
+ return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s, \
235
{
521
+ IMM_MODE); \
236
- if (translator_use_goto_tb(&ctx->base, dest)) {
522
+ } \
237
+ /*
523
+ return false; \
238
+ * Under itrigger, instruction executes one by one like singlestep,
524
+ }
239
+ * direct block chain benefits will be small.
525
+
240
+ */
526
+GEN_OPIVV_WIDEN_TRANS(vwsll_vv, vwsll_vv_check)
241
+ if (translator_use_goto_tb(&ctx->base, dest) && !ctx->itrigger) {
527
+GEN_OPIVX_WIDEN_TRANS(vwsll_vx, vwsll_vx_check)
242
tcg_gen_goto_tb(n);
528
+GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
243
gen_set_pc_imm(ctx, dest);
244
tcg_gen_exit_tb(ctx->base.tb, n);
245
} else {
246
gen_set_pc_imm(ctx, dest);
247
- tcg_gen_lookup_and_goto_ptr();
248
+ lookup_and_goto_ptr(ctx);
249
}
250
}
251
252
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
253
memset(ctx->ftemp, 0, sizeof(ctx->ftemp));
254
ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
255
ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
256
+ ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
257
ctx->zero = tcg_constant_tl(0);
258
}
259
260
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
261
262
/* Only the first insn within a TB is allowed to cross a page boundary. */
263
if (ctx->base.is_jmp == DISAS_NEXT) {
264
- if (!is_same_page(&ctx->base, ctx->base.pc_next)) {
265
+ if (ctx->itrigger || !is_same_page(&ctx->base, ctx->base.pc_next)) {
266
ctx->base.is_jmp = DISAS_TOO_MANY;
267
} else {
268
unsigned page_ofs = ctx->base.pc_next & ~TARGET_PAGE_MASK;
269
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
270
index XXXXXXX..XXXXXXX 100644
271
--- a/target/riscv/insn_trans/trans_privileged.c.inc
272
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
273
@@ -XXX,XX +XXX,XX @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
274
if (has_ext(ctx, RVS)) {
275
decode_save_opc(ctx);
276
gen_helper_sret(cpu_pc, cpu_env);
277
- tcg_gen_exit_tb(NULL, 0); /* no chaining */
278
+ exit_tb(ctx); /* no chaining */
279
ctx->base.is_jmp = DISAS_NORETURN;
280
} else {
281
return false;
282
@@ -XXX,XX +XXX,XX @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
283
#ifndef CONFIG_USER_ONLY
284
decode_save_opc(ctx);
285
gen_helper_mret(cpu_pc, cpu_env);
286
- tcg_gen_exit_tb(NULL, 0); /* no chaining */
287
+ exit_tb(ctx); /* no chaining */
288
ctx->base.is_jmp = DISAS_NORETURN;
289
return true;
290
#else
291
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
292
index XXXXXXX..XXXXXXX 100644
293
--- a/target/riscv/insn_trans/trans_rvi.c.inc
294
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
295
@@ -XXX,XX +XXX,XX @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
296
}
297
298
gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
299
- tcg_gen_lookup_and_goto_ptr();
300
+ lookup_and_goto_ptr(ctx);
301
302
if (misaligned) {
303
gen_set_label(misaligned);
304
@@ -XXX,XX +XXX,XX @@ static bool trans_pause(DisasContext *ctx, arg_pause *a)
305
* end the TB and return to main loop
306
*/
307
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
308
- tcg_gen_exit_tb(NULL, 0);
309
+ exit_tb(ctx);
310
ctx->base.is_jmp = DISAS_NORETURN;
311
312
return true;
313
@@ -XXX,XX +XXX,XX @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
314
* however we need to end the translation block
315
*/
316
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
317
- tcg_gen_exit_tb(NULL, 0);
318
+ exit_tb(ctx);
319
ctx->base.is_jmp = DISAS_NORETURN;
320
return true;
321
}
322
@@ -XXX,XX +XXX,XX @@ static bool do_csr_post(DisasContext *ctx)
323
decode_save_opc(ctx);
324
/* We may have changed important cpu state -- exit to main loop. */
325
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
326
- tcg_gen_exit_tb(NULL, 0);
327
+ exit_tb(ctx);
328
ctx->base.is_jmp = DISAS_NORETURN;
329
return true;
330
}
331
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
332
index XXXXXXX..XXXXXXX 100644
333
--- a/target/riscv/insn_trans/trans_rvv.c.inc
334
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
335
@@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
336
mark_vs_dirty(s);
337
338
gen_set_pc_imm(s, s->pc_succ_insn);
339
- tcg_gen_lookup_and_goto_ptr();
340
+ lookup_and_goto_ptr(s);
341
s->base.is_jmp = DISAS_NORETURN;
342
343
if (rd == 0 && rs1 == 0) {
344
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
345
gen_set_gpr(s, rd, dst);
346
mark_vs_dirty(s);
347
gen_set_pc_imm(s, s->pc_succ_insn);
348
- tcg_gen_lookup_and_goto_ptr();
349
+ lookup_and_goto_ptr(s);
350
s->base.is_jmp = DISAS_NORETURN;
351
352
return true;
353
--
529
--
354
2.38.1
530
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
PLIC is not included in the 'spike' machine.
3
This commit adds support for the Zvkned vector-crypto extension, which
4
consists of the following instructions:
4
5
5
Signed-off-by: Bin Meng <bmeng@tinylab.org>
6
* vaesef.[vv,vs]
6
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
7
* vaesdf.[vv,vs]
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
* vaesdm.[vv,vs]
8
Message-Id: <20221211030829.802437-5-bmeng@tinylab.org>
9
* vaesz.vs
10
* vaesem.[vv,vs]
11
* vaeskf1.vi
12
* vaeskf2.vi
13
14
Translation functions are defined in
15
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
16
`target/riscv/vcrypto_helper.c`.
17
18
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
19
Co-authored-by: William Salmon <will.salmon@codethink.co.uk>
20
[max.chou@sifive.com: Replaced vstart checking by TCG op]
21
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
22
Signed-off-by: William Salmon <will.salmon@codethink.co.uk>
23
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
24
Signed-off-by: Max Chou <max.chou@sifive.com>
25
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
26
[max.chou@sifive.com: Imported aes-round.h and exposed x-zvkned
27
property]
28
[max.chou@sifive.com: Fixed endian issues and replaced the vstart & vl
29
egs checking by helper function]
30
[max.chou@sifive.com: Replaced bswap32 calls in aes key expanding]
31
Message-ID: <20230711165917.2629866-10-max.chou@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
32
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
33
---
11
hw/riscv/spike.c | 1 -
34
target/riscv/cpu_cfg.h | 1 +
12
1 file changed, 1 deletion(-)
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(-)
13
41
14
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
42
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
15
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/spike.c
44
--- a/target/riscv/cpu_cfg.h
17
+++ b/hw/riscv/spike.c
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
18
@@ -XXX,XX +XXX,XX @@
80
@@ -XXX,XX +XXX,XX @@
19
*
81
@r_rm ....... ..... ..... ... ..... ....... %rs2 %rs1 %rm %rd
20
* 0) HTIF Console and Poweroff
82
@r2_rm ....... ..... ..... ... ..... ....... %rs1 %rm %rd
21
* 1) CLINT (Timer and IPI)
83
@r2 ....... ..... ..... ... ..... ....... &r2 %rs1 %rd
22
- * 2) PLIC (Platform Level Interrupt Controller)
84
+@r2_vm_1 ...... . ..... ..... ... ..... ....... &rmr vm=1 %rs2 %rd
23
*
85
@r2_nfvm ... ... vm:1 ..... ..... ... ..... ....... &r2nfvm %nf %rs1 %rd
24
* This program is free software; you can redistribute it and/or modify it
86
@r2_vm ...... vm:1 ..... ..... ... ..... ....... &rmr %rs2 %rd
25
* under the terms and conditions of the GNU General Public License,
87
@r1_vm ...... vm:1 ..... ..... ... ..... ....... %rd
88
@@ -XXX,XX +XXX,XX @@ vcpop_v 010010 . ..... 01110 010 ..... 1010111 @r2_vm
89
vwsll_vv 110101 . ..... ..... 000 ..... 1010111 @r_vm
90
vwsll_vx 110101 . ..... ..... 100 ..... 1010111 @r_vm
91
vwsll_vi 110101 . ..... ..... 011 ..... 1010111 @r_vm
92
+
93
+# *** Zvkned vector crypto extension ***
94
+vaesef_vv 101000 1 ..... 00011 010 ..... 1110111 @r2_vm_1
95
+vaesef_vs 101001 1 ..... 00011 010 ..... 1110111 @r2_vm_1
96
+vaesdf_vv 101000 1 ..... 00001 010 ..... 1110111 @r2_vm_1
97
+vaesdf_vs 101001 1 ..... 00001 010 ..... 1110111 @r2_vm_1
98
+vaesem_vv 101000 1 ..... 00010 010 ..... 1110111 @r2_vm_1
99
+vaesem_vs 101001 1 ..... 00010 010 ..... 1110111 @r2_vm_1
100
+vaesdm_vv 101000 1 ..... 00000 010 ..... 1110111 @r2_vm_1
101
+vaesdm_vs 101001 1 ..... 00000 010 ..... 1110111 @r2_vm_1
102
+vaesz_vs 101001 1 ..... 00111 010 ..... 1110111 @r2_vm_1
103
+vaeskf1_vi 100010 1 ..... ..... 010 ..... 1110111 @r_vm_1
104
+vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1
105
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/riscv/cpu.c
108
+++ b/target/riscv/cpu.c
109
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
110
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
111
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
112
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
113
+ ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
114
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
115
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
116
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
117
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
118
* In principle Zve*x would also suffice here, were they supported
119
* in qemu
120
*/
121
- if (cpu->cfg.ext_zvbb && !cpu->cfg.ext_zve32f) {
122
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) && !cpu->cfg.ext_zve32f) {
123
error_setg(errp,
124
"Vector crypto extensions require V or Zve* extensions");
125
return;
126
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
127
/* Vector cryptography extensions */
128
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
129
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
130
+ DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
131
132
DEFINE_PROP_END_OF_LIST(),
133
};
134
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
135
index XXXXXXX..XXXXXXX 100644
136
--- a/target/riscv/vcrypto_helper.c
137
+++ b/target/riscv/vcrypto_helper.c
138
@@ -XXX,XX +XXX,XX @@
139
#include "qemu/bitops.h"
140
#include "qemu/bswap.h"
141
#include "cpu.h"
142
+#include "crypto/aes.h"
143
+#include "crypto/aes-round.h"
144
#include "exec/memop.h"
145
#include "exec/exec-all.h"
146
#include "exec/helper-proto.h"
147
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVX2, vwsll_vx_w, WOP_UUU_W, H8, H4, DO_SLL)
148
GEN_VEXT_VX(vwsll_vx_b, 2)
149
GEN_VEXT_VX(vwsll_vx_h, 4)
150
GEN_VEXT_VX(vwsll_vx_w, 8)
151
+
152
+void HELPER(egs_check)(uint32_t egs, CPURISCVState *env)
153
+{
154
+ uint32_t vl = env->vl;
155
+ uint32_t vstart = env->vstart;
156
+
157
+ if (vl % egs != 0 || vstart % egs != 0) {
158
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
159
+ }
160
+}
161
+
162
+static inline void xor_round_key(AESState *round_state, AESState *round_key)
163
+{
164
+ round_state->v = round_state->v ^ round_key->v;
165
+}
166
+
167
+#define GEN_ZVKNED_HELPER_VV(NAME, ...) \
168
+ void HELPER(NAME)(void *vd, void *vs2, CPURISCVState *env, \
169
+ uint32_t desc) \
170
+ { \
171
+ uint32_t vl = env->vl; \
172
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4); \
173
+ uint32_t vta = vext_vta(desc); \
174
+ \
175
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \
176
+ AESState round_key; \
177
+ round_key.d[0] = *((uint64_t *)vs2 + H8(i * 2 + 0)); \
178
+ round_key.d[1] = *((uint64_t *)vs2 + H8(i * 2 + 1)); \
179
+ AESState round_state; \
180
+ round_state.d[0] = *((uint64_t *)vd + H8(i * 2 + 0)); \
181
+ round_state.d[1] = *((uint64_t *)vd + H8(i * 2 + 1)); \
182
+ __VA_ARGS__; \
183
+ *((uint64_t *)vd + H8(i * 2 + 0)) = round_state.d[0]; \
184
+ *((uint64_t *)vd + H8(i * 2 + 1)) = round_state.d[1]; \
185
+ } \
186
+ env->vstart = 0; \
187
+ /* set tail elements to 1s */ \
188
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4); \
189
+ }
190
+
191
+#define GEN_ZVKNED_HELPER_VS(NAME, ...) \
192
+ void HELPER(NAME)(void *vd, void *vs2, CPURISCVState *env, \
193
+ uint32_t desc) \
194
+ { \
195
+ uint32_t vl = env->vl; \
196
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4); \
197
+ uint32_t vta = vext_vta(desc); \
198
+ \
199
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) { \
200
+ AESState round_key; \
201
+ round_key.d[0] = *((uint64_t *)vs2 + H8(0)); \
202
+ round_key.d[1] = *((uint64_t *)vs2 + H8(1)); \
203
+ AESState round_state; \
204
+ round_state.d[0] = *((uint64_t *)vd + H8(i * 2 + 0)); \
205
+ round_state.d[1] = *((uint64_t *)vd + H8(i * 2 + 1)); \
206
+ __VA_ARGS__; \
207
+ *((uint64_t *)vd + H8(i * 2 + 0)) = round_state.d[0]; \
208
+ *((uint64_t *)vd + H8(i * 2 + 1)) = round_state.d[1]; \
209
+ } \
210
+ env->vstart = 0; \
211
+ /* set tail elements to 1s */ \
212
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4); \
213
+ }
214
+
215
+GEN_ZVKNED_HELPER_VV(vaesef_vv, aesenc_SB_SR_AK(&round_state,
216
+ &round_state,
217
+ &round_key,
218
+ false);)
219
+GEN_ZVKNED_HELPER_VS(vaesef_vs, aesenc_SB_SR_AK(&round_state,
220
+ &round_state,
221
+ &round_key,
222
+ false);)
223
+GEN_ZVKNED_HELPER_VV(vaesdf_vv, aesdec_ISB_ISR_AK(&round_state,
224
+ &round_state,
225
+ &round_key,
226
+ false);)
227
+GEN_ZVKNED_HELPER_VS(vaesdf_vs, aesdec_ISB_ISR_AK(&round_state,
228
+ &round_state,
229
+ &round_key,
230
+ false);)
231
+GEN_ZVKNED_HELPER_VV(vaesem_vv, aesenc_SB_SR_MC_AK(&round_state,
232
+ &round_state,
233
+ &round_key,
234
+ false);)
235
+GEN_ZVKNED_HELPER_VS(vaesem_vs, aesenc_SB_SR_MC_AK(&round_state,
236
+ &round_state,
237
+ &round_key,
238
+ false);)
239
+GEN_ZVKNED_HELPER_VV(vaesdm_vv, aesdec_ISB_ISR_AK_IMC(&round_state,
240
+ &round_state,
241
+ &round_key,
242
+ false);)
243
+GEN_ZVKNED_HELPER_VS(vaesdm_vs, aesdec_ISB_ISR_AK_IMC(&round_state,
244
+ &round_state,
245
+ &round_key,
246
+ false);)
247
+GEN_ZVKNED_HELPER_VS(vaesz_vs, xor_round_key(&round_state, &round_key);)
248
+
249
+void HELPER(vaeskf1_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
250
+ CPURISCVState *env, uint32_t desc)
251
+{
252
+ uint32_t *vd = vd_vptr;
253
+ uint32_t *vs2 = vs2_vptr;
254
+ uint32_t vl = env->vl;
255
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
256
+ uint32_t vta = vext_vta(desc);
257
+
258
+ uimm &= 0b1111;
259
+ if (uimm > 10 || uimm == 0) {
260
+ uimm ^= 0b1000;
261
+ }
262
+
263
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
264
+ uint32_t rk[8], tmp;
265
+ static const uint32_t rcon[] = {
266
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
267
+ 0x00000020, 0x00000040, 0x00000080, 0x0000001B, 0x00000036,
268
+ };
269
+
270
+ rk[0] = vs2[i * 4 + H4(0)];
271
+ rk[1] = vs2[i * 4 + H4(1)];
272
+ rk[2] = vs2[i * 4 + H4(2)];
273
+ rk[3] = vs2[i * 4 + H4(3)];
274
+ tmp = ror32(rk[3], 8);
275
+
276
+ rk[4] = rk[0] ^ (((uint32_t)AES_sbox[(tmp >> 24) & 0xff] << 24) |
277
+ ((uint32_t)AES_sbox[(tmp >> 16) & 0xff] << 16) |
278
+ ((uint32_t)AES_sbox[(tmp >> 8) & 0xff] << 8) |
279
+ ((uint32_t)AES_sbox[(tmp >> 0) & 0xff] << 0))
280
+ ^ rcon[uimm - 1];
281
+ rk[5] = rk[1] ^ rk[4];
282
+ rk[6] = rk[2] ^ rk[5];
283
+ rk[7] = rk[3] ^ rk[6];
284
+
285
+ vd[i * 4 + H4(0)] = rk[4];
286
+ vd[i * 4 + H4(1)] = rk[5];
287
+ vd[i * 4 + H4(2)] = rk[6];
288
+ vd[i * 4 + H4(3)] = rk[7];
289
+ }
290
+ env->vstart = 0;
291
+ /* set tail elements to 1s */
292
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
293
+}
294
+
295
+void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
296
+ CPURISCVState *env, uint32_t desc)
297
+{
298
+ uint32_t *vd = vd_vptr;
299
+ uint32_t *vs2 = vs2_vptr;
300
+ uint32_t vl = env->vl;
301
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
302
+ uint32_t vta = vext_vta(desc);
303
+
304
+ uimm &= 0b1111;
305
+ if (uimm > 14 || uimm < 2) {
306
+ uimm ^= 0b1000;
307
+ }
308
+
309
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
310
+ uint32_t rk[12], tmp;
311
+ static const uint32_t rcon[] = {
312
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
313
+ 0x00000020, 0x00000040, 0x00000080, 0x0000001B, 0x00000036,
314
+ };
315
+
316
+ rk[0] = vd[i * 4 + H4(0)];
317
+ rk[1] = vd[i * 4 + H4(1)];
318
+ rk[2] = vd[i * 4 + H4(2)];
319
+ rk[3] = vd[i * 4 + H4(3)];
320
+ rk[4] = vs2[i * 4 + H4(0)];
321
+ rk[5] = vs2[i * 4 + H4(1)];
322
+ rk[6] = vs2[i * 4 + H4(2)];
323
+ rk[7] = vs2[i * 4 + H4(3)];
324
+
325
+ if (uimm % 2 == 0) {
326
+ tmp = ror32(rk[7], 8);
327
+ rk[8] = rk[0] ^ (((uint32_t)AES_sbox[(tmp >> 24) & 0xff] << 24) |
328
+ ((uint32_t)AES_sbox[(tmp >> 16) & 0xff] << 16) |
329
+ ((uint32_t)AES_sbox[(tmp >> 8) & 0xff] << 8) |
330
+ ((uint32_t)AES_sbox[(tmp >> 0) & 0xff] << 0))
331
+ ^ rcon[(uimm - 1) / 2];
332
+ } else {
333
+ rk[8] = rk[0] ^ (((uint32_t)AES_sbox[(rk[7] >> 24) & 0xff] << 24) |
334
+ ((uint32_t)AES_sbox[(rk[7] >> 16) & 0xff] << 16) |
335
+ ((uint32_t)AES_sbox[(rk[7] >> 8) & 0xff] << 8) |
336
+ ((uint32_t)AES_sbox[(rk[7] >> 0) & 0xff] << 0));
337
+ }
338
+ rk[9] = rk[1] ^ rk[8];
339
+ rk[10] = rk[2] ^ rk[9];
340
+ rk[11] = rk[3] ^ rk[10];
341
+
342
+ vd[i * 4 + H4(0)] = rk[8];
343
+ vd[i * 4 + H4(1)] = rk[9];
344
+ vd[i * 4 + H4(2)] = rk[10];
345
+ vd[i * 4 + H4(3)] = rk[11];
346
+ }
347
+ env->vstart = 0;
348
+ /* set tail elements to 1s */
349
+ vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
350
+}
351
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
352
index XXXXXXX..XXXXXXX 100644
353
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
354
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
355
@@ -XXX,XX +XXX,XX @@ static bool vwsll_vx_check(DisasContext *s, arg_rmrr *a)
356
GEN_OPIVV_WIDEN_TRANS(vwsll_vv, vwsll_vv_check)
357
GEN_OPIVX_WIDEN_TRANS(vwsll_vx, vwsll_vx_check)
358
GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
359
+
360
+/*
361
+ * Zvkned
362
+ */
363
+
364
+#define ZVKNED_EGS 4
365
+
366
+#define GEN_V_UNMASKED_TRANS(NAME, CHECK, EGS) \
367
+ static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
368
+ { \
369
+ if (CHECK(s, a)) { \
370
+ TCGv_ptr rd_v, rs2_v; \
371
+ TCGv_i32 desc, egs; \
372
+ uint32_t data = 0; \
373
+ TCGLabel *over = gen_new_label(); \
374
+ \
375
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
376
+ /* save opcode for unwinding in case we throw an exception */ \
377
+ decode_save_opc(s); \
378
+ egs = tcg_constant_i32(EGS); \
379
+ gen_helper_egs_check(egs, cpu_env); \
380
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
381
+ } \
382
+ \
383
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
384
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
385
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
386
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
387
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
388
+ rd_v = tcg_temp_new_ptr(); \
389
+ rs2_v = tcg_temp_new_ptr(); \
390
+ desc = tcg_constant_i32( \
391
+ simd_desc(s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, data)); \
392
+ tcg_gen_addi_ptr(rd_v, cpu_env, vreg_ofs(s, a->rd)); \
393
+ tcg_gen_addi_ptr(rs2_v, cpu_env, vreg_ofs(s, a->rs2)); \
394
+ gen_helper_##NAME(rd_v, rs2_v, cpu_env, desc); \
395
+ mark_vs_dirty(s); \
396
+ gen_set_label(over); \
397
+ return true; \
398
+ } \
399
+ return false; \
400
+ }
401
+
402
+static bool vaes_check_vv(DisasContext *s, arg_rmr *a)
403
+{
404
+ int egw_bytes = ZVKNED_EGS << s->sew;
405
+ return s->cfg_ptr->ext_zvkned == true &&
406
+ require_rvv(s) &&
407
+ vext_check_isa_ill(s) &&
408
+ MAXSZ(s) >= egw_bytes &&
409
+ require_align(a->rd, s->lmul) &&
410
+ require_align(a->rs2, s->lmul) &&
411
+ s->sew == MO_32;
412
+}
413
+
414
+static bool vaes_check_overlap(DisasContext *s, int vd, int vs2)
415
+{
416
+ int8_t op_size = s->lmul <= 0 ? 1 : 1 << s->lmul;
417
+ return !is_overlapped(vd, op_size, vs2, 1);
418
+}
419
+
420
+static bool vaes_check_vs(DisasContext *s, arg_rmr *a)
421
+{
422
+ int egw_bytes = ZVKNED_EGS << s->sew;
423
+ return vaes_check_overlap(s, a->rd, a->rs2) &&
424
+ MAXSZ(s) >= egw_bytes &&
425
+ s->cfg_ptr->ext_zvkned == true &&
426
+ require_rvv(s) &&
427
+ vext_check_isa_ill(s) &&
428
+ require_align(a->rd, s->lmul) &&
429
+ s->sew == MO_32;
430
+}
431
+
432
+GEN_V_UNMASKED_TRANS(vaesef_vv, vaes_check_vv, ZVKNED_EGS)
433
+GEN_V_UNMASKED_TRANS(vaesef_vs, vaes_check_vs, ZVKNED_EGS)
434
+GEN_V_UNMASKED_TRANS(vaesdf_vv, vaes_check_vv, ZVKNED_EGS)
435
+GEN_V_UNMASKED_TRANS(vaesdf_vs, vaes_check_vs, ZVKNED_EGS)
436
+GEN_V_UNMASKED_TRANS(vaesdm_vv, vaes_check_vv, ZVKNED_EGS)
437
+GEN_V_UNMASKED_TRANS(vaesdm_vs, vaes_check_vs, ZVKNED_EGS)
438
+GEN_V_UNMASKED_TRANS(vaesz_vs, vaes_check_vs, ZVKNED_EGS)
439
+GEN_V_UNMASKED_TRANS(vaesem_vv, vaes_check_vv, ZVKNED_EGS)
440
+GEN_V_UNMASKED_TRANS(vaesem_vs, vaes_check_vs, ZVKNED_EGS)
441
+
442
+#define GEN_VI_UNMASKED_TRANS(NAME, CHECK, EGS) \
443
+ static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
444
+ { \
445
+ if (CHECK(s, a)) { \
446
+ TCGv_ptr rd_v, rs2_v; \
447
+ TCGv_i32 uimm_v, desc, egs; \
448
+ uint32_t data = 0; \
449
+ TCGLabel *over = gen_new_label(); \
450
+ \
451
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
452
+ /* save opcode for unwinding in case we throw an exception */ \
453
+ decode_save_opc(s); \
454
+ egs = tcg_constant_i32(EGS); \
455
+ gen_helper_egs_check(egs, cpu_env); \
456
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
457
+ } \
458
+ \
459
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
460
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
461
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
462
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
463
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
464
+ \
465
+ rd_v = tcg_temp_new_ptr(); \
466
+ rs2_v = tcg_temp_new_ptr(); \
467
+ uimm_v = tcg_constant_i32(a->rs1); \
468
+ desc = tcg_constant_i32( \
469
+ simd_desc(s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, data)); \
470
+ tcg_gen_addi_ptr(rd_v, cpu_env, vreg_ofs(s, a->rd)); \
471
+ tcg_gen_addi_ptr(rs2_v, cpu_env, vreg_ofs(s, a->rs2)); \
472
+ gen_helper_##NAME(rd_v, rs2_v, uimm_v, cpu_env, desc); \
473
+ mark_vs_dirty(s); \
474
+ gen_set_label(over); \
475
+ return true; \
476
+ } \
477
+ return false; \
478
+ }
479
+
480
+static bool vaeskf1_check(DisasContext *s, arg_vaeskf1_vi *a)
481
+{
482
+ int egw_bytes = ZVKNED_EGS << s->sew;
483
+ return s->cfg_ptr->ext_zvkned == true &&
484
+ require_rvv(s) &&
485
+ vext_check_isa_ill(s) &&
486
+ MAXSZ(s) >= egw_bytes &&
487
+ s->sew == MO_32 &&
488
+ require_align(a->rd, s->lmul) &&
489
+ require_align(a->rs2, s->lmul);
490
+}
491
+
492
+static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi *a)
493
+{
494
+ int egw_bytes = ZVKNED_EGS << s->sew;
495
+ return s->cfg_ptr->ext_zvkned == true &&
496
+ require_rvv(s) &&
497
+ vext_check_isa_ill(s) &&
498
+ MAXSZ(s) >= egw_bytes &&
499
+ s->sew == MO_32 &&
500
+ require_align(a->rd, s->lmul) &&
501
+ require_align(a->rs2, s->lmul);
502
+}
503
+
504
+GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, ZVKNED_EGS)
505
+GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
26
--
506
--
27
2.38.1
507
2.41.0
diff view generated by jsdifflib
1
From: Jim Shu <jim.shu@sifive.com>
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
2
3
let tlb_fill() function also increments PMU counter when it is from
3
This commit adds support for the Zvknh vector-crypto extension, which
4
two-stage translation, so QEMU could also monitor these PMU events when
4
consists of the following instructions:
5
CPU runs in VS/VU mode (like running guest OS).
6
5
7
Signed-off-by: Jim Shu <jim.shu@sifive.com>
6
* vsha2ms.vv
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
* vsha2c[hl].vv
9
Message-Id: <20221123090635.6574-1-jim.shu@sifive.com>
8
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
14
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
15
[max.chou@sifive.com: Replaced vstart checking by TCG op]
16
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
17
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
18
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
19
Signed-off-by: Max Chou <max.chou@sifive.com>
20
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
21
[max.chou@sifive.com: Exposed x-zvknha & x-zvknhb properties]
22
[max.chou@sifive.com: Replaced SEW selection to happened during
23
translation]
24
Message-ID: <20230711165917.2629866-11-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
26
---
12
target/riscv/cpu_helper.c | 2 +-
27
target/riscv/cpu_cfg.h | 2 +
13
1 file changed, 1 insertion(+), 1 deletion(-)
28
target/riscv/helper.h | 6 +
29
target/riscv/insn32.decode | 5 +
30
target/riscv/cpu.c | 13 +-
31
target/riscv/vcrypto_helper.c | 238 +++++++++++++++++++++++
32
target/riscv/insn_trans/trans_rvvk.c.inc | 129 ++++++++++++
33
6 files changed, 390 insertions(+), 3 deletions(-)
14
34
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
35
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
16
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
37
--- a/target/riscv/cpu_cfg.h
18
+++ b/target/riscv/cpu_helper.c
38
+++ b/target/riscv/cpu_cfg.h
19
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
39
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
20
}
40
bool ext_zvbb;
41
bool ext_zvbc;
42
bool ext_zvkned;
43
+ bool ext_zvknha;
44
+ bool ext_zvknhb;
45
bool ext_zmmul;
46
bool ext_zvfbfmin;
47
bool ext_zvfbfwma;
48
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/helper.h
51
+++ b/target/riscv/helper.h
52
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
53
DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
54
DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
55
DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
56
+
57
+DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32)
58
+DEF_HELPER_5(vsha2ch32_vv, void, ptr, ptr, ptr, env, i32)
59
+DEF_HELPER_5(vsha2ch64_vv, void, ptr, ptr, ptr, env, i32)
60
+DEF_HELPER_5(vsha2cl32_vv, void, ptr, ptr, ptr, env, i32)
61
+DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
62
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
63
index XXXXXXX..XXXXXXX 100644
64
--- a/target/riscv/insn32.decode
65
+++ b/target/riscv/insn32.decode
66
@@ -XXX,XX +XXX,XX @@ vaesdm_vs 101001 1 ..... 00000 010 ..... 1110111 @r2_vm_1
67
vaesz_vs 101001 1 ..... 00111 010 ..... 1110111 @r2_vm_1
68
vaeskf1_vi 100010 1 ..... ..... 010 ..... 1110111 @r_vm_1
69
vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1
70
+
71
+# *** Zvknh vector crypto extension ***
72
+vsha2ms_vv 101101 1 ..... ..... 010 ..... 1110111 @r_vm_1
73
+vsha2ch_vv 101110 1 ..... ..... 010 ..... 1110111 @r_vm_1
74
+vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
75
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/riscv/cpu.c
78
+++ b/target/riscv/cpu.c
79
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
80
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
81
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
82
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
83
+ ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
84
+ ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
85
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
86
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
87
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
88
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
89
* In principle Zve*x would also suffice here, were they supported
90
* in qemu
91
*/
92
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) && !cpu->cfg.ext_zve32f) {
93
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
94
+ !cpu->cfg.ext_zve32f) {
95
error_setg(errp,
96
"Vector crypto extensions require V or Zve* extensions");
97
return;
21
}
98
}
22
99
23
+ pmu_tlb_fill_incr_ctr(cpu, access_type);
100
- if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
24
if (riscv_cpu_virt_enabled(env) ||
101
- error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
25
((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
102
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
26
access_type != MMU_INST_FETCH)) {
103
+ error_setg(
27
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
104
+ errp,
28
}
105
+ "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
29
}
106
return;
30
} else {
107
}
31
- pmu_tlb_fill_incr_ctr(cpu, access_type);
108
32
/* Single stage lookup */
109
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
33
ret = get_physical_address(env, &pa, &prot, address, NULL,
110
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
34
access_type, mmu_idx, true, false, false);
111
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
112
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
113
+ DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
114
+ DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
115
116
DEFINE_PROP_END_OF_LIST(),
117
};
118
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
119
index XXXXXXX..XXXXXXX 100644
120
--- a/target/riscv/vcrypto_helper.c
121
+++ b/target/riscv/vcrypto_helper.c
122
@@ -XXX,XX +XXX,XX @@ void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
123
/* set tail elements to 1s */
124
vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
125
}
126
+
127
+static inline uint32_t sig0_sha256(uint32_t x)
128
+{
129
+ return ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3);
130
+}
131
+
132
+static inline uint32_t sig1_sha256(uint32_t x)
133
+{
134
+ return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
135
+}
136
+
137
+static inline uint64_t sig0_sha512(uint64_t x)
138
+{
139
+ return ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7);
140
+}
141
+
142
+static inline uint64_t sig1_sha512(uint64_t x)
143
+{
144
+ return ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6);
145
+}
146
+
147
+static inline void vsha2ms_e32(uint32_t *vd, uint32_t *vs1, uint32_t *vs2)
148
+{
149
+ uint32_t res[4];
150
+ res[0] = sig1_sha256(vs1[H4(2)]) + vs2[H4(1)] + sig0_sha256(vd[H4(1)]) +
151
+ vd[H4(0)];
152
+ res[1] = sig1_sha256(vs1[H4(3)]) + vs2[H4(2)] + sig0_sha256(vd[H4(2)]) +
153
+ vd[H4(1)];
154
+ res[2] =
155
+ sig1_sha256(res[0]) + vs2[H4(3)] + sig0_sha256(vd[H4(3)]) + vd[H4(2)];
156
+ res[3] =
157
+ sig1_sha256(res[1]) + vs1[H4(0)] + sig0_sha256(vs2[H4(0)]) + vd[H4(3)];
158
+ vd[H4(3)] = res[3];
159
+ vd[H4(2)] = res[2];
160
+ vd[H4(1)] = res[1];
161
+ vd[H4(0)] = res[0];
162
+}
163
+
164
+static inline void vsha2ms_e64(uint64_t *vd, uint64_t *vs1, uint64_t *vs2)
165
+{
166
+ uint64_t res[4];
167
+ res[0] = sig1_sha512(vs1[2]) + vs2[1] + sig0_sha512(vd[1]) + vd[0];
168
+ res[1] = sig1_sha512(vs1[3]) + vs2[2] + sig0_sha512(vd[2]) + vd[1];
169
+ res[2] = sig1_sha512(res[0]) + vs2[3] + sig0_sha512(vd[3]) + vd[2];
170
+ res[3] = sig1_sha512(res[1]) + vs1[0] + sig0_sha512(vs2[0]) + vd[3];
171
+ vd[3] = res[3];
172
+ vd[2] = res[2];
173
+ vd[1] = res[1];
174
+ vd[0] = res[0];
175
+}
176
+
177
+void HELPER(vsha2ms_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
178
+ uint32_t desc)
179
+{
180
+ uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
181
+ uint32_t esz = sew == MO_32 ? 4 : 8;
182
+ uint32_t total_elems;
183
+ uint32_t vta = vext_vta(desc);
184
+
185
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
186
+ if (sew == MO_32) {
187
+ vsha2ms_e32(((uint32_t *)vd) + i * 4, ((uint32_t *)vs1) + i * 4,
188
+ ((uint32_t *)vs2) + i * 4);
189
+ } else {
190
+ /* If not 32 then SEW should be 64 */
191
+ vsha2ms_e64(((uint64_t *)vd) + i * 4, ((uint64_t *)vs1) + i * 4,
192
+ ((uint64_t *)vs2) + i * 4);
193
+ }
194
+ }
195
+ /* set tail elements to 1s */
196
+ total_elems = vext_get_total_elems(env, desc, esz);
197
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
198
+ env->vstart = 0;
199
+}
200
+
201
+static inline uint64_t sum0_64(uint64_t x)
202
+{
203
+ return ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39);
204
+}
205
+
206
+static inline uint32_t sum0_32(uint32_t x)
207
+{
208
+ return ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22);
209
+}
210
+
211
+static inline uint64_t sum1_64(uint64_t x)
212
+{
213
+ return ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41);
214
+}
215
+
216
+static inline uint32_t sum1_32(uint32_t x)
217
+{
218
+ return ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25);
219
+}
220
+
221
+#define ch(x, y, z) ((x & y) ^ ((~x) & z))
222
+
223
+#define maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
224
+
225
+static void vsha2c_64(uint64_t *vs2, uint64_t *vd, uint64_t *vs1)
226
+{
227
+ uint64_t a = vs2[3], b = vs2[2], e = vs2[1], f = vs2[0];
228
+ uint64_t c = vd[3], d = vd[2], g = vd[1], h = vd[0];
229
+ uint64_t W0 = vs1[0], W1 = vs1[1];
230
+ uint64_t T1 = h + sum1_64(e) + ch(e, f, g) + W0;
231
+ uint64_t T2 = sum0_64(a) + maj(a, b, c);
232
+
233
+ h = g;
234
+ g = f;
235
+ f = e;
236
+ e = d + T1;
237
+ d = c;
238
+ c = b;
239
+ b = a;
240
+ a = T1 + T2;
241
+
242
+ T1 = h + sum1_64(e) + ch(e, f, g) + W1;
243
+ T2 = sum0_64(a) + maj(a, b, c);
244
+ h = g;
245
+ g = f;
246
+ f = e;
247
+ e = d + T1;
248
+ d = c;
249
+ c = b;
250
+ b = a;
251
+ a = T1 + T2;
252
+
253
+ vd[0] = f;
254
+ vd[1] = e;
255
+ vd[2] = b;
256
+ vd[3] = a;
257
+}
258
+
259
+static void vsha2c_32(uint32_t *vs2, uint32_t *vd, uint32_t *vs1)
260
+{
261
+ uint32_t a = vs2[H4(3)], b = vs2[H4(2)], e = vs2[H4(1)], f = vs2[H4(0)];
262
+ uint32_t c = vd[H4(3)], d = vd[H4(2)], g = vd[H4(1)], h = vd[H4(0)];
263
+ uint32_t W0 = vs1[H4(0)], W1 = vs1[H4(1)];
264
+ uint32_t T1 = h + sum1_32(e) + ch(e, f, g) + W0;
265
+ uint32_t T2 = sum0_32(a) + maj(a, b, c);
266
+
267
+ h = g;
268
+ g = f;
269
+ f = e;
270
+ e = d + T1;
271
+ d = c;
272
+ c = b;
273
+ b = a;
274
+ a = T1 + T2;
275
+
276
+ T1 = h + sum1_32(e) + ch(e, f, g) + W1;
277
+ T2 = sum0_32(a) + maj(a, b, c);
278
+ h = g;
279
+ g = f;
280
+ f = e;
281
+ e = d + T1;
282
+ d = c;
283
+ c = b;
284
+ b = a;
285
+ a = T1 + T2;
286
+
287
+ vd[H4(0)] = f;
288
+ vd[H4(1)] = e;
289
+ vd[H4(2)] = b;
290
+ vd[H4(3)] = a;
291
+}
292
+
293
+void HELPER(vsha2ch32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
294
+ uint32_t desc)
295
+{
296
+ const uint32_t esz = 4;
297
+ uint32_t total_elems;
298
+ uint32_t vta = vext_vta(desc);
299
+
300
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
301
+ vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i,
302
+ ((uint32_t *)vs1) + 4 * i + 2);
303
+ }
304
+
305
+ /* set tail elements to 1s */
306
+ total_elems = vext_get_total_elems(env, desc, esz);
307
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
308
+ env->vstart = 0;
309
+}
310
+
311
+void HELPER(vsha2ch64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
312
+ uint32_t desc)
313
+{
314
+ const uint32_t esz = 8;
315
+ uint32_t total_elems;
316
+ uint32_t vta = vext_vta(desc);
317
+
318
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
319
+ vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i,
320
+ ((uint64_t *)vs1) + 4 * i + 2);
321
+ }
322
+
323
+ /* set tail elements to 1s */
324
+ total_elems = vext_get_total_elems(env, desc, esz);
325
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
326
+ env->vstart = 0;
327
+}
328
+
329
+void HELPER(vsha2cl32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
330
+ uint32_t desc)
331
+{
332
+ const uint32_t esz = 4;
333
+ uint32_t total_elems;
334
+ uint32_t vta = vext_vta(desc);
335
+
336
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
337
+ vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i,
338
+ (((uint32_t *)vs1) + 4 * i));
339
+ }
340
+
341
+ /* set tail elements to 1s */
342
+ total_elems = vext_get_total_elems(env, desc, esz);
343
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
344
+ env->vstart = 0;
345
+}
346
+
347
+void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
348
+ uint32_t desc)
349
+{
350
+ uint32_t esz = 8;
351
+ uint32_t total_elems;
352
+ uint32_t vta = vext_vta(desc);
353
+
354
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
355
+ vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i,
356
+ (((uint64_t *)vs1) + 4 * i));
357
+ }
358
+
359
+ /* set tail elements to 1s */
360
+ total_elems = vext_get_total_elems(env, desc, esz);
361
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
362
+ env->vstart = 0;
363
+}
364
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
365
index XXXXXXX..XXXXXXX 100644
366
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
367
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
368
@@ -XXX,XX +XXX,XX @@ static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi *a)
369
370
GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, ZVKNED_EGS)
371
GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
372
+
373
+/*
374
+ * Zvknh
375
+ */
376
+
377
+#define ZVKNH_EGS 4
378
+
379
+#define GEN_VV_UNMASKED_TRANS(NAME, CHECK, EGS) \
380
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
381
+ { \
382
+ if (CHECK(s, a)) { \
383
+ uint32_t data = 0; \
384
+ TCGLabel *over = gen_new_label(); \
385
+ TCGv_i32 egs; \
386
+ \
387
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
388
+ /* save opcode for unwinding in case we throw an exception */ \
389
+ decode_save_opc(s); \
390
+ egs = tcg_constant_i32(EGS); \
391
+ gen_helper_egs_check(egs, cpu_env); \
392
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
393
+ } \
394
+ \
395
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
396
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
397
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
398
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
399
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
400
+ \
401
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1), \
402
+ vreg_ofs(s, a->rs2), cpu_env, \
403
+ s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, \
404
+ data, gen_helper_##NAME); \
405
+ \
406
+ mark_vs_dirty(s); \
407
+ gen_set_label(over); \
408
+ return true; \
409
+ } \
410
+ return false; \
411
+ }
412
+
413
+static bool vsha_check_sew(DisasContext *s)
414
+{
415
+ return (s->cfg_ptr->ext_zvknha == true && s->sew == MO_32) ||
416
+ (s->cfg_ptr->ext_zvknhb == true &&
417
+ (s->sew == MO_32 || s->sew == MO_64));
418
+}
419
+
420
+static bool vsha_check(DisasContext *s, arg_rmrr *a)
421
+{
422
+ int egw_bytes = ZVKNH_EGS << s->sew;
423
+ int mult = 1 << MAX(s->lmul, 0);
424
+ return opivv_check(s, a) &&
425
+ vsha_check_sew(s) &&
426
+ MAXSZ(s) >= egw_bytes &&
427
+ !is_overlapped(a->rd, mult, a->rs1, mult) &&
428
+ !is_overlapped(a->rd, mult, a->rs2, mult) &&
429
+ s->lmul >= 0;
430
+}
431
+
432
+GEN_VV_UNMASKED_TRANS(vsha2ms_vv, vsha_check, ZVKNH_EGS)
433
+
434
+static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
435
+{
436
+ if (vsha_check(s, a)) {
437
+ uint32_t data = 0;
438
+ TCGLabel *over = gen_new_label();
439
+ TCGv_i32 egs;
440
+
441
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
442
+ /* save opcode for unwinding in case we throw an exception */
443
+ decode_save_opc(s);
444
+ egs = tcg_constant_i32(ZVKNH_EGS);
445
+ gen_helper_egs_check(egs, cpu_env);
446
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
447
+ }
448
+
449
+ data = FIELD_DP32(data, VDATA, VM, a->vm);
450
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
451
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
452
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
453
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
454
+
455
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
456
+ vreg_ofs(s, a->rs2), cpu_env, s->cfg_ptr->vlen / 8,
457
+ s->cfg_ptr->vlen / 8, data,
458
+ s->sew == MO_32 ?
459
+ gen_helper_vsha2cl32_vv : gen_helper_vsha2cl64_vv);
460
+
461
+ mark_vs_dirty(s);
462
+ gen_set_label(over);
463
+ return true;
464
+ }
465
+ return false;
466
+}
467
+
468
+static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
469
+{
470
+ if (vsha_check(s, a)) {
471
+ uint32_t data = 0;
472
+ TCGLabel *over = gen_new_label();
473
+ TCGv_i32 egs;
474
+
475
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
476
+ /* save opcode for unwinding in case we throw an exception */
477
+ decode_save_opc(s);
478
+ egs = tcg_constant_i32(ZVKNH_EGS);
479
+ gen_helper_egs_check(egs, cpu_env);
480
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
481
+ }
482
+
483
+ data = FIELD_DP32(data, VDATA, VM, a->vm);
484
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
485
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
486
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
487
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
488
+
489
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
490
+ vreg_ofs(s, a->rs2), cpu_env, s->cfg_ptr->vlen / 8,
491
+ s->cfg_ptr->vlen / 8, data,
492
+ s->sew == MO_32 ?
493
+ gen_helper_vsha2ch32_vv : gen_helper_vsha2ch64_vv);
494
+
495
+ mark_vs_dirty(s);
496
+ gen_set_label(over);
497
+ return true;
498
+ }
499
+ return false;
500
+}
35
--
501
--
36
2.38.1
502
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
2
2
3
hw/pci/Kconfig says MSI_NONBROKEN should be selected by interrupt
3
This commit adds support for the Zvksh vector-crypto extension, which
4
controllers regardless of how MSI is implemented. msi_nonbroken is
4
consists of the following instructions:
5
initialized to true in both riscv_aplic_realize() and
5
6
riscv_imsic_realize().
6
* vsm3me.vv
7
7
* vsm3c.vi
8
Select MSI_NONBROKEN in RISCV_APLIC and RISCV_IMSIC.
8
9
9
Translation functions are defined in
10
Signed-off-by: Bin Meng <bmeng@tinylab.org>
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
`target/riscv/vcrypto_helper.c`.
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
13
Message-Id: <20221211030829.802437-2-bmeng@tinylab.org>
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>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
22
---
16
hw/intc/Kconfig | 2 ++
23
target/riscv/cpu_cfg.h | 1 +
17
1 file changed, 2 insertions(+)
24
target/riscv/helper.h | 3 +
18
25
target/riscv/insn32.decode | 4 +
19
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
26
target/riscv/cpu.c | 6 +-
20
index XXXXXXX..XXXXXXX 100644
27
target/riscv/vcrypto_helper.c | 134 +++++++++++++++++++++++
21
--- a/hw/intc/Kconfig
28
target/riscv/insn_trans/trans_rvvk.c.inc | 31 ++++++
22
+++ b/hw/intc/Kconfig
29
6 files changed, 177 insertions(+), 2 deletions(-)
23
@@ -XXX,XX +XXX,XX @@ config RISCV_ACLINT
30
24
31
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
25
config RISCV_APLIC
32
index XXXXXXX..XXXXXXX 100644
26
bool
33
--- a/target/riscv/cpu_cfg.h
27
+ select MSI_NONBROKEN
34
+++ b/target/riscv/cpu_cfg.h
28
35
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
29
config RISCV_IMSIC
36
bool ext_zvkned;
30
bool
37
bool ext_zvknha;
31
+ select MSI_NONBROKEN
38
bool ext_zvknhb;
32
39
+ bool ext_zvksh;
33
config SIFIVE_PLIC
40
bool ext_zmmul;
34
bool
41
bool ext_zvfbfmin;
42
bool ext_zvfbfwma;
43
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/helper.h
46
+++ b/target/riscv/helper.h
47
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsha2ch32_vv, void, ptr, ptr, ptr, env, i32)
48
DEF_HELPER_5(vsha2ch64_vv, void, ptr, ptr, ptr, env, i32)
49
DEF_HELPER_5(vsha2cl32_vv, void, ptr, ptr, ptr, env, i32)
50
DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
51
+
52
+DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
53
+DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
54
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/riscv/insn32.decode
57
+++ b/target/riscv/insn32.decode
58
@@ -XXX,XX +XXX,XX @@ vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1
59
vsha2ms_vv 101101 1 ..... ..... 010 ..... 1110111 @r_vm_1
60
vsha2ch_vv 101110 1 ..... ..... 010 ..... 1110111 @r_vm_1
61
vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
62
+
63
+# *** Zvksh vector crypto extension ***
64
+vsm3me_vv 100000 1 ..... ..... 010 ..... 1110111 @r_vm_1
65
+vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
66
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/cpu.c
69
+++ b/target/riscv/cpu.c
70
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
71
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
72
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
73
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
74
+ ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh),
75
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
76
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
77
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
78
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
79
* In principle Zve*x would also suffice here, were they supported
80
* in qemu
81
*/
82
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
83
- !cpu->cfg.ext_zve32f) {
84
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
85
+ cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
86
error_setg(errp,
87
"Vector crypto extensions require V or Zve* extensions");
88
return;
89
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
90
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
91
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
92
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
93
+ DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
94
95
DEFINE_PROP_END_OF_LIST(),
96
};
97
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
98
index XXXXXXX..XXXXXXX 100644
99
--- a/target/riscv/vcrypto_helper.c
100
+++ b/target/riscv/vcrypto_helper.c
101
@@ -XXX,XX +XXX,XX @@ void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
102
vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
103
env->vstart = 0;
104
}
105
+
106
+static inline uint32_t p1(uint32_t x)
107
+{
108
+ return x ^ rol32(x, 15) ^ rol32(x, 23);
109
+}
110
+
111
+static inline uint32_t zvksh_w(uint32_t m16, uint32_t m9, uint32_t m3,
112
+ uint32_t m13, uint32_t m6)
113
+{
114
+ return p1(m16 ^ m9 ^ rol32(m3, 15)) ^ rol32(m13, 7) ^ m6;
115
+}
116
+
117
+void HELPER(vsm3me_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
118
+ CPURISCVState *env, uint32_t desc)
119
+{
120
+ uint32_t esz = memop_size(FIELD_EX64(env->vtype, VTYPE, VSEW));
121
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
122
+ uint32_t vta = vext_vta(desc);
123
+ uint32_t *vd = vd_vptr;
124
+ uint32_t *vs1 = vs1_vptr;
125
+ uint32_t *vs2 = vs2_vptr;
126
+
127
+ for (int i = env->vstart / 8; i < env->vl / 8; i++) {
128
+ uint32_t w[24];
129
+ for (int j = 0; j < 8; j++) {
130
+ w[j] = bswap32(vs1[H4((i * 8) + j)]);
131
+ w[j + 8] = bswap32(vs2[H4((i * 8) + j)]);
132
+ }
133
+ for (int j = 0; j < 8; j++) {
134
+ w[j + 16] =
135
+ zvksh_w(w[j], w[j + 7], w[j + 13], w[j + 3], w[j + 10]);
136
+ }
137
+ for (int j = 0; j < 8; j++) {
138
+ vd[(i * 8) + j] = bswap32(w[H4(j + 16)]);
139
+ }
140
+ }
141
+ vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
142
+ env->vstart = 0;
143
+}
144
+
145
+static inline uint32_t ff1(uint32_t x, uint32_t y, uint32_t z)
146
+{
147
+ return x ^ y ^ z;
148
+}
149
+
150
+static inline uint32_t ff2(uint32_t x, uint32_t y, uint32_t z)
151
+{
152
+ return (x & y) | (x & z) | (y & z);
153
+}
154
+
155
+static inline uint32_t ff_j(uint32_t x, uint32_t y, uint32_t z, uint32_t j)
156
+{
157
+ return (j <= 15) ? ff1(x, y, z) : ff2(x, y, z);
158
+}
159
+
160
+static inline uint32_t gg1(uint32_t x, uint32_t y, uint32_t z)
161
+{
162
+ return x ^ y ^ z;
163
+}
164
+
165
+static inline uint32_t gg2(uint32_t x, uint32_t y, uint32_t z)
166
+{
167
+ return (x & y) | (~x & z);
168
+}
169
+
170
+static inline uint32_t gg_j(uint32_t x, uint32_t y, uint32_t z, uint32_t j)
171
+{
172
+ return (j <= 15) ? gg1(x, y, z) : gg2(x, y, z);
173
+}
174
+
175
+static inline uint32_t t_j(uint32_t j)
176
+{
177
+ return (j <= 15) ? 0x79cc4519 : 0x7a879d8a;
178
+}
179
+
180
+static inline uint32_t p_0(uint32_t x)
181
+{
182
+ return x ^ rol32(x, 9) ^ rol32(x, 17);
183
+}
184
+
185
+static void sm3c(uint32_t *vd, uint32_t *vs1, uint32_t *vs2, uint32_t uimm)
186
+{
187
+ uint32_t x0, x1;
188
+ uint32_t j;
189
+ uint32_t ss1, ss2, tt1, tt2;
190
+ x0 = vs2[0] ^ vs2[4];
191
+ x1 = vs2[1] ^ vs2[5];
192
+ j = 2 * uimm;
193
+ ss1 = rol32(rol32(vs1[0], 12) + vs1[4] + rol32(t_j(j), j % 32), 7);
194
+ ss2 = ss1 ^ rol32(vs1[0], 12);
195
+ tt1 = ff_j(vs1[0], vs1[1], vs1[2], j) + vs1[3] + ss2 + x0;
196
+ tt2 = gg_j(vs1[4], vs1[5], vs1[6], j) + vs1[7] + ss1 + vs2[0];
197
+ vs1[3] = vs1[2];
198
+ vd[3] = rol32(vs1[1], 9);
199
+ vs1[1] = vs1[0];
200
+ vd[1] = tt1;
201
+ vs1[7] = vs1[6];
202
+ vd[7] = rol32(vs1[5], 19);
203
+ vs1[5] = vs1[4];
204
+ vd[5] = p_0(tt2);
205
+ j = 2 * uimm + 1;
206
+ ss1 = rol32(rol32(vd[1], 12) + vd[5] + rol32(t_j(j), j % 32), 7);
207
+ ss2 = ss1 ^ rol32(vd[1], 12);
208
+ tt1 = ff_j(vd[1], vs1[1], vd[3], j) + vs1[3] + ss2 + x1;
209
+ tt2 = gg_j(vd[5], vs1[5], vd[7], j) + vs1[7] + ss1 + vs2[1];
210
+ vd[2] = rol32(vs1[1], 9);
211
+ vd[0] = tt1;
212
+ vd[6] = rol32(vs1[5], 19);
213
+ vd[4] = p_0(tt2);
214
+}
215
+
216
+void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
217
+ CPURISCVState *env, uint32_t desc)
218
+{
219
+ uint32_t esz = memop_size(FIELD_EX64(env->vtype, VTYPE, VSEW));
220
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
221
+ uint32_t vta = vext_vta(desc);
222
+ uint32_t *vd = vd_vptr;
223
+ uint32_t *vs2 = vs2_vptr;
224
+ uint32_t v1[8], v2[8], v3[8];
225
+
226
+ for (int i = env->vstart / 8; i < env->vl / 8; i++) {
227
+ for (int k = 0; k < 8; k++) {
228
+ v2[k] = bswap32(vd[H4(i * 8 + k)]);
229
+ v3[k] = bswap32(vs2[H4(i * 8 + k)]);
230
+ }
231
+ sm3c(v1, v2, v3, uimm);
232
+ for (int k = 0; k < 8; k++) {
233
+ vd[i * 8 + k] = bswap32(v1[H4(k)]);
234
+ }
235
+ }
236
+ vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
237
+ env->vstart = 0;
238
+}
239
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
240
index XXXXXXX..XXXXXXX 100644
241
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
242
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
243
@@ -XXX,XX +XXX,XX @@ static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
244
}
245
return false;
246
}
247
+
248
+/*
249
+ * Zvksh
250
+ */
251
+
252
+#define ZVKSH_EGS 8
253
+
254
+static inline bool vsm3_check(DisasContext *s, arg_rmrr *a)
255
+{
256
+ int egw_bytes = ZVKSH_EGS << s->sew;
257
+ int mult = 1 << MAX(s->lmul, 0);
258
+ return s->cfg_ptr->ext_zvksh == true &&
259
+ require_rvv(s) &&
260
+ vext_check_isa_ill(s) &&
261
+ !is_overlapped(a->rd, mult, a->rs2, mult) &&
262
+ MAXSZ(s) >= egw_bytes &&
263
+ s->sew == MO_32;
264
+}
265
+
266
+static inline bool vsm3me_check(DisasContext *s, arg_rmrr *a)
267
+{
268
+ return vsm3_check(s, a) && vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm);
269
+}
270
+
271
+static inline bool vsm3c_check(DisasContext *s, arg_rmrr *a)
272
+{
273
+ return vsm3_check(s, a) && vext_check_ss(s, a->rd, a->rs2, a->vm);
274
+}
275
+
276
+GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS)
277
+GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS)
35
--
278
--
36
2.38.1
279
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
hw/pci/Kconfig says MSI_NONBROKEN should be selected by interrupt
3
This commit adds support for the Zvkg vector-crypto extension, which
4
controllers regardless of how MSI is implemented. msi_nonbroken is
4
consists of the following instructions:
5
initialized to true in sifive_plic_realize().
5
6
6
* vgmul.vv
7
Let SIFIVE_PLIC select MSI_NONBROKEN and drop the selection from
7
* vghsh.vv
8
RISC-V machines.
8
9
9
Translation functions are defined in
10
Signed-off-by: Bin Meng <bmeng@tinylab.org>
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
`target/riscv/vcrypto_helper.c`.
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
13
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
13
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
14
Message-Id: <20221211030829.802437-1-bmeng@tinylab.org>
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>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
23
---
17
hw/intc/Kconfig | 1 +
24
target/riscv/cpu_cfg.h | 1 +
18
hw/riscv/Kconfig | 5 -----
25
target/riscv/helper.h | 3 +
19
2 files changed, 1 insertion(+), 5 deletions(-)
26
target/riscv/insn32.decode | 4 ++
20
27
target/riscv/cpu.c | 6 +-
21
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
28
target/riscv/vcrypto_helper.c | 72 ++++++++++++++++++++++++
22
index XXXXXXX..XXXXXXX 100644
29
target/riscv/insn_trans/trans_rvvk.c.inc | 30 ++++++++++
23
--- a/hw/intc/Kconfig
30
6 files changed, 114 insertions(+), 2 deletions(-)
24
+++ b/hw/intc/Kconfig
31
25
@@ -XXX,XX +XXX,XX @@ config RISCV_IMSIC
32
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
26
33
index XXXXXXX..XXXXXXX 100644
27
config SIFIVE_PLIC
34
--- a/target/riscv/cpu_cfg.h
28
bool
35
+++ b/target/riscv/cpu_cfg.h
29
+ select MSI_NONBROKEN
36
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
30
37
bool ext_zve64d;
31
config GOLDFISH_PIC
38
bool ext_zvbb;
32
bool
39
bool ext_zvbc;
33
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
40
+ bool ext_zvkg;
34
index XXXXXXX..XXXXXXX 100644
41
bool ext_zvkned;
35
--- a/hw/riscv/Kconfig
42
bool ext_zvknha;
36
+++ b/hw/riscv/Kconfig
43
bool ext_zvknhb;
37
@@ -XXX,XX +XXX,XX @@ config MICROCHIP_PFSOC
44
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
38
select MCHP_PFSOC_IOSCB
45
index XXXXXXX..XXXXXXX 100644
39
select MCHP_PFSOC_MMUART
46
--- a/target/riscv/helper.h
40
select MCHP_PFSOC_SYSREG
47
+++ b/target/riscv/helper.h
41
- select MSI_NONBROKEN
48
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
42
select RISCV_ACLINT
49
43
select SIFIVE_PDMA
50
DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
44
select SIFIVE_PLIC
51
DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
45
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
52
+
46
imply TPM_TIS_SYSBUS
53
+DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
47
select RISCV_NUMA
54
+DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
48
select GOLDFISH_RTC
55
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
49
- select MSI_NONBROKEN
56
index XXXXXXX..XXXXXXX 100644
50
select PCI
57
--- a/target/riscv/insn32.decode
51
select PCI_EXPRESS_GENERIC_BRIDGE
58
+++ b/target/riscv/insn32.decode
52
select PFLASH_CFI01
59
@@ -XXX,XX +XXX,XX @@ vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
53
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
60
# *** Zvksh vector crypto extension ***
54
61
vsm3me_vv 100000 1 ..... ..... 010 ..... 1110111 @r_vm_1
55
config SIFIVE_E
62
vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
56
bool
63
+
57
- select MSI_NONBROKEN
64
+# *** Zvkg vector crypto extension ***
58
select RISCV_ACLINT
65
+vghsh_vv 101100 1 ..... ..... 010 ..... 1110111 @r_vm_1
59
select SIFIVE_GPIO
66
+vgmul_vv 101000 1 ..... 10001 010 ..... 1110111 @r2_vm_1
60
select SIFIVE_PLIC
67
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
61
@@ -XXX,XX +XXX,XX @@ config SIFIVE_E
68
index XXXXXXX..XXXXXXX 100644
62
config SIFIVE_U
69
--- a/target/riscv/cpu.c
63
bool
70
+++ b/target/riscv/cpu.c
64
select CADENCE
71
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
65
- select MSI_NONBROKEN
72
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
66
select RISCV_ACLINT
73
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
67
select SIFIVE_GPIO
74
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
68
select SIFIVE_PDMA
75
+ ISA_EXT_DATA_ENTRY(zvkg, PRIV_VERSION_1_12_0, ext_zvkg),
69
@@ -XXX,XX +XXX,XX @@ config SPIKE
76
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
70
bool
77
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
71
select RISCV_NUMA
78
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
72
select HTIF
79
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
73
- select MSI_NONBROKEN
80
* In principle Zve*x would also suffice here, were they supported
74
select RISCV_ACLINT
81
* in qemu
75
select SIFIVE_PLIC
82
*/
83
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
84
- cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
85
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
86
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
87
error_setg(errp,
88
"Vector crypto extensions require V or Zve* extensions");
89
return;
90
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
91
/* Vector cryptography extensions */
92
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
93
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
94
+ DEFINE_PROP_BOOL("x-zvkg", RISCVCPU, cfg.ext_zvkg, false),
95
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
96
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
97
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
98
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/riscv/vcrypto_helper.c
101
+++ b/target/riscv/vcrypto_helper.c
102
@@ -XXX,XX +XXX,XX @@ void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
103
vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
104
env->vstart = 0;
105
}
106
+
107
+void HELPER(vghsh_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
108
+ CPURISCVState *env, uint32_t desc)
109
+{
110
+ uint64_t *vd = vd_vptr;
111
+ uint64_t *vs1 = vs1_vptr;
112
+ uint64_t *vs2 = vs2_vptr;
113
+ uint32_t vta = vext_vta(desc);
114
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
115
+
116
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
117
+ uint64_t Y[2] = {vd[i * 2 + 0], vd[i * 2 + 1]};
118
+ uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
119
+ uint64_t X[2] = {vs1[i * 2 + 0], vs1[i * 2 + 1]};
120
+ uint64_t Z[2] = {0, 0};
121
+
122
+ uint64_t S[2] = {brev8(Y[0] ^ X[0]), brev8(Y[1] ^ X[1])};
123
+
124
+ for (int j = 0; j < 128; j++) {
125
+ if ((S[j / 64] >> (j % 64)) & 1) {
126
+ Z[0] ^= H[0];
127
+ Z[1] ^= H[1];
128
+ }
129
+ bool reduce = ((H[1] >> 63) & 1);
130
+ H[1] = H[1] << 1 | H[0] >> 63;
131
+ H[0] = H[0] << 1;
132
+ if (reduce) {
133
+ H[0] ^= 0x87;
134
+ }
135
+ }
136
+
137
+ vd[i * 2 + 0] = brev8(Z[0]);
138
+ vd[i * 2 + 1] = brev8(Z[1]);
139
+ }
140
+ /* set tail elements to 1s */
141
+ vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
142
+ env->vstart = 0;
143
+}
144
+
145
+void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env,
146
+ uint32_t desc)
147
+{
148
+ uint64_t *vd = vd_vptr;
149
+ uint64_t *vs2 = vs2_vptr;
150
+ uint32_t vta = vext_vta(desc);
151
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
152
+
153
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
154
+ uint64_t Y[2] = {brev8(vd[i * 2 + 0]), brev8(vd[i * 2 + 1])};
155
+ uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
156
+ uint64_t Z[2] = {0, 0};
157
+
158
+ for (int j = 0; j < 128; j++) {
159
+ if ((Y[j / 64] >> (j % 64)) & 1) {
160
+ Z[0] ^= H[0];
161
+ Z[1] ^= H[1];
162
+ }
163
+ bool reduce = ((H[1] >> 63) & 1);
164
+ H[1] = H[1] << 1 | H[0] >> 63;
165
+ H[0] = H[0] << 1;
166
+ if (reduce) {
167
+ H[0] ^= 0x87;
168
+ }
169
+ }
170
+
171
+ vd[i * 2 + 0] = brev8(Z[0]);
172
+ vd[i * 2 + 1] = brev8(Z[1]);
173
+ }
174
+ /* set tail elements to 1s */
175
+ vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
176
+ env->vstart = 0;
177
+}
178
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
179
index XXXXXXX..XXXXXXX 100644
180
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
181
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
182
@@ -XXX,XX +XXX,XX @@ static inline bool vsm3c_check(DisasContext *s, arg_rmrr *a)
183
184
GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS)
185
GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS)
186
+
187
+/*
188
+ * Zvkg
189
+ */
190
+
191
+#define ZVKG_EGS 4
192
+
193
+static bool vgmul_check(DisasContext *s, arg_rmr *a)
194
+{
195
+ int egw_bytes = ZVKG_EGS << s->sew;
196
+ return s->cfg_ptr->ext_zvkg == true &&
197
+ vext_check_isa_ill(s) &&
198
+ require_rvv(s) &&
199
+ MAXSZ(s) >= egw_bytes &&
200
+ vext_check_ss(s, a->rd, a->rs2, a->vm) &&
201
+ s->sew == MO_32;
202
+}
203
+
204
+GEN_V_UNMASKED_TRANS(vgmul_vv, vgmul_check, ZVKG_EGS)
205
+
206
+static bool vghsh_check(DisasContext *s, arg_rmrr *a)
207
+{
208
+ int egw_bytes = ZVKG_EGS << s->sew;
209
+ return s->cfg_ptr->ext_zvkg == true &&
210
+ opivv_check(s, a) &&
211
+ MAXSZ(s) >= egw_bytes &&
212
+ s->sew == MO_32;
213
+}
214
+
215
+GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
76
--
216
--
77
2.38.1
217
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
At present the PLIC config parser can only handle legal config string
3
Allows sharing of sm4_subword between different targets.
4
like "MS,MS". However if a config string like ",MS,MS,,MS,MS,," is
5
given the parser won't get the correct configuration.
6
4
7
This commit improves the config parser to make it more robust.
5
Signed-off-by: Max Chou <max.chou@sifive.com>
8
6
Reviewed-by: Frank Chang <frank.chang@sifive.com>
9
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Acked-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Max Chou <max.chou@sifive.com>
11
Message-Id: <20221211030829.802437-7-bmeng@tinylab.org>
9
Message-ID: <20230711165917.2629866-14-max.chou@sifive.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
11
---
14
hw/intc/sifive_plic.c | 24 ++++++++++++++++--------
12
include/crypto/sm4.h | 8 ++++++++
15
1 file changed, 16 insertions(+), 8 deletions(-)
13
target/arm/tcg/crypto_helper.c | 10 ++--------
14
2 files changed, 10 insertions(+), 8 deletions(-)
16
15
17
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
16
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/sifive_plic.c
18
--- a/include/crypto/sm4.h
20
+++ b/hw/intc/sifive_plic.c
19
+++ b/include/crypto/sm4.h
21
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_reset(DeviceState *dev)
20
@@ -XXX,XX +XXX,XX @@
22
*/
21
23
static void parse_hart_config(SiFivePLICState *plic)
22
extern const uint8_t sm4_sbox[256];
24
{
23
25
- int addrid, hartid, modes;
24
+static inline uint32_t sm4_subword(uint32_t word)
26
+ int addrid, hartid, modes, m;
25
+{
27
const char *p;
26
+ return sm4_sbox[word & 0xff] |
28
char c;
27
+ sm4_sbox[(word >> 8) & 0xff] << 8 |
29
28
+ sm4_sbox[(word >> 16) & 0xff] << 16 |
30
@@ -XXX,XX +XXX,XX @@ static void parse_hart_config(SiFivePLICState *plic)
29
+ sm4_sbox[(word >> 24) & 0xff] << 24;
31
p = plic->hart_config;
30
+}
32
while ((c = *p++)) {
31
+
33
if (c == ',') {
32
#endif
34
- addrid += ctpop8(modes);
33
diff --git a/target/arm/tcg/crypto_helper.c b/target/arm/tcg/crypto_helper.c
35
- modes = 0;
34
index XXXXXXX..XXXXXXX 100644
36
- hartid++;
35
--- a/target/arm/tcg/crypto_helper.c
37
+ if (modes) {
36
+++ b/target/arm/tcg/crypto_helper.c
38
+ addrid += ctpop8(modes);
37
@@ -XXX,XX +XXX,XX @@ static void do_crypto_sm4e(uint64_t *rd, uint64_t *rn, uint64_t *rm)
39
+ hartid++;
38
CR_ST_WORD(d, (i + 3) % 4) ^
40
+ modes = 0;
39
CR_ST_WORD(n, i);
41
+ }
40
42
} else {
41
- t = sm4_sbox[t & 0xff] |
43
- int m = 1 << char_to_mode(c);
42
- sm4_sbox[(t >> 8) & 0xff] << 8 |
44
+ m = 1 << char_to_mode(c);
43
- sm4_sbox[(t >> 16) & 0xff] << 16 |
45
if (modes == (modes | m)) {
44
- sm4_sbox[(t >> 24) & 0xff] << 24;
46
error_report("plic: duplicate mode '%c' in config: %s",
45
+ t = sm4_subword(t);
47
c, plic->hart_config);
46
48
@@ -XXX,XX +XXX,XX @@ static void parse_hart_config(SiFivePLICState *plic)
47
CR_ST_WORD(d, i) ^= t ^ rol32(t, 2) ^ rol32(t, 10) ^ rol32(t, 18) ^
49
}
48
rol32(t, 24);
50
if (modes) {
49
@@ -XXX,XX +XXX,XX @@ static void do_crypto_sm4ekey(uint64_t *rd, uint64_t *rn, uint64_t *rm)
51
addrid += ctpop8(modes);
50
CR_ST_WORD(d, (i + 3) % 4) ^
52
+ hartid++;
51
CR_ST_WORD(m, i);
53
+ modes = 0;
52
54
}
53
- t = sm4_sbox[t & 0xff] |
55
- hartid++;
54
- sm4_sbox[(t >> 8) & 0xff] << 8 |
56
55
- sm4_sbox[(t >> 16) & 0xff] << 16 |
57
plic->num_addrs = addrid;
56
- sm4_sbox[(t >> 24) & 0xff] << 24;
58
plic->num_harts = hartid;
57
+ t = sm4_subword(t);
59
@@ -XXX,XX +XXX,XX @@ static void parse_hart_config(SiFivePLICState *plic)
58
60
p = plic->hart_config;
59
CR_ST_WORD(d, i) ^= t ^ rol32(t, 13) ^ rol32(t, 23);
61
while ((c = *p++)) {
62
if (c == ',') {
63
- hartid++;
64
+ if (modes) {
65
+ hartid++;
66
+ modes = 0;
67
+ }
68
} else {
69
+ m = char_to_mode(c);
70
plic->addr_config[addrid].addrid = addrid;
71
plic->addr_config[addrid].hartid = hartid;
72
- plic->addr_config[addrid].mode = char_to_mode(c);
73
+ plic->addr_config[addrid].mode = m;
74
+ modes |= (1 << m);
75
addrid++;
76
}
77
}
60
}
78
--
61
--
79
2.38.1
62
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
Per chapter 10 in Freedom E310 manuals [1][2][3], E310 G002 and G003
3
Adds sm4_ck constant for use in sm4 cryptography across different targets.
4
supports 52 interrupt sources while G000 supports 51 interrupt sources.
5
4
6
We use the value of G002 and G003, so it is 53 (including source 0).
5
Signed-off-by: Max Chou <max.chou@sifive.com>
7
6
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
[1] G000 manual:
7
Signed-off-by: Max Chou <max.chou@sifive.com>
9
https://sifive.cdn.prismic.io/sifive/4faf3e34-4a42-4c2f-be9e-c77baa4928c7_fe310-g000-manual-v3p2.pdf
8
Message-ID: <20230711165917.2629866-15-max.chou@sifive.com>
10
11
[2] G002 manual:
12
https://sifive.cdn.prismic.io/sifive/034760b5-ac6a-4b1c-911c-f4148bb2c4a5_fe310-g002-v1p5.pdf
13
14
[3] G003 manual:
15
https://sifive.cdn.prismic.io/sifive/3af39c59-6498-471e-9dab-5355a0d539eb_fe310-g003-manual.pdf
16
17
Fixes: eb637edb1241 ("SiFive Freedom E Series RISC-V Machine")
18
Signed-off-by: Bin Meng <bmeng@tinylab.org>
19
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-Id: <20221211030829.802437-11-bmeng@tinylab.org>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
10
---
24
include/hw/riscv/sifive_e.h | 7 ++++++-
11
include/crypto/sm4.h | 1 +
25
1 file changed, 6 insertions(+), 1 deletion(-)
12
crypto/sm4.c | 10 ++++++++++
13
2 files changed, 11 insertions(+)
26
14
27
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
15
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
28
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
29
--- a/include/hw/riscv/sifive_e.h
17
--- a/include/crypto/sm4.h
30
+++ b/include/hw/riscv/sifive_e.h
18
+++ b/include/crypto/sm4.h
31
@@ -XXX,XX +XXX,XX @@ enum {
19
@@ -XXX,XX +XXX,XX @@
20
#define QEMU_SM4_H
21
22
extern const uint8_t sm4_sbox[256];
23
+extern const uint32_t sm4_ck[32];
24
25
static inline uint32_t sm4_subword(uint32_t word)
26
{
27
diff --git a/crypto/sm4.c b/crypto/sm4.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/crypto/sm4.c
30
+++ b/crypto/sm4.c
31
@@ -XXX,XX +XXX,XX @@ uint8_t const sm4_sbox[] = {
32
0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
32
};
33
};
33
34
34
#define SIFIVE_E_PLIC_HART_CONFIG "M"
35
+uint32_t const sm4_ck[] = {
35
-#define SIFIVE_E_PLIC_NUM_SOURCES 127
36
+ 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
36
+/*
37
+ 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
37
+ * Freedom E310 G002 and G003 supports 52 interrupt sources while
38
+ 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
38
+ * Freedom E310 G000 supports 51 interrupt sources. We use the value
39
+ 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
39
+ * of G002 and G003, so it is 53 (including interrupt source 0).
40
+ 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
40
+ */
41
+ 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
41
+#define SIFIVE_E_PLIC_NUM_SOURCES 53
42
+ 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
42
#define SIFIVE_E_PLIC_NUM_PRIORITIES 7
43
+ 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
43
#define SIFIVE_E_PLIC_PRIORITY_BASE 0x04
44
+};
44
#define SIFIVE_E_PLIC_PENDING_BASE 0x1000
45
--
45
--
46
2.38.1
46
2.41.0
diff view generated by jsdifflib
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
Adds the updated `aon_timer` base as an unimplemented device. This is
3
This commit adds support for the Zvksed vector-crypto extension, which
4
used by TockOS, patch ensures the guest doesn't hit load faults.
4
consists of the following instructions:
5
5
6
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
6
* vsm4k.vi
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
7
* vsm4r.[vv,vs]
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
9
Message-Id: <20221025043335.339815-3-wilfred.mallawa@opensource.wdc.com>
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Signed-off-by: Max Chou <max.chou@sifive.com>
14
Reviewed-by: Frank Chang <frank.chang@sifive.com>
15
[lawrence.hunter@codethink.co.uk: Moved SM4 functions from
16
crypto_helper.c to vcrypto_helper.c]
17
[nazar.kazakov@codethink.co.uk: Added alignment checks, refactored code to
18
use macros, and minor style changes]
19
Signed-off-by: Max Chou <max.chou@sifive.com>
20
Message-ID: <20230711165917.2629866-16-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
22
---
12
include/hw/riscv/opentitan.h | 1 +
23
target/riscv/cpu_cfg.h | 1 +
13
hw/riscv/opentitan.c | 3 +++
24
target/riscv/helper.h | 4 +
14
2 files changed, 4 insertions(+)
25
target/riscv/insn32.decode | 5 +
15
26
target/riscv/cpu.c | 5 +-
16
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
27
target/riscv/vcrypto_helper.c | 127 +++++++++++++++++++++++
17
index XXXXXXX..XXXXXXX 100644
28
target/riscv/insn_trans/trans_rvvk.c.inc | 43 ++++++++
18
--- a/include/hw/riscv/opentitan.h
29
6 files changed, 184 insertions(+), 1 deletion(-)
19
+++ b/include/hw/riscv/opentitan.h
30
20
@@ -XXX,XX +XXX,XX @@ enum {
31
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
21
IBEX_DEV_RSTMGR,
32
index XXXXXXX..XXXXXXX 100644
22
IBEX_DEV_CLKMGR,
33
--- a/target/riscv/cpu_cfg.h
23
IBEX_DEV_PINMUX,
34
+++ b/target/riscv/cpu_cfg.h
24
+ IBEX_DEV_AON_TIMER,
35
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
25
IBEX_DEV_USBDEV,
36
bool ext_zvkned;
26
IBEX_DEV_FLASH_CTRL,
37
bool ext_zvknha;
27
IBEX_DEV_PLIC,
38
bool ext_zvknhb;
28
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
39
+ bool ext_zvksed;
29
index XXXXXXX..XXXXXXX 100644
40
bool ext_zvksh;
30
--- a/hw/riscv/opentitan.c
41
bool ext_zmmul;
31
+++ b/hw/riscv/opentitan.c
42
bool ext_zvfbfmin;
32
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = {
43
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
33
[IBEX_DEV_RSTMGR] = { 0x40410000, 0x1000 },
44
index XXXXXXX..XXXXXXX 100644
34
[IBEX_DEV_CLKMGR] = { 0x40420000, 0x1000 },
45
--- a/target/riscv/helper.h
35
[IBEX_DEV_PINMUX] = { 0x40460000, 0x1000 },
46
+++ b/target/riscv/helper.h
36
+ [IBEX_DEV_AON_TIMER] = { 0x40470000, 0x1000 },
47
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
37
[IBEX_DEV_SENSOR_CTRL] = { 0x40490000, 0x1000 },
48
38
[IBEX_DEV_FLASH_CTRL] = { 0x41000000, 0x1000 },
49
DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
39
[IBEX_DEV_AES] = { 0x41100000, 0x1000 },
50
DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
40
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
51
+
41
memmap[IBEX_DEV_CLKMGR].base, memmap[IBEX_DEV_CLKMGR].size);
52
+DEF_HELPER_5(vsm4k_vi, void, ptr, ptr, i32, env, i32)
42
create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
53
+DEF_HELPER_4(vsm4r_vv, void, ptr, ptr, env, i32)
43
memmap[IBEX_DEV_PINMUX].base, memmap[IBEX_DEV_PINMUX].size);
54
+DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32)
44
+ create_unimplemented_device("riscv.lowrisc.ibex.aon_timer",
55
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
45
+ memmap[IBEX_DEV_AON_TIMER].base, memmap[IBEX_DEV_AON_TIMER].size);
56
index XXXXXXX..XXXXXXX 100644
46
create_unimplemented_device("riscv.lowrisc.ibex.usbdev",
57
--- a/target/riscv/insn32.decode
47
memmap[IBEX_DEV_USBDEV].base, memmap[IBEX_DEV_USBDEV].size);
58
+++ b/target/riscv/insn32.decode
48
create_unimplemented_device("riscv.lowrisc.ibex.flash_ctrl",
59
@@ -XXX,XX +XXX,XX @@ vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
60
# *** Zvkg vector crypto extension ***
61
vghsh_vv 101100 1 ..... ..... 010 ..... 1110111 @r_vm_1
62
vgmul_vv 101000 1 ..... 10001 010 ..... 1110111 @r2_vm_1
63
+
64
+# *** Zvksed vector crypto extension ***
65
+vsm4k_vi 100001 1 ..... ..... 010 ..... 1110111 @r_vm_1
66
+vsm4r_vv 101000 1 ..... 10000 010 ..... 1110111 @r2_vm_1
67
+vsm4r_vs 101001 1 ..... 10000 010 ..... 1110111 @r2_vm_1
68
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/riscv/cpu.c
71
+++ b/target/riscv/cpu.c
72
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
73
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
74
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
75
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
76
+ ISA_EXT_DATA_ENTRY(zvksed, PRIV_VERSION_1_12_0, ext_zvksed),
77
ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh),
78
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
79
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
80
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
81
* in qemu
82
*/
83
if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
84
- cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
85
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed || cpu->cfg.ext_zvksh) &&
86
+ !cpu->cfg.ext_zve32f) {
87
error_setg(errp,
88
"Vector crypto extensions require V or Zve* extensions");
89
return;
90
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
91
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
92
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
93
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
94
+ DEFINE_PROP_BOOL("x-zvksed", RISCVCPU, cfg.ext_zvksed, false),
95
DEFINE_PROP_BOOL("x-zvksh", RISCVCPU, cfg.ext_zvksh, false),
96
97
DEFINE_PROP_END_OF_LIST(),
98
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/riscv/vcrypto_helper.c
101
+++ b/target/riscv/vcrypto_helper.c
102
@@ -XXX,XX +XXX,XX @@
103
#include "cpu.h"
104
#include "crypto/aes.h"
105
#include "crypto/aes-round.h"
106
+#include "crypto/sm4.h"
107
#include "exec/memop.h"
108
#include "exec/exec-all.h"
109
#include "exec/helper-proto.h"
110
@@ -XXX,XX +XXX,XX @@ void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env,
111
vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
112
env->vstart = 0;
113
}
114
+
115
+void HELPER(vsm4k_vi)(void *vd, void *vs2, uint32_t uimm5, CPURISCVState *env,
116
+ uint32_t desc)
117
+{
118
+ const uint32_t egs = 4;
119
+ uint32_t rnd = uimm5 & 0x7;
120
+ uint32_t group_start = env->vstart / egs;
121
+ uint32_t group_end = env->vl / egs;
122
+ uint32_t esz = sizeof(uint32_t);
123
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
124
+
125
+ for (uint32_t i = group_start; i < group_end; ++i) {
126
+ uint32_t vstart = i * egs;
127
+ uint32_t vend = (i + 1) * egs;
128
+ uint32_t rk[4] = {0};
129
+ uint32_t tmp[8] = {0};
130
+
131
+ for (uint32_t j = vstart; j < vend; ++j) {
132
+ rk[j - vstart] = *((uint32_t *)vs2 + H4(j));
133
+ }
134
+
135
+ for (uint32_t j = 0; j < egs; ++j) {
136
+ tmp[j] = rk[j];
137
+ }
138
+
139
+ for (uint32_t j = 0; j < egs; ++j) {
140
+ uint32_t b, s;
141
+ b = tmp[j + 1] ^ tmp[j + 2] ^ tmp[j + 3] ^ sm4_ck[rnd * 4 + j];
142
+
143
+ s = sm4_subword(b);
144
+
145
+ tmp[j + 4] = tmp[j] ^ (s ^ rol32(s, 13) ^ rol32(s, 23));
146
+ }
147
+
148
+ for (uint32_t j = vstart; j < vend; ++j) {
149
+ *((uint32_t *)vd + H4(j)) = tmp[egs + (j - vstart)];
150
+ }
151
+ }
152
+
153
+ env->vstart = 0;
154
+ /* set tail elements to 1s */
155
+ vext_set_elems_1s(vd, vext_vta(desc), env->vl * esz, total_elems * esz);
156
+}
157
+
158
+static void do_sm4_round(uint32_t *rk, uint32_t *buf)
159
+{
160
+ const uint32_t egs = 4;
161
+ uint32_t s, b;
162
+
163
+ for (uint32_t j = egs; j < egs * 2; ++j) {
164
+ b = buf[j - 3] ^ buf[j - 2] ^ buf[j - 1] ^ rk[j - 4];
165
+
166
+ s = sm4_subword(b);
167
+
168
+ buf[j] = buf[j - 4] ^ (s ^ rol32(s, 2) ^ rol32(s, 10) ^ rol32(s, 18) ^
169
+ rol32(s, 24));
170
+ }
171
+}
172
+
173
+void HELPER(vsm4r_vv)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
174
+{
175
+ const uint32_t egs = 4;
176
+ uint32_t group_start = env->vstart / egs;
177
+ uint32_t group_end = env->vl / egs;
178
+ uint32_t esz = sizeof(uint32_t);
179
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
180
+
181
+ for (uint32_t i = group_start; i < group_end; ++i) {
182
+ uint32_t vstart = i * egs;
183
+ uint32_t vend = (i + 1) * egs;
184
+ uint32_t rk[4] = {0};
185
+ uint32_t tmp[8] = {0};
186
+
187
+ for (uint32_t j = vstart; j < vend; ++j) {
188
+ rk[j - vstart] = *((uint32_t *)vs2 + H4(j));
189
+ }
190
+
191
+ for (uint32_t j = vstart; j < vend; ++j) {
192
+ tmp[j - vstart] = *((uint32_t *)vd + H4(j));
193
+ }
194
+
195
+ do_sm4_round(rk, tmp);
196
+
197
+ for (uint32_t j = vstart; j < vend; ++j) {
198
+ *((uint32_t *)vd + H4(j)) = tmp[egs + (j - vstart)];
199
+ }
200
+ }
201
+
202
+ env->vstart = 0;
203
+ /* set tail elements to 1s */
204
+ vext_set_elems_1s(vd, vext_vta(desc), env->vl * esz, total_elems * esz);
205
+}
206
+
207
+void HELPER(vsm4r_vs)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc)
208
+{
209
+ const uint32_t egs = 4;
210
+ uint32_t group_start = env->vstart / egs;
211
+ uint32_t group_end = env->vl / egs;
212
+ uint32_t esz = sizeof(uint32_t);
213
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
214
+
215
+ for (uint32_t i = group_start; i < group_end; ++i) {
216
+ uint32_t vstart = i * egs;
217
+ uint32_t vend = (i + 1) * egs;
218
+ uint32_t rk[4] = {0};
219
+ uint32_t tmp[8] = {0};
220
+
221
+ for (uint32_t j = 0; j < egs; ++j) {
222
+ rk[j] = *((uint32_t *)vs2 + H4(j));
223
+ }
224
+
225
+ for (uint32_t j = vstart; j < vend; ++j) {
226
+ tmp[j - vstart] = *((uint32_t *)vd + H4(j));
227
+ }
228
+
229
+ do_sm4_round(rk, tmp);
230
+
231
+ for (uint32_t j = vstart; j < vend; ++j) {
232
+ *((uint32_t *)vd + H4(j)) = tmp[egs + (j - vstart)];
233
+ }
234
+ }
235
+
236
+ env->vstart = 0;
237
+ /* set tail elements to 1s */
238
+ vext_set_elems_1s(vd, vext_vta(desc), env->vl * esz, total_elems * esz);
239
+}
240
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
241
index XXXXXXX..XXXXXXX 100644
242
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
243
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
244
@@ -XXX,XX +XXX,XX @@ static bool vghsh_check(DisasContext *s, arg_rmrr *a)
245
}
246
247
GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
248
+
249
+/*
250
+ * Zvksed
251
+ */
252
+
253
+#define ZVKSED_EGS 4
254
+
255
+static bool zvksed_check(DisasContext *s)
256
+{
257
+ int egw_bytes = ZVKSED_EGS << s->sew;
258
+ return s->cfg_ptr->ext_zvksed == true &&
259
+ require_rvv(s) &&
260
+ vext_check_isa_ill(s) &&
261
+ MAXSZ(s) >= egw_bytes &&
262
+ s->sew == MO_32;
263
+}
264
+
265
+static bool vsm4k_vi_check(DisasContext *s, arg_rmrr *a)
266
+{
267
+ return zvksed_check(s) &&
268
+ require_align(a->rd, s->lmul) &&
269
+ require_align(a->rs2, s->lmul);
270
+}
271
+
272
+GEN_VI_UNMASKED_TRANS(vsm4k_vi, vsm4k_vi_check, ZVKSED_EGS)
273
+
274
+static bool vsm4r_vv_check(DisasContext *s, arg_rmr *a)
275
+{
276
+ return zvksed_check(s) &&
277
+ require_align(a->rd, s->lmul) &&
278
+ require_align(a->rs2, s->lmul);
279
+}
280
+
281
+GEN_V_UNMASKED_TRANS(vsm4r_vv, vsm4r_vv_check, ZVKSED_EGS)
282
+
283
+static bool vsm4r_vs_check(DisasContext *s, arg_rmr *a)
284
+{
285
+ return zvksed_check(s) &&
286
+ !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) &&
287
+ require_align(a->rd, s->lmul);
288
+}
289
+
290
+GEN_V_UNMASKED_TRANS(vsm4r_vs, vsm4r_vs_check, ZVKSED_EGS)
49
--
291
--
50
2.38.1
292
2.41.0
diff view generated by jsdifflib
1
From: Mayuresh Chitale <mchitale@ventanamicro.com>
1
From: Rob Bradford <rbradford@rivosinc.com>
2
2
3
Smstateen extension specifies a mechanism to close
3
These are WARL fields - zero out the bits for unavailable counters and
4
the potential covert channels that could cause security issues.
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
This patch adds the CSRs defined in the specification and
8
Tested by modifying OpenSBI to write max value to these CSRs and upon
7
the corresponding predicates and read/write functions.
9
subsequent read the appropriate number of bits for number of PMUs is
10
enabled and the TM bit is zero in mcountinhibit.
8
11
9
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
12
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Atish Patra <atishp@rivosinc.com>
12
Message-Id: <20221016124726.102129-2-mchitale@ventanamicro.com>
15
Message-ID: <20230802124906.24197-1-rbradford@rivosinc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
17
---
15
target/riscv/cpu.h | 4 +
18
target/riscv/csr.c | 11 +++++++++--
16
target/riscv/cpu_bits.h | 37 +++++
19
1 file changed, 9 insertions(+), 2 deletions(-)
17
target/riscv/csr.c | 316 ++++++++++++++++++++++++++++++++++++++++
18
target/riscv/machine.c | 21 +++
19
4 files changed, 378 insertions(+)
20
20
21
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/cpu.h
24
+++ b/target/riscv/cpu.h
25
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
26
27
/* CSRs for execution enviornment configuration */
28
uint64_t menvcfg;
29
+ uint64_t mstateen[SMSTATEEN_MAX_COUNT];
30
+ uint64_t hstateen[SMSTATEEN_MAX_COUNT];
31
+ uint64_t sstateen[SMSTATEEN_MAX_COUNT];
32
target_ulong senvcfg;
33
uint64_t henvcfg;
34
#endif
35
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
36
bool ext_ifencei;
37
bool ext_icsr;
38
bool ext_zihintpause;
39
+ bool ext_smstateen;
40
bool ext_sstc;
41
bool ext_svinval;
42
bool ext_svnapot;
43
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/cpu_bits.h
46
+++ b/target/riscv/cpu_bits.h
47
@@ -XXX,XX +XXX,XX @@
48
/* Supervisor Configuration CSRs */
49
#define CSR_SENVCFG 0x10A
50
51
+/* Supervisor state CSRs */
52
+#define CSR_SSTATEEN0 0x10C
53
+#define CSR_SSTATEEN1 0x10D
54
+#define CSR_SSTATEEN2 0x10E
55
+#define CSR_SSTATEEN3 0x10F
56
+
57
/* Supervisor Trap Handling */
58
#define CSR_SSCRATCH 0x140
59
#define CSR_SEPC 0x141
60
@@ -XXX,XX +XXX,XX @@
61
#define CSR_HENVCFG 0x60A
62
#define CSR_HENVCFGH 0x61A
63
64
+/* Hypervisor state CSRs */
65
+#define CSR_HSTATEEN0 0x60C
66
+#define CSR_HSTATEEN0H 0x61C
67
+#define CSR_HSTATEEN1 0x60D
68
+#define CSR_HSTATEEN1H 0x61D
69
+#define CSR_HSTATEEN2 0x60E
70
+#define CSR_HSTATEEN2H 0x61E
71
+#define CSR_HSTATEEN3 0x60F
72
+#define CSR_HSTATEEN3H 0x61F
73
+
74
/* Virtual CSRs */
75
#define CSR_VSSTATUS 0x200
76
#define CSR_VSIE 0x204
77
@@ -XXX,XX +XXX,XX @@
78
#define CSR_MENVCFG 0x30A
79
#define CSR_MENVCFGH 0x31A
80
81
+/* Machine state CSRs */
82
+#define CSR_MSTATEEN0 0x30C
83
+#define CSR_MSTATEEN0H 0x31C
84
+#define CSR_MSTATEEN1 0x30D
85
+#define CSR_MSTATEEN1H 0x31D
86
+#define CSR_MSTATEEN2 0x30E
87
+#define CSR_MSTATEEN2H 0x31E
88
+#define CSR_MSTATEEN3 0x30F
89
+#define CSR_MSTATEEN3H 0x31F
90
+
91
+/* Common defines for all smstateen */
92
+#define SMSTATEEN_MAX_COUNT 4
93
+#define SMSTATEEN0_CS (1ULL << 0)
94
+#define SMSTATEEN0_FCSR (1ULL << 1)
95
+#define SMSTATEEN0_HSCONTXT (1ULL << 57)
96
+#define SMSTATEEN0_IMSIC (1ULL << 58)
97
+#define SMSTATEEN0_AIA (1ULL << 59)
98
+#define SMSTATEEN0_SVSLCT (1ULL << 60)
99
+#define SMSTATEEN0_HSENVCFG (1ULL << 62)
100
+#define SMSTATEEN_STATEEN (1ULL << 63)
101
+
102
/* Enhanced Physical Memory Protection (ePMP) */
103
#define CSR_MSECCFG 0x747
104
#define CSR_MSECCFGH 0x757
105
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
106
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
107
--- a/target/riscv/csr.c
23
--- a/target/riscv/csr.c
108
+++ b/target/riscv/csr.c
24
+++ b/target/riscv/csr.c
109
@@ -XXX,XX +XXX,XX @@ static RISCVException umode32(CPURISCVState *env, int csrno)
25
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
110
return umode(env, csrno);
26
{
111
}
27
int cidx;
112
28
PMUCTRState *counter;
113
+static RISCVException mstateen(CPURISCVState *env, int csrno)
29
+ RISCVCPU *cpu = env_archcpu(env);
114
+{
30
115
+ CPUState *cs = env_cpu(env);
31
- env->mcountinhibit = val;
116
+ RISCVCPU *cpu = RISCV_CPU(cs);
32
+ /* WARL register - disable unavailable counters; TM bit is always 0 */
33
+ env->mcountinhibit =
34
+ val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_IR);
35
36
/* Check if any other counter is also monitoring cycles/instructions */
37
for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
38
@@ -XXX,XX +XXX,XX @@ static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
39
static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
40
target_ulong val)
41
{
42
- env->mcounteren = val;
43
+ RISCVCPU *cpu = env_archcpu(env);
117
+
44
+
118
+ if (!cpu->cfg.ext_smstateen) {
45
+ /* WARL register - disable unavailable counters */
119
+ return RISCV_EXCP_ILLEGAL_INST;
46
+ env->mcounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
120
+ }
47
+ COUNTEREN_IR);
121
+
122
+ return any(env, csrno);
123
+}
124
+
125
+static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)
126
+{
127
+ CPUState *cs = env_cpu(env);
128
+ RISCVCPU *cpu = RISCV_CPU(cs);
129
+
130
+ if (!cpu->cfg.ext_smstateen) {
131
+ return RISCV_EXCP_ILLEGAL_INST;
132
+ }
133
+
134
+ if (env->priv < PRV_M) {
135
+ if (!(env->mstateen[csrno - base] & SMSTATEEN_STATEEN)) {
136
+ return RISCV_EXCP_ILLEGAL_INST;
137
+ }
138
+ }
139
+
140
+ return hmode(env, csrno);
141
+}
142
+
143
+static RISCVException hstateen(CPURISCVState *env, int csrno)
144
+{
145
+ return hstateen_pred(env, csrno, CSR_HSTATEEN0);
146
+}
147
+
148
+static RISCVException hstateenh(CPURISCVState *env, int csrno)
149
+{
150
+ return hstateen_pred(env, csrno, CSR_HSTATEEN0H);
151
+}
152
+
153
+static RISCVException sstateen(CPURISCVState *env, int csrno)
154
+{
155
+ bool virt = riscv_cpu_virt_enabled(env);
156
+ int index = csrno - CSR_SSTATEEN0;
157
+ CPUState *cs = env_cpu(env);
158
+ RISCVCPU *cpu = RISCV_CPU(cs);
159
+
160
+ if (!cpu->cfg.ext_smstateen) {
161
+ return RISCV_EXCP_ILLEGAL_INST;
162
+ }
163
+
164
+ if (env->priv < PRV_M) {
165
+ if (!(env->mstateen[index] & SMSTATEEN_STATEEN)) {
166
+ return RISCV_EXCP_ILLEGAL_INST;
167
+ }
168
+
169
+ if (virt) {
170
+ if (!(env->hstateen[index] & SMSTATEEN_STATEEN)) {
171
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
172
+ }
173
+ }
174
+ }
175
+
176
+ return smode(env, csrno);
177
+}
178
+
179
/* Checks if PointerMasking registers could be accessed */
180
static RISCVException pointer_masking(CPURISCVState *env, int csrno)
181
{
182
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
183
return RISCV_EXCP_NONE;
48
return RISCV_EXCP_NONE;
184
}
49
}
185
50
186
+static RISCVException read_mstateen(CPURISCVState *env, int csrno,
187
+ target_ulong *val)
188
+{
189
+ *val = env->mstateen[csrno - CSR_MSTATEEN0];
190
+
191
+ return RISCV_EXCP_NONE;
192
+}
193
+
194
+static RISCVException write_mstateen(CPURISCVState *env, int csrno,
195
+ uint64_t wr_mask, target_ulong new_val)
196
+{
197
+ uint64_t *reg;
198
+
199
+ reg = &env->mstateen[csrno - CSR_MSTATEEN0];
200
+ *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
201
+
202
+ return RISCV_EXCP_NONE;
203
+}
204
+
205
+static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
206
+ target_ulong new_val)
207
+{
208
+ uint64_t wr_mask = SMSTATEEN_STATEEN;
209
+
210
+ return write_mstateen(env, csrno, wr_mask, new_val);
211
+}
212
+
213
+static RISCVException write_mstateen_1_3(CPURISCVState *env, int csrno,
214
+ target_ulong new_val)
215
+{
216
+ return write_mstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
217
+}
218
+
219
+static RISCVException read_mstateenh(CPURISCVState *env, int csrno,
220
+ target_ulong *val)
221
+{
222
+ *val = env->mstateen[csrno - CSR_MSTATEEN0H] >> 32;
223
+
224
+ return RISCV_EXCP_NONE;
225
+}
226
+
227
+static RISCVException write_mstateenh(CPURISCVState *env, int csrno,
228
+ uint64_t wr_mask, target_ulong new_val)
229
+{
230
+ uint64_t *reg, val;
231
+
232
+ reg = &env->mstateen[csrno - CSR_MSTATEEN0H];
233
+ val = (uint64_t)new_val << 32;
234
+ val |= *reg & 0xFFFFFFFF;
235
+ *reg = (*reg & ~wr_mask) | (val & wr_mask);
236
+
237
+ return RISCV_EXCP_NONE;
238
+}
239
+
240
+static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
241
+ target_ulong new_val)
242
+{
243
+ uint64_t wr_mask = SMSTATEEN_STATEEN;
244
+
245
+ return write_mstateenh(env, csrno, wr_mask, new_val);
246
+}
247
+
248
+static RISCVException write_mstateenh_1_3(CPURISCVState *env, int csrno,
249
+ target_ulong new_val)
250
+{
251
+ return write_mstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
252
+}
253
+
254
+static RISCVException read_hstateen(CPURISCVState *env, int csrno,
255
+ target_ulong *val)
256
+{
257
+ int index = csrno - CSR_HSTATEEN0;
258
+
259
+ *val = env->hstateen[index] & env->mstateen[index];
260
+
261
+ return RISCV_EXCP_NONE;
262
+}
263
+
264
+static RISCVException write_hstateen(CPURISCVState *env, int csrno,
265
+ uint64_t mask, target_ulong new_val)
266
+{
267
+ int index = csrno - CSR_HSTATEEN0;
268
+ uint64_t *reg, wr_mask;
269
+
270
+ reg = &env->hstateen[index];
271
+ wr_mask = env->mstateen[index] & mask;
272
+ *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
273
+
274
+ return RISCV_EXCP_NONE;
275
+}
276
+
277
+static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
278
+ target_ulong new_val)
279
+{
280
+ uint64_t wr_mask = SMSTATEEN_STATEEN;
281
+
282
+ return write_hstateen(env, csrno, wr_mask, new_val);
283
+}
284
+
285
+static RISCVException write_hstateen_1_3(CPURISCVState *env, int csrno,
286
+ target_ulong new_val)
287
+{
288
+ return write_hstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
289
+}
290
+
291
+static RISCVException read_hstateenh(CPURISCVState *env, int csrno,
292
+ target_ulong *val)
293
+{
294
+ int index = csrno - CSR_HSTATEEN0H;
295
+
296
+ *val = (env->hstateen[index] >> 32) & (env->mstateen[index] >> 32);
297
+
298
+ return RISCV_EXCP_NONE;
299
+}
300
+
301
+static RISCVException write_hstateenh(CPURISCVState *env, int csrno,
302
+ uint64_t mask, target_ulong new_val)
303
+{
304
+ int index = csrno - CSR_HSTATEEN0H;
305
+ uint64_t *reg, wr_mask, val;
306
+
307
+ reg = &env->hstateen[index];
308
+ val = (uint64_t)new_val << 32;
309
+ val |= *reg & 0xFFFFFFFF;
310
+ wr_mask = env->mstateen[index] & mask;
311
+ *reg = (*reg & ~wr_mask) | (val & wr_mask);
312
+
313
+ return RISCV_EXCP_NONE;
314
+}
315
+
316
+static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
317
+ target_ulong new_val)
318
+{
319
+ uint64_t wr_mask = SMSTATEEN_STATEEN;
320
+
321
+ return write_hstateenh(env, csrno, wr_mask, new_val);
322
+}
323
+
324
+static RISCVException write_hstateenh_1_3(CPURISCVState *env, int csrno,
325
+ target_ulong new_val)
326
+{
327
+ return write_hstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
328
+}
329
+
330
+static RISCVException read_sstateen(CPURISCVState *env, int csrno,
331
+ target_ulong *val)
332
+{
333
+ bool virt = riscv_cpu_virt_enabled(env);
334
+ int index = csrno - CSR_SSTATEEN0;
335
+
336
+ *val = env->sstateen[index] & env->mstateen[index];
337
+ if (virt) {
338
+ *val &= env->hstateen[index];
339
+ }
340
+
341
+ return RISCV_EXCP_NONE;
342
+}
343
+
344
+static RISCVException write_sstateen(CPURISCVState *env, int csrno,
345
+ uint64_t mask, target_ulong new_val)
346
+{
347
+ bool virt = riscv_cpu_virt_enabled(env);
348
+ int index = csrno - CSR_SSTATEEN0;
349
+ uint64_t wr_mask;
350
+ uint64_t *reg;
351
+
352
+ wr_mask = env->mstateen[index] & mask;
353
+ if (virt) {
354
+ wr_mask &= env->hstateen[index];
355
+ }
356
+
357
+ reg = &env->sstateen[index];
358
+ *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
359
+
360
+ return RISCV_EXCP_NONE;
361
+}
362
+
363
+static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
364
+ target_ulong new_val)
365
+{
366
+ uint64_t wr_mask = SMSTATEEN_STATEEN;
367
+
368
+ return write_sstateen(env, csrno, wr_mask, new_val);
369
+}
370
+
371
+static RISCVException write_sstateen_1_3(CPURISCVState *env, int csrno,
372
+ target_ulong new_val)
373
+{
374
+ return write_sstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
375
+}
376
+
377
static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
378
uint64_t *ret_val,
379
uint64_t new_val, uint64_t wr_mask)
380
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
381
[CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh,
382
.min_priv_ver = PRIV_VERSION_1_12_0 },
383
384
+ /* Smstateen extension CSRs */
385
+ [CSR_MSTATEEN0] = { "mstateen0", mstateen, read_mstateen, write_mstateen0,
386
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
387
+ [CSR_MSTATEEN0H] = { "mstateen0h", mstateen, read_mstateenh,
388
+ write_mstateen0h,
389
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
390
+ [CSR_MSTATEEN1] = { "mstateen1", mstateen, read_mstateen,
391
+ write_mstateen_1_3,
392
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
393
+ [CSR_MSTATEEN1H] = { "mstateen1h", mstateen, read_mstateenh,
394
+ write_mstateenh_1_3,
395
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
396
+ [CSR_MSTATEEN2] = { "mstateen2", mstateen, read_mstateen,
397
+ write_mstateen_1_3,
398
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
399
+ [CSR_MSTATEEN2H] = { "mstateen2h", mstateen, read_mstateenh,
400
+ write_mstateenh_1_3,
401
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
402
+ [CSR_MSTATEEN3] = { "mstateen3", mstateen, read_mstateen,
403
+ write_mstateen_1_3,
404
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
405
+ [CSR_MSTATEEN3H] = { "mstateen3h", mstateen, read_mstateenh,
406
+ write_mstateenh_1_3,
407
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
408
+ [CSR_HSTATEEN0] = { "hstateen0", hstateen, read_hstateen, write_hstateen0,
409
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
410
+ [CSR_HSTATEEN0H] = { "hstateen0h", hstateenh, read_hstateenh,
411
+ write_hstateen0h,
412
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
413
+ [CSR_HSTATEEN1] = { "hstateen1", hstateen, read_hstateen,
414
+ write_hstateen_1_3,
415
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
416
+ [CSR_HSTATEEN1H] = { "hstateen1h", hstateenh, read_hstateenh,
417
+ write_hstateenh_1_3,
418
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
419
+ [CSR_HSTATEEN2] = { "hstateen2", hstateen, read_hstateen,
420
+ write_hstateen_1_3,
421
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
422
+ [CSR_HSTATEEN2H] = { "hstateen2h", hstateenh, read_hstateenh,
423
+ write_hstateenh_1_3,
424
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
425
+ [CSR_HSTATEEN3] = { "hstateen3", hstateen, read_hstateen,
426
+ write_hstateen_1_3,
427
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
428
+ [CSR_HSTATEEN3H] = { "hstateen3h", hstateenh, read_hstateenh,
429
+ write_hstateenh_1_3,
430
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
431
+ [CSR_SSTATEEN0] = { "sstateen0", sstateen, read_sstateen, write_sstateen0,
432
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
433
+ [CSR_SSTATEEN1] = { "sstateen1", sstateen, read_sstateen,
434
+ write_sstateen_1_3,
435
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
436
+ [CSR_SSTATEEN2] = { "sstateen2", sstateen, read_sstateen,
437
+ write_sstateen_1_3,
438
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
439
+ [CSR_SSTATEEN3] = { "sstateen3", sstateen, read_sstateen,
440
+ write_sstateen_1_3,
441
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
442
+
443
/* Supervisor Trap Setup */
444
[CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus,
445
NULL, read_sstatus_i128 },
446
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
447
index XXXXXXX..XXXXXXX 100644
448
--- a/target/riscv/machine.c
449
+++ b/target/riscv/machine.c
450
@@ -XXX,XX +XXX,XX @@ static int riscv_cpu_post_load(void *opaque, int version_id)
451
return 0;
452
}
453
454
+static bool smstateen_needed(void *opaque)
455
+{
456
+ RISCVCPU *cpu = opaque;
457
+
458
+ return cpu->cfg.ext_smstateen;
459
+}
460
+
461
+static const VMStateDescription vmstate_smstateen = {
462
+ .name = "cpu/smtateen",
463
+ .version_id = 1,
464
+ .minimum_version_id = 1,
465
+ .needed = smstateen_needed,
466
+ .fields = (VMStateField[]) {
467
+ VMSTATE_UINT64_ARRAY(env.mstateen, RISCVCPU, 4),
468
+ VMSTATE_UINT64_ARRAY(env.hstateen, RISCVCPU, 4),
469
+ VMSTATE_UINT64_ARRAY(env.sstateen, RISCVCPU, 4),
470
+ VMSTATE_END_OF_LIST()
471
+ }
472
+};
473
+
474
static bool envcfg_needed(void *opaque)
475
{
476
RISCVCPU *cpu = opaque;
477
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
478
&vmstate_kvmtimer,
479
&vmstate_envcfg,
480
&vmstate_debug,
481
+ &vmstate_smstateen,
482
NULL
483
}
484
};
485
--
51
--
486
2.38.1
52
2.41.0
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
There was a typo using opc_addi instead of opc_add with the
3
RVA23 Profiles states:
4
two registers. While we're at it, simplify the gating test
4
The RVA23 profiles are intended to be used for 64-bit application
5
to al == bl to improve dynamic scheduling even when the
5
processors that will run rich OS stacks from standard binary OS
6
output register does not overlap the inputs.
6
distributions and with a substantial number of third-party binary user
7
applications that will be supported over a considerable length of time
8
in the field.
7
9
8
Reported-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
10
The chapter 4 of the unprivileged spec introduces the Zihintntl extension
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
and Zihintntl is a mandatory extension presented in RVA23 Profiles, whose
12
purpose is to enable application and operating system portability across
13
different implementations. Thus the DTS should contain the Zihintntl ISA
14
string in order to pass to software.
15
16
The unprivileged spec states:
17
Like any HINTs, these instructions may be freely ignored. Hence, although
18
they are described in terms of cache-based memory hierarchies, they do not
19
mandate the provision of caches.
20
21
These instructions are encoded with non-used opcode, e.g. ADD x0, x0, x2,
22
which QEMU already supports, and QEMU does not emulate cache. Therefore
23
these instructions can be considered as a no-op, and we only need to add
24
a new property for the Zihintntl extension.
25
26
Reviewed-by: Frank Chang <frank.chang@sifive.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
27
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20221020233836.2341671-1-richard.henderson@linaro.org>
28
Signed-off-by: Jason Chien <jason.chien@sifive.com>
29
Message-ID: <20230726074049.19505-2-jason.chien@sifive.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
31
---
14
tcg/riscv/tcg-target.c.inc | 10 ++++++++--
32
target/riscv/cpu_cfg.h | 1 +
15
1 file changed, 8 insertions(+), 2 deletions(-)
33
target/riscv/cpu.c | 2 ++
34
2 files changed, 3 insertions(+)
16
35
17
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
36
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
18
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
19
--- a/tcg/riscv/tcg-target.c.inc
38
--- a/target/riscv/cpu_cfg.h
20
+++ b/tcg/riscv/tcg-target.c.inc
39
+++ b/target/riscv/cpu_cfg.h
21
@@ -XXX,XX +XXX,XX @@ static void tcg_out_addsub2(TCGContext *s,
40
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
22
if (cbl) {
41
bool ext_icbom;
23
tcg_out_opc_imm(s, opc_addi, rl, al, bl);
42
bool ext_icboz;
24
tcg_out_opc_imm(s, OPC_SLTIU, TCG_REG_TMP0, rl, bl);
43
bool ext_zicond;
25
- } else if (rl == al && rl == bl) {
44
+ bool ext_zihintntl;
26
+ } else if (al == bl) {
45
bool ext_zihintpause;
27
+ /*
46
bool ext_smstateen;
28
+ * If the input regs overlap, this is a simple doubling
47
bool ext_sstc;
29
+ * and carry-out is the input msb. This special case is
48
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
30
+ * required when the output reg overlaps the input,
49
index XXXXXXX..XXXXXXX 100644
31
+ * but we might as well use it always.
50
--- a/target/riscv/cpu.c
32
+ */
51
+++ b/target/riscv/cpu.c
33
tcg_out_opc_imm(s, OPC_SLTI, TCG_REG_TMP0, al, 0);
52
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
34
- tcg_out_opc_reg(s, opc_addi, rl, al, bl);
53
ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
35
+ tcg_out_opc_reg(s, opc_add, rl, al, al);
54
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
36
} else {
55
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
37
tcg_out_opc_reg(s, opc_add, rl, al, bl);
56
+ ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl),
38
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_TMP0,
57
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
58
ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
59
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
60
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
61
DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
62
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
63
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
64
+ DEFINE_PROP_BOOL("Zihintntl", RISCVCPU, cfg.ext_zihintntl, true),
65
DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
66
DEFINE_PROP_BOOL("Zawrs", RISCVCPU, cfg.ext_zawrs, true),
67
DEFINE_PROP_BOOL("Zfa", RISCVCPU, cfg.ext_zfa, true),
39
--
68
--
40
2.38.1
69
2.41.0
diff view generated by jsdifflib
1
From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
2
3
Commit 40244040a7a changed the way the S irqs are numbered. This breaks when
3
Commit a47842d ("riscv: Add support for the Zfa extension") implemented the zfa extension.
4
using numa configuration, e.g.:
4
However, it has some typos for fleq.d and fltq.d. Both of them misused the fltq.s
5
./qemu-system-riscv64 -nographic -machine virt,dumpdtb=numa-tree.dtb \
5
helper function.
6
-m 2G -smp cpus=16 \
7
         -object memory-backend-ram,id=mem0,size=512M \
8
         -object memory-backend-ram,id=mem1,size=512M \
9
         -object memory-backend-ram,id=mem2,size=512M \
10
         -object memory-backend-ram,id=mem3,size=512M \
11
         -numa node,cpus=0-3,memdev=mem0,nodeid=0 \
12
         -numa node,cpus=4-7,memdev=mem1,nodeid=1 \
13
         -numa node,cpus=8-11,memdev=mem2,nodeid=2 \
14
         -numa node,cpus=12-15,memdev=mem3,nodeid=3
15
leads to:
16
Unexpected error in object_property_find_err() at ../qom/object.c:1304:
17
qemu-system-riscv64: Property 'riscv.sifive.plic.unnamed-gpio-out[8]' not
18
found
19
6
20
This patch makes the nubering of the S irqs identical to what it was before.
7
Fixes: a47842d ("riscv: Add support for the Zfa extension")
21
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
22
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
23
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
24
Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
11
Message-ID: <20230728003906.768-1-zhiwei_liu@linux.alibaba.com>
25
Message-Id: <20221114135122.1668703-1-frederic.petrot@univ-grenoble-alpes.fr>
26
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
---
13
---
28
hw/intc/sifive_plic.c | 4 ++--
14
target/riscv/insn_trans/trans_rvzfa.c.inc | 4 ++--
29
1 file changed, 2 insertions(+), 2 deletions(-)
15
1 file changed, 2 insertions(+), 2 deletions(-)
30
16
31
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
17
diff --git a/target/riscv/insn_trans/trans_rvzfa.c.inc b/target/riscv/insn_trans/trans_rvzfa.c.inc
32
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/intc/sifive_plic.c
19
--- a/target/riscv/insn_trans/trans_rvzfa.c.inc
34
+++ b/hw/intc/sifive_plic.c
20
+++ b/target/riscv/insn_trans/trans_rvzfa.c.inc
35
@@ -XXX,XX +XXX,XX @@ DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
21
@@ -XXX,XX +XXX,XX @@ bool trans_fleq_d(DisasContext *ctx, arg_fleq_d *a)
36
CPUState *cpu = qemu_get_cpu(cpu_num);
22
TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
37
23
TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
38
if (plic->addr_config[i].mode == PLICMode_M) {
24
39
- qdev_connect_gpio_out(dev, num_harts - plic->hartid_base + cpu_num,
25
- gen_helper_fltq_s(dest, cpu_env, src1, src2);
40
+ qdev_connect_gpio_out(dev, cpu_num - hartid_base + num_harts,
26
+ gen_helper_fleq_d(dest, cpu_env, src1, src2);
41
qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
27
gen_set_gpr(ctx, a->rd, dest);
42
}
28
return true;
43
if (plic->addr_config[i].mode == PLICMode_S) {
29
}
44
- qdev_connect_gpio_out(dev, cpu_num,
30
@@ -XXX,XX +XXX,XX @@ bool trans_fltq_d(DisasContext *ctx, arg_fltq_d *a)
45
+ qdev_connect_gpio_out(dev, cpu_num - hartid_base,
31
TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
46
qdev_get_gpio_in(DEVICE(cpu), IRQ_S_EXT));
32
TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
47
}
33
48
}
34
- gen_helper_fltq_s(dest, cpu_env, src1, src2);
35
+ gen_helper_fltq_d(dest, cpu_env, src1, src2);
36
gen_set_gpr(ctx, a->rd, dest);
37
return true;
38
}
49
--
39
--
50
2.38.1
40
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
The pending register upper limit is currently set to
3
When writing the upper mtime, we should keep the original lower mtime
4
plic->num_sources >> 3, which is wrong, e.g.: considering
4
whose value is given by cpu_riscv_read_rtc() instead of
5
plic->num_sources is 7, the upper limit becomes 0 which fails
5
cpu_riscv_read_rtc_raw(). The same logic applies to writes to lower mtime.
6
the range check if reading the pending register at pending_base.
7
6
8
Fixes: 1e24429e40df ("SiFive RISC-V PLIC Block")
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
9
Signed-off-by: Bin Meng <bmeng@tinylab.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20221211030829.802437-16-bmeng@tinylab.org>
9
Message-ID: <20230728082502.26439-1-jason.chien@sifive.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
11
---
14
hw/intc/sifive_plic.c | 5 +++--
12
hw/intc/riscv_aclint.c | 5 +++--
15
1 file changed, 3 insertions(+), 2 deletions(-)
13
1 file changed, 3 insertions(+), 2 deletions(-)
16
14
17
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
15
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/sifive_plic.c
17
--- a/hw/intc/riscv_aclint.c
20
+++ b/hw/intc/sifive_plic.c
18
+++ b/hw/intc/riscv_aclint.c
21
@@ -XXX,XX +XXX,XX @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size)
19
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
22
uint32_t irq = (addr - plic->priority_base) >> 2;
20
return;
23
21
} else if (addr == mtimer->time_base || addr == mtimer->time_base + 4) {
24
return plic->source_priority[irq];
22
uint64_t rtc_r = cpu_riscv_read_rtc_raw(mtimer->timebase_freq);
25
- } else if (addr_between(addr, plic->pending_base, plic->num_sources >> 3)) {
23
+ uint64_t rtc = cpu_riscv_read_rtc(mtimer);
26
+ } else if (addr_between(addr, plic->pending_base,
24
27
+ (plic->num_sources + 31) >> 3)) {
25
if (addr == mtimer->time_base) {
28
uint32_t word = (addr - plic->pending_base) >> 2;
26
if (size == 4) {
29
27
/* time_lo for RV32/RV64 */
30
return plic->pending[word];
28
- mtimer->time_delta = ((rtc_r & ~0xFFFFFFFFULL) | value) - rtc_r;
31
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_write(void *opaque, hwaddr addr, uint64_t value,
29
+ mtimer->time_delta = ((rtc & ~0xFFFFFFFFULL) | value) - rtc_r;
32
sifive_plic_update(plic);
30
} else {
33
}
31
/* time for RV64 */
34
} else if (addr_between(addr, plic->pending_base,
32
mtimer->time_delta = value - rtc_r;
35
- plic->num_sources >> 3)) {
33
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
36
+ (plic->num_sources + 31) >> 3)) {
34
} else {
37
qemu_log_mask(LOG_GUEST_ERROR,
35
if (size == 4) {
38
"%s: invalid pending write: 0x%" HWADDR_PRIx "",
36
/* time_hi for RV32/RV64 */
39
__func__, addr);
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",
40
--
42
--
41
2.38.1
43
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
Since priv spec v1.12, MRET and SRET now clear mstatus.MPRV when
3
The variables whose values are given by cpu_riscv_read_rtc() should be named
4
leaving M-mode.
4
"rtc". The variables whose value are given by cpu_riscv_read_rtc_raw()
5
should be named "rtc_r".
5
6
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20221207090037.281452-2-bmeng@tinylab.org>
9
Message-ID: <20230728082502.26439-2-jason.chien@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
---
11
target/riscv/op_helper.c | 6 ++++++
12
hw/intc/riscv_aclint.c | 6 +++---
12
1 file changed, 6 insertions(+)
13
1 file changed, 3 insertions(+), 3 deletions(-)
13
14
14
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
15
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/op_helper.c
17
--- a/hw/intc/riscv_aclint.c
17
+++ b/target/riscv/op_helper.c
18
+++ b/hw/intc/riscv_aclint.c
18
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env)
19
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
19
get_field(mstatus, MSTATUS_SPIE));
20
uint64_t next;
20
mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
21
uint64_t diff;
21
mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
22
22
+ if (env->priv_ver >= PRIV_VERSION_1_12_0) {
23
- uint64_t rtc_r = cpu_riscv_read_rtc(mtimer);
23
+ mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
24
+ uint64_t rtc = cpu_riscv_read_rtc(mtimer);
24
+ }
25
25
env->mstatus = mstatus;
26
/* Compute the relative hartid w.r.t the socket */
26
27
hartid = hartid - mtimer->hartid_base;
27
if (riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
28
28
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mret(CPURISCVState *env)
29
mtimer->timecmp[hartid] = value;
29
mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
30
- if (mtimer->timecmp[hartid] <= rtc_r) {
30
mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
31
+ if (mtimer->timecmp[hartid] <= rtc) {
31
mstatus = set_field(mstatus, MSTATUS_MPV, 0);
32
/*
32
+ if ((env->priv_ver >= PRIV_VERSION_1_12_0) && (prev_priv != PRV_M)) {
33
* If we're setting an MTIMECMP value in the "past",
33
+ mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
34
* immediately raise the timer interrupt
34
+ }
35
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
35
env->mstatus = mstatus;
36
36
riscv_cpu_set_mode(env, prev_priv);
37
/* otherwise, set up the future timer interrupt */
38
qemu_irq_lower(mtimer->timer_irqs[hartid]);
39
- diff = mtimer->timecmp[hartid] - rtc_r;
40
+ diff = mtimer->timecmp[hartid] - rtc;
41
/* back to ns (note args switched in muldiv64) */
42
uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
37
43
38
--
44
--
39
2.38.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
When QEMU is not in icount mode, execute instruction one by one. The
3
We should not use types dependend on host arch for target_ucontext.
4
tdata1 can be read directly.
4
This bug is found when run rv32 applications.
5
6
When QEMU is in icount mode, use a timer to simulate the itrigger. The
7
tdata1 may be not right because of lazy update of count in tdata1. Thus,
8
We should pack the adjusted count into tdata1 before read it back.
9
5
10
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
6
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-Id: <20221013062946.7530-4-zhiwei_liu@linux.alibaba.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-ID: <20230811055438.1945-1-zhiwei_liu@linux.alibaba.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
12
---
15
target/riscv/debug.c | 72 ++++++++++++++++++++++++++++++++++++++++++++
13
linux-user/riscv/signal.c | 4 ++--
16
1 file changed, 72 insertions(+)
14
1 file changed, 2 insertions(+), 2 deletions(-)
17
15
18
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
16
diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/debug.c
18
--- a/linux-user/riscv/signal.c
21
+++ b/target/riscv/debug.c
19
+++ b/linux-user/riscv/signal.c
22
@@ -XXX,XX +XXX,XX @@ void riscv_itrigger_update_priv(CPURISCVState *env)
20
@@ -XXX,XX +XXX,XX @@ struct target_sigcontext {
23
riscv_itrigger_update_count(env);
21
}; /* cf. riscv-linux:arch/riscv/include/uapi/asm/ptrace.h */
24
}
22
25
23
struct target_ucontext {
26
+static target_ulong itrigger_validate(CPURISCVState *env,
24
- unsigned long uc_flags;
27
+ target_ulong ctrl)
25
- struct target_ucontext *uc_link;
28
+{
26
+ abi_ulong uc_flags;
29
+ target_ulong val;
27
+ abi_ptr uc_link;
30
+
28
target_stack_t uc_stack;
31
+ /* validate the generic part first */
29
target_sigset_t uc_sigmask;
32
+ val = tdata1_validate(env, ctrl, TRIGGER_TYPE_INST_CNT);
30
uint8_t __unused[1024 / 8 - sizeof(target_sigset_t)];
33
+
34
+ /* validate unimplemented (always zero) bits */
35
+ warn_always_zero_bit(ctrl, ITRIGGER_ACTION, "action");
36
+ warn_always_zero_bit(ctrl, ITRIGGER_HIT, "hit");
37
+ warn_always_zero_bit(ctrl, ITRIGGER_PENDING, "pending");
38
+
39
+ /* keep the mode and attribute bits */
40
+ val |= ctrl & (ITRIGGER_VU | ITRIGGER_VS | ITRIGGER_U | ITRIGGER_S |
41
+ ITRIGGER_M | ITRIGGER_COUNT);
42
+
43
+ return val;
44
+}
45
+
46
+static void itrigger_reg_write(CPURISCVState *env, target_ulong index,
47
+ int tdata_index, target_ulong val)
48
+{
49
+ target_ulong new_val;
50
+
51
+ switch (tdata_index) {
52
+ case TDATA1:
53
+ /* set timer for icount */
54
+ new_val = itrigger_validate(env, val);
55
+ if (new_val != env->tdata1[index]) {
56
+ env->tdata1[index] = new_val;
57
+ if (icount_enabled()) {
58
+ env->last_icount = icount_get_raw();
59
+ /* set the count to timer */
60
+ timer_mod(env->itrigger_timer[index],
61
+ env->last_icount + itrigger_get_count(env, index));
62
+ }
63
+ }
64
+ break;
65
+ case TDATA2:
66
+ qemu_log_mask(LOG_UNIMP,
67
+ "tdata2 is not supported for icount trigger\n");
68
+ break;
69
+ case TDATA3:
70
+ qemu_log_mask(LOG_UNIMP,
71
+ "tdata3 is not supported for icount trigger\n");
72
+ break;
73
+ default:
74
+ g_assert_not_reached();
75
+ }
76
+
77
+ return;
78
+}
79
+
80
+static int itrigger_get_adjust_count(CPURISCVState *env)
81
+{
82
+ int count = itrigger_get_count(env, env->trigger_cur), executed;
83
+ if ((count != 0) && check_itrigger_priv(env, env->trigger_cur)) {
84
+ executed = icount_get_raw() - env->last_icount;
85
+ count += executed;
86
+ }
87
+ return count;
88
+}
89
+
90
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
91
{
92
+ int trigger_type;
93
switch (tdata_index) {
94
case TDATA1:
95
+ trigger_type = extract_trigger_type(env, env->tdata1[env->trigger_cur]);
96
+ if ((trigger_type == TRIGGER_TYPE_INST_CNT) && icount_enabled()) {
97
+ return deposit64(env->tdata1[env->trigger_cur], 10, 14,
98
+ itrigger_get_adjust_count(env));
99
+ }
100
return env->tdata1[env->trigger_cur];
101
case TDATA2:
102
return env->tdata2[env->trigger_cur];
103
@@ -XXX,XX +XXX,XX @@ void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val)
104
type6_reg_write(env, env->trigger_cur, tdata_index, val);
105
break;
106
case TRIGGER_TYPE_INST_CNT:
107
+ itrigger_reg_write(env, env->trigger_cur, tdata_index, val);
108
+ break;
109
case TRIGGER_TYPE_INT:
110
case TRIGGER_TYPE_EXCP:
111
case TRIGGER_TYPE_EXT_SRC:
112
--
31
--
113
2.38.1
32
2.41.0
33
34
diff view generated by jsdifflib
1
From: Conor Dooley <conor.dooley@microchip.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
The system controller on PolarFire SoC is access via a mailbox. The
3
In this patch, we create the APLIC and IMSIC FDT helper functions and
4
control registers for this mailbox lie in the "IOSCB" region & the
4
remove M mode AIA devices when using KVM acceleration.
5
interrupt is cleared via write to the "SYSREG" region. It also has a
6
QSPI controller, usually connected to a flash chip, that is used for
7
storing FPGA bitstreams and used for In-Application Programming (IAP).
8
5
9
Linux has an implementation of the system controller, through which the
6
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
10
hwrng is accessed, leading to load/store access faults.
7
Reviewed-by: Jim Shu <jim.shu@sifive.com>
11
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
Add the QSPI as unimplemented and a very basic (effectively
9
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
13
unimplemented) version of the system controller's mailbox. Rather than
10
Message-ID: <20230727102439.22554-2-yongxuan.wang@sifive.com>
14
purely marking the regions as unimplemented, service the mailbox
15
requests by reporting failures and raising the interrupt so a guest can
16
better handle the lack of support.
17
18
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
19
Acked-by: Alistair Francis <alistair.francis@wdc.com>
20
Message-Id: <20221117225518.4102575-4-conor@kernel.org>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
---
12
---
23
include/hw/misc/mchp_pfsoc_ioscb.h | 3 ++
13
hw/riscv/virt.c | 290 +++++++++++++++++++++++-------------------------
24
include/hw/misc/mchp_pfsoc_sysreg.h | 1 +
14
1 file changed, 137 insertions(+), 153 deletions(-)
25
include/hw/riscv/microchip_pfsoc.h | 1 +
26
hw/misc/mchp_pfsoc_ioscb.c | 72 ++++++++++++++++++++++++++++-
27
hw/misc/mchp_pfsoc_sysreg.c | 18 ++++++--
28
hw/riscv/microchip_pfsoc.c | 6 +++
29
6 files changed, 95 insertions(+), 6 deletions(-)
30
15
31
diff --git a/include/hw/misc/mchp_pfsoc_ioscb.h b/include/hw/misc/mchp_pfsoc_ioscb.h
16
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
32
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
33
--- a/include/hw/misc/mchp_pfsoc_ioscb.h
18
--- a/hw/riscv/virt.c
34
+++ b/include/hw/misc/mchp_pfsoc_ioscb.h
19
+++ b/hw/riscv/virt.c
35
@@ -XXX,XX +XXX,XX @@ typedef struct MchpPfSoCIoscbState {
20
@@ -XXX,XX +XXX,XX @@ static uint32_t imsic_num_bits(uint32_t count)
36
MemoryRegion lane01;
21
return ret;
37
MemoryRegion lane23;
22
}
38
MemoryRegion ctrl;
23
39
+ MemoryRegion qspixip;
24
-static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
40
+ MemoryRegion mailbox;
25
- uint32_t *phandle, uint32_t *intc_phandles,
41
MemoryRegion cfg;
26
- uint32_t *msi_m_phandle, uint32_t *msi_s_phandle)
42
MemoryRegion ccc;
27
+static void create_fdt_one_imsic(RISCVVirtState *s, hwaddr base_addr,
43
MemoryRegion pll_mss;
28
+ uint32_t *intc_phandles, uint32_t msi_phandle,
44
@@ -XXX,XX +XXX,XX @@ typedef struct MchpPfSoCIoscbState {
29
+ bool m_mode, uint32_t imsic_guest_bits)
45
MemoryRegion cfm_sgmii;
30
{
46
MemoryRegion bc_sgmii;
31
int cpu, socket;
47
MemoryRegion io_calib_sgmii;
32
char *imsic_name;
48
+ qemu_irq irq;
33
MachineState *ms = MACHINE(s);
49
} MchpPfSoCIoscbState;
34
int socket_count = riscv_socket_count(ms);
50
35
- uint32_t imsic_max_hart_per_socket, imsic_guest_bits;
51
#define TYPE_MCHP_PFSOC_IOSCB "mchp.pfsoc.ioscb"
36
+ uint32_t imsic_max_hart_per_socket;
52
diff --git a/include/hw/misc/mchp_pfsoc_sysreg.h b/include/hw/misc/mchp_pfsoc_sysreg.h
37
uint32_t *imsic_cells, *imsic_regs, imsic_addr, imsic_size;
53
index XXXXXXX..XXXXXXX 100644
38
54
--- a/include/hw/misc/mchp_pfsoc_sysreg.h
39
- *msi_m_phandle = (*phandle)++;
55
+++ b/include/hw/misc/mchp_pfsoc_sysreg.h
40
- *msi_s_phandle = (*phandle)++;
56
@@ -XXX,XX +XXX,XX @@
41
imsic_cells = g_new0(uint32_t, ms->smp.cpus * 2);
57
typedef struct MchpPfSoCSysregState {
42
imsic_regs = g_new0(uint32_t, socket_count * 4);
58
SysBusDevice parent;
43
59
MemoryRegion sysreg;
44
- /* M-level IMSIC node */
60
+ qemu_irq irq;
45
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
61
} MchpPfSoCSysregState;
46
imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
62
47
- imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
63
#define TYPE_MCHP_PFSOC_SYSREG "mchp.pfsoc.sysreg"
48
+ imsic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
64
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
49
}
65
index XXXXXXX..XXXXXXX 100644
50
- imsic_max_hart_per_socket = 0;
66
--- a/include/hw/riscv/microchip_pfsoc.h
51
- for (socket = 0; socket < socket_count; socket++) {
67
+++ b/include/hw/riscv/microchip_pfsoc.h
52
- imsic_addr = memmap[VIRT_IMSIC_M].base +
68
@@ -XXX,XX +XXX,XX @@ enum {
53
- socket * VIRT_IMSIC_GROUP_MAX_SIZE;
69
MICROCHIP_PFSOC_MMUART2_IRQ = 92,
54
- imsic_size = IMSIC_HART_SIZE(0) * s->soc[socket].num_harts;
70
MICROCHIP_PFSOC_MMUART3_IRQ = 93,
55
- imsic_regs[socket * 4 + 0] = 0;
71
MICROCHIP_PFSOC_MMUART4_IRQ = 94,
56
- imsic_regs[socket * 4 + 1] = cpu_to_be32(imsic_addr);
72
+ MICROCHIP_PFSOC_MAILBOX_IRQ = 96,
57
- imsic_regs[socket * 4 + 2] = 0;
73
};
58
- imsic_regs[socket * 4 + 3] = cpu_to_be32(imsic_size);
74
59
- if (imsic_max_hart_per_socket < s->soc[socket].num_harts) {
75
#define MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT 1
60
- imsic_max_hart_per_socket = s->soc[socket].num_harts;
76
diff --git a/hw/misc/mchp_pfsoc_ioscb.c b/hw/misc/mchp_pfsoc_ioscb.c
61
- }
77
index XXXXXXX..XXXXXXX 100644
62
- }
78
--- a/hw/misc/mchp_pfsoc_ioscb.c
63
- imsic_name = g_strdup_printf("/soc/imsics@%lx",
79
+++ b/hw/misc/mchp_pfsoc_ioscb.c
64
- (unsigned long)memmap[VIRT_IMSIC_M].base);
80
@@ -XXX,XX +XXX,XX @@
65
- qemu_fdt_add_subnode(ms->fdt, imsic_name);
81
#include "qemu/bitops.h"
66
- qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
82
#include "qemu/log.h"
67
- "riscv,imsics");
83
#include "qapi/error.h"
68
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
84
+#include "hw/irq.h"
69
- FDT_IMSIC_INT_CELLS);
85
#include "hw/sysbus.h"
70
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
86
#include "hw/misc/mchp_pfsoc_ioscb.h"
71
- NULL, 0);
87
72
- qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
88
@@ -XXX,XX +XXX,XX @@
73
- NULL, 0);
89
#define IOSCB_WHOLE_REG_SIZE 0x10000000
74
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
90
#define IOSCB_SUBMOD_REG_SIZE 0x1000
75
- imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
91
#define IOSCB_CCC_REG_SIZE 0x2000000
76
- qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
92
+#define IOSCB_CTRL_REG_SIZE 0x800
77
- socket_count * sizeof(uint32_t) * 4);
93
+#define IOSCB_QSPIXIP_REG_SIZE 0x200
78
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
94
+
79
- VIRT_IRQCHIP_NUM_MSIS);
95
80
- if (socket_count > 1) {
96
/*
81
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
97
* There are many sub-modules in the IOSCB module.
82
- imsic_num_bits(imsic_max_hart_per_socket));
98
@@ -XXX,XX +XXX,XX @@
83
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
99
#define IOSCB_LANE01_BASE 0x06500000
84
- imsic_num_bits(socket_count));
100
#define IOSCB_LANE23_BASE 0x06510000
85
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
101
#define IOSCB_CTRL_BASE 0x07020000
86
- IMSIC_MMIO_GROUP_MIN_SHIFT);
102
+#define IOSCB_QSPIXIP_BASE 0x07020100
87
- }
103
+#define IOSCB_MAILBOX_BASE 0x07020800
88
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_m_phandle);
104
#define IOSCB_CFG_BASE 0x07080000
89
-
105
#define IOSCB_CCC_BASE 0x08000000
90
- g_free(imsic_name);
106
#define IOSCB_PLL_MSS_BASE 0x0E001000
91
107
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps mchp_pfsoc_io_calib_ddr_ops = {
92
- /* S-level IMSIC node */
108
.endianness = DEVICE_LITTLE_ENDIAN,
93
- for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
109
};
94
- imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
110
95
- imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
111
+#define SERVICES_CR 0x50
96
- }
112
+#define SERVICES_SR 0x54
97
- imsic_guest_bits = imsic_num_bits(s->aia_guests + 1);
113
+#define SERVICES_STATUS_SHIFT 16
98
imsic_max_hart_per_socket = 0;
114
+
99
for (socket = 0; socket < socket_count; socket++) {
115
+static uint64_t mchp_pfsoc_ctrl_read(void *opaque, hwaddr offset,
100
- imsic_addr = memmap[VIRT_IMSIC_S].base +
116
+ unsigned size)
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)
117
+{
173
+{
118
+ uint32_t val = 0;
174
+ *msi_m_phandle = (*phandle)++;
119
+
175
+ *msi_s_phandle = (*phandle)++;
120
+ switch (offset) {
176
+
121
+ case SERVICES_SR:
177
+ if (!kvm_enabled()) {
122
+ /*
178
+ /* M-level IMSIC node */
123
+ * Although some services have no error codes, most do. All services
179
+ create_fdt_one_imsic(s, memmap[VIRT_IMSIC_M].base, intc_phandles,
124
+ * that do implement errors, begin their error codes at 1. Treat all
180
+ *msi_m_phandle, true, 0);
125
+ * service requests as failures & return 1.
126
+ * See the "PolarFire® FPGA and PolarFire SoC FPGA System Services"
127
+ * user guide for more information on service error codes.
128
+ */
129
+ val = 1u << SERVICES_STATUS_SHIFT;
130
+ break;
131
+ default:
132
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
133
+ "(size %d, offset 0x%" HWADDR_PRIx ")\n",
134
+ __func__, size, offset);
135
+ }
181
+ }
136
+
182
+
137
+ return val;
183
+ /* S-level IMSIC node */
184
+ create_fdt_one_imsic(s, memmap[VIRT_IMSIC_S].base, intc_phandles,
185
+ *msi_s_phandle, false,
186
+ imsic_num_bits(s->aia_guests + 1));
187
+
138
+}
188
+}
139
+
189
+
140
+static void mchp_pfsoc_ctrl_write(void *opaque, hwaddr offset,
190
+static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
141
+ uint64_t value, unsigned size)
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);
254
+ }
255
+
256
riscv_socket_fdt_write_id(ms, aplic_name, socket);
257
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_m_phandle);
258
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_phandle);
259
+
260
g_free(aplic_name);
261
+ g_free(aplic_cells);
262
+}
263
264
- /* S-level APLIC node */
265
- for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
266
- aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
267
- aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
268
+static void create_fdt_socket_aplic(RISCVVirtState *s,
269
+ const MemMapEntry *memmap, int socket,
270
+ uint32_t msi_m_phandle,
271
+ uint32_t msi_s_phandle,
272
+ uint32_t *phandle,
273
+ uint32_t *intc_phandles,
274
+ uint32_t *aplic_phandles)
142
+{
275
+{
143
+ MchpPfSoCIoscbState *s = opaque;
276
+ char *aplic_name;
144
+
277
+ unsigned long aplic_addr;
145
+ switch (offset) {
278
+ MachineState *ms = MACHINE(s);
146
+ case SERVICES_CR:
279
+ uint32_t aplic_m_phandle, aplic_s_phandle;
147
+ qemu_irq_raise(s->irq);
280
+
148
+ break;
281
+ aplic_m_phandle = (*phandle)++;
149
+ default:
282
+ aplic_s_phandle = (*phandle)++;
150
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
283
+
151
+ "(size %d, value 0x%" PRIx64
284
+ if (!kvm_enabled()) {
152
+ ", offset 0x%" HWADDR_PRIx ")\n",
285
+ /* M-level APLIC node */
153
+ __func__, size, value, offset);
286
+ aplic_addr = memmap[VIRT_APLIC_M].base +
154
+ }
287
+ (memmap[VIRT_APLIC_M].size * socket);
155
+}
288
+ create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_M].size,
156
+
289
+ msi_m_phandle, intc_phandles,
157
+static const MemoryRegionOps mchp_pfsoc_ctrl_ops = {
290
+ aplic_m_phandle, aplic_s_phandle,
158
+ .read = mchp_pfsoc_ctrl_read,
291
+ true);
159
+ .write = mchp_pfsoc_ctrl_write,
292
}
160
+ .endianness = DEVICE_LITTLE_ENDIAN,
293
+
161
+};
294
+ /* S-level APLIC node */
162
+
295
aplic_addr = memmap[VIRT_APLIC_S].base +
163
static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp)
296
(memmap[VIRT_APLIC_S].size * socket);
164
{
297
+ create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_S].size,
165
MchpPfSoCIoscbState *s = MCHP_PFSOC_IOSCB(dev);
298
+ msi_s_phandle, intc_phandles,
166
@@ -XXX,XX +XXX,XX @@ static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp)
299
+ aplic_s_phandle, 0,
167
"mchp.pfsoc.ioscb.lane23", IOSCB_SUBMOD_REG_SIZE);
300
+ false);
168
memory_region_add_subregion(&s->container, IOSCB_LANE23_BASE, &s->lane23);
301
+
169
302
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
170
- memory_region_init_io(&s->ctrl, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
303
- qemu_fdt_add_subnode(ms->fdt, aplic_name);
171
- "mchp.pfsoc.ioscb.ctrl", IOSCB_SUBMOD_REG_SIZE);
304
- qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
172
+ memory_region_init_io(&s->ctrl, OBJECT(s), &mchp_pfsoc_ctrl_ops, s,
305
- qemu_fdt_setprop_cell(ms->fdt, aplic_name,
173
+ "mchp.pfsoc.ioscb.ctrl", IOSCB_CTRL_REG_SIZE);
306
- "#interrupt-cells", FDT_APLIC_INT_CELLS);
174
memory_region_add_subregion(&s->container, IOSCB_CTRL_BASE, &s->ctrl);
307
- qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
175
308
- if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
176
+ memory_region_init_io(&s->qspixip, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
309
- qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
177
+ "mchp.pfsoc.ioscb.qspixip", IOSCB_QSPIXIP_REG_SIZE);
310
- aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2);
178
+ memory_region_add_subregion(&s->container, IOSCB_QSPIXIP_BASE, &s->qspixip);
311
- } else {
179
+
312
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent",
180
+ memory_region_init_io(&s->mailbox, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
313
- msi_s_phandle);
181
+ "mchp.pfsoc.ioscb.mailbox", IOSCB_SUBMOD_REG_SIZE);
314
- }
182
+ memory_region_add_subregion(&s->container, IOSCB_MAILBOX_BASE, &s->mailbox);
315
- qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
183
+
316
- 0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_S].size);
184
memory_region_init_io(&s->cfg, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
317
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
185
"mchp.pfsoc.ioscb.cfg", IOSCB_SUBMOD_REG_SIZE);
318
- VIRT_IRQCHIP_NUM_SOURCES);
186
memory_region_add_subregion(&s->container, IOSCB_CFG_BASE, &s->cfg);
319
- riscv_socket_fdt_write_id(ms, aplic_name, socket);
187
@@ -XXX,XX +XXX,XX @@ static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp)
320
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_s_phandle);
188
IOSCB_SUBMOD_REG_SIZE);
321
189
memory_region_add_subregion(&s->container, IOSCB_IO_CALIB_SGMII_BASE,
322
if (!socket) {
190
&s->io_calib_sgmii);
323
platform_bus_add_all_fdt_nodes(ms->fdt, aplic_name,
191
+
324
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
192
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
325
326
g_free(aplic_name);
327
328
- g_free(aplic_cells);
329
aplic_phandles[socket] = aplic_s_phandle;
193
}
330
}
194
331
195
static void mchp_pfsoc_ioscb_class_init(ObjectClass *klass, void *data)
332
@@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
196
diff --git a/hw/misc/mchp_pfsoc_sysreg.c b/hw/misc/mchp_pfsoc_sysreg.c
333
int i;
197
index XXXXXXX..XXXXXXX 100644
334
hwaddr addr;
198
--- a/hw/misc/mchp_pfsoc_sysreg.c
335
uint32_t guest_bits;
199
+++ b/hw/misc/mchp_pfsoc_sysreg.c
336
- DeviceState *aplic_m;
200
@@ -XXX,XX +XXX,XX @@
337
- bool msimode = (aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) ? true : false;
201
#include "qemu/bitops.h"
338
+ DeviceState *aplic_s = NULL;
202
#include "qemu/log.h"
339
+ DeviceState *aplic_m = NULL;
203
#include "qapi/error.h"
340
+ bool msimode = aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
204
+#include "hw/irq.h"
341
205
#include "hw/sysbus.h"
342
if (msimode) {
206
#include "hw/misc/mchp_pfsoc_sysreg.h"
343
- /* Per-socket M-level IMSICs */
207
344
- addr = memmap[VIRT_IMSIC_M].base + socket * VIRT_IMSIC_GROUP_MAX_SIZE;
208
#define ENVM_CR 0xb8
345
- for (i = 0; i < hart_count; i++) {
209
+#define MESSAGE_INT 0x118c
346
- riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0),
210
347
- base_hartid + i, true, 1,
211
static uint64_t mchp_pfsoc_sysreg_read(void *opaque, hwaddr offset,
348
- VIRT_IRQCHIP_NUM_MSIS);
212
unsigned size)
349
+ if (!kvm_enabled()) {
213
@@ -XXX,XX +XXX,XX @@ static uint64_t mchp_pfsoc_sysreg_read(void *opaque, hwaddr offset,
350
+ /* Per-socket M-level IMSICs */
214
static void mchp_pfsoc_sysreg_write(void *opaque, hwaddr offset,
351
+ addr = memmap[VIRT_IMSIC_M].base +
215
uint64_t value, unsigned size)
352
+ socket * VIRT_IMSIC_GROUP_MAX_SIZE;
216
{
353
+ for (i = 0; i < hart_count; i++) {
217
- qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
354
+ riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0),
218
- "(size %d, value 0x%" PRIx64
355
+ base_hartid + i, true, 1,
219
- ", offset 0x%" HWADDR_PRIx ")\n",
356
+ VIRT_IRQCHIP_NUM_MSIS);
220
- __func__, size, value, offset);
357
+ }
221
+ MchpPfSoCSysregState *s = opaque;
358
}
222
+ switch (offset) {
359
223
+ case MESSAGE_INT:
360
/* Per-socket S-level IMSICs */
224
+ qemu_irq_lower(s->irq);
361
@@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
225
+ break;
362
}
226
+ default:
363
}
227
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
364
228
+ "(size %d, value 0x%" PRIx64
365
- /* Per-socket M-level APLIC */
229
+ ", offset 0x%" HWADDR_PRIx ")\n",
366
- aplic_m = riscv_aplic_create(
230
+ __func__, size, value, offset);
367
- memmap[VIRT_APLIC_M].base + socket * memmap[VIRT_APLIC_M].size,
231
+ }
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;
232
}
409
}
233
410
234
static const MemoryRegionOps mchp_pfsoc_sysreg_ops = {
411
static void create_platform_bus(RISCVVirtState *s, DeviceState *irqchip)
235
@@ -XXX,XX +XXX,XX @@ static void mchp_pfsoc_sysreg_realize(DeviceState *dev, Error **errp)
236
"mchp.pfsoc.sysreg",
237
MCHP_PFSOC_SYSREG_REG_SIZE);
238
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->sysreg);
239
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
240
}
241
242
static void mchp_pfsoc_sysreg_class_init(ObjectClass *klass, void *data)
243
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
244
index XXXXXXX..XXXXXXX 100644
245
--- a/hw/riscv/microchip_pfsoc.c
246
+++ b/hw/riscv/microchip_pfsoc.c
247
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
248
sysbus_realize(SYS_BUS_DEVICE(&s->sysreg), errp);
249
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysreg), 0,
250
memmap[MICROCHIP_PFSOC_SYSREG].base);
251
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->sysreg), 0,
252
+ qdev_get_gpio_in(DEVICE(s->plic),
253
+ MICROCHIP_PFSOC_MAILBOX_IRQ));
254
255
/* AXISW */
256
create_unimplemented_device("microchip.pfsoc.axisw",
257
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
258
sysbus_realize(SYS_BUS_DEVICE(&s->ioscb), errp);
259
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioscb), 0,
260
memmap[MICROCHIP_PFSOC_IOSCB].base);
261
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ioscb), 0,
262
+ qdev_get_gpio_in(DEVICE(s->plic),
263
+ MICROCHIP_PFSOC_MAILBOX_IRQ));
264
265
/* FPGA Fabric */
266
create_unimplemented_device("microchip.pfsoc.fabricfic3",
267
--
412
--
268
2.38.1
413
2.41.0
diff view generated by jsdifflib
1
From: Mayuresh Chitale <mchitale@ventanamicro.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
This patch adds a mechanism to generate a virtual instruction
3
We check the in-kernel irqchip support when using KVM acceleration.
4
instruction exception instead of an illegal instruction exception
5
during instruction decode when virt is enabled.
6
4
7
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
5
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
8
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Reviewed-by: Jim Shu <jim.shu@sifive.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Message-Id: <20221016124726.102129-4-mchitale@ventanamicro.com>
8
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
9
Message-ID: <20230727102439.22554-3-yongxuan.wang@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/translate.c | 8 +++++++-
12
target/riscv/kvm.c | 10 +++++++++-
14
1 file changed, 7 insertions(+), 1 deletion(-)
13
1 file changed, 9 insertions(+), 1 deletion(-)
15
14
16
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
15
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/translate.c
17
--- a/target/riscv/kvm.c
19
+++ b/target/riscv/translate.c
18
+++ b/target/riscv/kvm.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
19
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
21
to reset this known value. */
20
22
int frm;
21
int kvm_arch_irqchip_create(KVMState *s)
23
RISCVMXL ol;
24
+ bool virt_inst_excp;
25
bool virt_enabled;
26
const RISCVCPUConfig *cfg_ptr;
27
bool hlsx;
28
@@ -XXX,XX +XXX,XX @@ static void gen_exception_illegal(DisasContext *ctx)
29
{
22
{
30
tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env,
23
- return 0;
31
offsetof(CPURISCVState, bins));
24
+ if (kvm_kernel_irqchip_split()) {
32
- generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
25
+ error_report("-machine kernel_irqchip=split is not supported on RISC-V.");
33
+ if (ctx->virt_inst_excp) {
26
+ exit(1);
34
+ generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
35
+ } else {
36
+ generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
37
+ }
27
+ }
28
+
29
+ /*
30
+ * We can create the VAIA using the newer device control API.
31
+ */
32
+ return kvm_check_extension(s, KVM_CAP_DEVICE_CTRL);
38
}
33
}
39
34
40
static void gen_exception_inst_addr_mis(DisasContext *ctx)
35
int kvm_arch_process_async_events(CPUState *cs)
41
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
42
{ has_XVentanaCondOps_p, decode_XVentanaCodeOps },
43
};
44
45
+ ctx->virt_inst_excp = false;
46
/* Check for compressed insn */
47
if (insn_len(opcode) == 2) {
48
if (!has_ext(ctx, RVC)) {
49
--
36
--
50
2.38.1
37
2.41.0
diff view generated by jsdifflib
1
From: Jim Shu <jim.shu@sifive.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
If the number of interrupt is not multiple of 32, PLIC will have
3
We create a vAIA chip by using the KVM_DEV_TYPE_RISCV_AIA and then set up
4
out-of-bound access to source_priority array. Compute the number of
4
the chip with the KVM_DEV_RISCV_AIA_GRP_* APIs.
5
interrupt in the last word to avoid this out-of-bound access of array.
5
We also extend KVM accelerator to specify the KVM AIA mode. The "riscv-aia"
6
parameter is passed along with --accel in QEMU command-line.
7
1) "riscv-aia=emul": IMSIC is emulated by hypervisor
8
2) "riscv-aia=hwaccel": use hardware guest IMSIC
9
3) "riscv-aia=auto": use the hardware guest IMSICs whenever available
10
otherwise we fallback to software emulation.
6
11
7
Signed-off-by: Jim Shu <jim.shu@sifive.com>
12
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
8
Reviewed-by: Bin Meng <bmeng@tinylab.org>
13
Reviewed-by: Jim Shu <jim.shu@sifive.com>
9
Message-Id: <20221127165753.30533-1-jim.shu@sifive.com>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
16
Message-ID: <20230727102439.22554-4-yongxuan.wang@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
18
---
12
hw/intc/sifive_plic.c | 12 +++++++++++-
19
target/riscv/kvm_riscv.h | 4 +
13
1 file changed, 11 insertions(+), 1 deletion(-)
20
target/riscv/kvm.c | 186 +++++++++++++++++++++++++++++++++++++++
21
2 files changed, 190 insertions(+)
14
22
15
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
23
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
16
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/sifive_plic.c
25
--- a/target/riscv/kvm_riscv.h
18
+++ b/hw/intc/sifive_plic.c
26
+++ b/target/riscv/kvm_riscv.h
19
@@ -XXX,XX +XXX,XX @@ static uint32_t sifive_plic_claimed(SiFivePLICState *plic, uint32_t addrid)
27
@@ -XXX,XX +XXX,XX @@
20
uint32_t max_irq = 0;
28
void kvm_riscv_init_user_properties(Object *cpu_obj);
21
uint32_t max_prio = plic->target_priority[addrid];
29
void kvm_riscv_reset_vcpu(RISCVCPU *cpu);
22
int i, j;
30
void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level);
23
+ int num_irq_in_word = 32;
31
+void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
24
32
+ uint64_t aia_irq_num, uint64_t aia_msi_num,
25
for (i = 0; i < plic->bitfield_words; i++) {
33
+ uint64_t aplic_base, uint64_t imsic_base,
26
uint32_t pending_enabled_not_claimed =
34
+ uint64_t guest_num);
27
@@ -XXX,XX +XXX,XX @@ static uint32_t sifive_plic_claimed(SiFivePLICState *plic, uint32_t addrid)
35
28
continue;
36
#endif
29
}
37
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
30
38
index XXXXXXX..XXXXXXX 100644
31
- for (j = 0; j < 32; j++) {
39
--- a/target/riscv/kvm.c
32
+ if (i == (plic->bitfield_words - 1)) {
40
+++ b/target/riscv/kvm.c
33
+ /*
41
@@ -XXX,XX +XXX,XX @@
34
+ * If plic->num_sources is not multiple of 32, num-of-irq in last
42
#include "exec/address-spaces.h"
35
+ * word is not 32. Compute the num-of-irq of last word to avoid
43
#include "hw/boards.h"
36
+ * out-of-bound access of source_priority array.
44
#include "hw/irq.h"
37
+ */
45
+#include "hw/intc/riscv_imsic.h"
38
+ num_irq_in_word = plic->num_sources - ((plic->bitfield_words - 1) << 5);
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;
59
}
60
61
+static int aia_mode;
62
+
63
+static const char *kvm_aia_mode_str(uint64_t mode)
64
+{
65
+ switch (mode) {
66
+ case KVM_DEV_RISCV_AIA_MODE_EMUL:
67
+ return "emul";
68
+ case KVM_DEV_RISCV_AIA_MODE_HWACCEL:
69
+ return "hwaccel";
70
+ case KVM_DEV_RISCV_AIA_MODE_AUTO:
71
+ default:
72
+ return "auto";
73
+ };
74
+}
75
+
76
+static char *riscv_get_kvm_aia(Object *obj, Error **errp)
77
+{
78
+ return g_strdup(kvm_aia_mode_str(aia_mode));
79
+}
80
+
81
+static void riscv_set_kvm_aia(Object *obj, const char *val, Error **errp)
82
+{
83
+ if (!strcmp(val, "emul")) {
84
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_EMUL;
85
+ } else if (!strcmp(val, "hwaccel")) {
86
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_HWACCEL;
87
+ } else if (!strcmp(val, "auto")) {
88
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_AUTO;
89
+ } else {
90
+ error_setg(errp, "Invalid KVM AIA mode");
91
+ error_append_hint(errp, "Valid values are emul, hwaccel, and auto.\n");
92
+ }
93
+}
94
+
95
void kvm_arch_accel_class_init(ObjectClass *oc)
96
{
97
+ object_class_property_add_str(oc, "riscv-aia", riscv_get_kvm_aia,
98
+ riscv_set_kvm_aia);
99
+ object_class_property_set_description(oc, "riscv-aia",
100
+ "Set KVM AIA mode. Valid values are "
101
+ "emul, hwaccel, and auto. Default "
102
+ "is auto.");
103
+ object_property_set_default_str(object_class_property_find(oc, "riscv-aia"),
104
+ "auto");
105
+}
106
+
107
+void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
108
+ uint64_t aia_irq_num, uint64_t aia_msi_num,
109
+ uint64_t aplic_base, uint64_t imsic_base,
110
+ uint64_t guest_num)
111
+{
112
+ int ret, i;
113
+ int aia_fd = -1;
114
+ uint64_t default_aia_mode;
115
+ uint64_t socket_count = riscv_socket_count(machine);
116
+ uint64_t max_hart_per_socket = 0;
117
+ uint64_t socket, base_hart, hart_count, socket_imsic_base, imsic_addr;
118
+ uint64_t socket_bits, hart_bits, guest_bits;
119
+
120
+ aia_fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_RISCV_AIA, false);
121
+
122
+ if (aia_fd < 0) {
123
+ error_report("Unable to create in-kernel irqchip");
124
+ exit(1);
125
+ }
126
+
127
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
128
+ KVM_DEV_RISCV_AIA_CONFIG_MODE,
129
+ &default_aia_mode, false, NULL);
130
+ if (ret < 0) {
131
+ error_report("KVM AIA: failed to get current KVM AIA mode");
132
+ exit(1);
133
+ }
134
+ qemu_log("KVM AIA: default mode is %s\n",
135
+ kvm_aia_mode_str(default_aia_mode));
136
+
137
+ if (default_aia_mode != aia_mode) {
138
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
139
+ KVM_DEV_RISCV_AIA_CONFIG_MODE,
140
+ &aia_mode, true, NULL);
141
+ if (ret < 0)
142
+ warn_report("KVM AIA: failed to set KVM AIA mode");
143
+ else
144
+ qemu_log("KVM AIA: set current mode to %s\n",
145
+ kvm_aia_mode_str(aia_mode));
146
+ }
147
+
148
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
149
+ KVM_DEV_RISCV_AIA_CONFIG_SRCS,
150
+ &aia_irq_num, true, NULL);
151
+ if (ret < 0) {
152
+ error_report("KVM AIA: failed to set number of input irq lines");
153
+ exit(1);
154
+ }
155
+
156
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
157
+ KVM_DEV_RISCV_AIA_CONFIG_IDS,
158
+ &aia_msi_num, true, NULL);
159
+ if (ret < 0) {
160
+ error_report("KVM AIA: failed to set number of msi");
161
+ exit(1);
162
+ }
163
+
164
+ socket_bits = find_last_bit(&socket_count, BITS_PER_LONG) + 1;
165
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
166
+ KVM_DEV_RISCV_AIA_CONFIG_GROUP_BITS,
167
+ &socket_bits, true, NULL);
168
+ if (ret < 0) {
169
+ error_report("KVM AIA: failed to set group_bits");
170
+ exit(1);
171
+ }
172
+
173
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
174
+ KVM_DEV_RISCV_AIA_CONFIG_GROUP_SHIFT,
175
+ &group_shift, true, NULL);
176
+ if (ret < 0) {
177
+ error_report("KVM AIA: failed to set group_shift");
178
+ exit(1);
179
+ }
180
+
181
+ guest_bits = guest_num == 0 ? 0 :
182
+ find_last_bit(&guest_num, BITS_PER_LONG) + 1;
183
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
184
+ KVM_DEV_RISCV_AIA_CONFIG_GUEST_BITS,
185
+ &guest_bits, true, NULL);
186
+ if (ret < 0) {
187
+ error_report("KVM AIA: failed to set guest_bits");
188
+ exit(1);
189
+ }
190
+
191
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_ADDR,
192
+ KVM_DEV_RISCV_AIA_ADDR_APLIC,
193
+ &aplic_base, true, NULL);
194
+ if (ret < 0) {
195
+ error_report("KVM AIA: failed to set the base address of APLIC");
196
+ exit(1);
197
+ }
198
+
199
+ for (socket = 0; socket < socket_count; socket++) {
200
+ socket_imsic_base = imsic_base + socket * (1U << group_shift);
201
+ hart_count = riscv_socket_hart_count(machine, socket);
202
+ base_hart = riscv_socket_first_hartid(machine, socket);
203
+
204
+ if (max_hart_per_socket < hart_count) {
205
+ max_hart_per_socket = hart_count;
39
+ }
206
+ }
40
+
207
+
41
+ for (j = 0; j < num_irq_in_word; j++) {
208
+ for (i = 0; i < hart_count; i++) {
42
int irq = (i << 5) + j;
209
+ imsic_addr = socket_imsic_base + i * IMSIC_HART_SIZE(guest_bits);
43
uint32_t prio = plic->source_priority[irq];
210
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_ADDR,
44
int enabled = pending_enabled_not_claimed & (1 << j);
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
}
45
--
248
--
46
2.38.1
249
2.41.0
diff view generated by jsdifflib
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
Adds a helper macro that implements the register `w1c`
3
KVM AIA can't emulate APLIC only. When "aia=aplic" parameter is passed,
4
functionality.
4
APLIC devices is emulated by QEMU. For "aia=aplic-imsic", remove the
5
mmio operations of APLIC when using KVM AIA and send wired interrupt
6
signal via KVM_IRQ_LINE API.
7
After KVM AIA enabled, MSI messages are delivered by KVM_SIGNAL_MSI API
8
when the IMSICs receive mmio write requests.
5
9
6
Ex:
10
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
7
uint32_t data = FIELD32_1CLEAR(val, REG, FIELD);
11
Reviewed-by: Jim Shu <jim.shu@sifive.com>
8
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
If ANY bits of the specified `FIELD` is set
13
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
10
then the respective field is cleared and returned to `data`.
14
Message-ID: <20230727102439.22554-5-yongxuan.wang@sifive.com>
11
12
If the field is cleared (0), then no change and
13
val is returned.
14
15
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-Id: <20221017054950.317584-2-wilfred.mallawa@opensource.wdc.com>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
16
---
20
include/hw/registerfields.h | 22 ++++++++++++++++++++++
17
hw/intc/riscv_aplic.c | 56 ++++++++++++++++++++++++++++++-------------
21
1 file changed, 22 insertions(+)
18
hw/intc/riscv_imsic.c | 25 +++++++++++++++----
19
2 files changed, 61 insertions(+), 20 deletions(-)
22
20
23
diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h
21
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
24
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/registerfields.h
23
--- a/hw/intc/riscv_aplic.c
26
+++ b/include/hw/registerfields.h
24
+++ b/hw/intc/riscv_aplic.c
27
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@
28
R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
26
#include "hw/irq.h"
29
_d; })
27
#include "target/riscv/cpu.h"
28
#include "sysemu/sysemu.h"
29
+#include "sysemu/kvm.h"
30
#include "migration/vmstate.h"
31
32
#define APLIC_MAX_IDC (1UL << 14)
33
@@ -XXX,XX +XXX,XX @@
34
35
#define APLIC_IDC_CLAIMI 0x1c
30
36
31
+/*
37
+/*
32
+ * Clear the specified field in storage if
38
+ * KVM AIA only supports APLIC MSI, fallback to QEMU emulation if we want to use
33
+ * any field bits are set, else no changes made. Implements
39
+ * APLIC Wired.
34
+ * single/multi-bit `w1c`
35
+ *
36
+ */
40
+ */
37
+#define FIELD8_1CLEAR(storage, reg, field) \
41
+static bool is_kvm_aia(bool msimode)
38
+ (FIELD_EX8(storage, reg, field) ? \
42
+{
39
+ FIELD_DP8(storage, reg, field, 0x00) : storage)
43
+ return kvm_irqchip_in_kernel() && msimode;
44
+}
40
+
45
+
41
+#define FIELD16_1CLEAR(storage, reg, field) \
46
static uint32_t riscv_aplic_read_input_word(RISCVAPLICState *aplic,
42
+ (FIELD_EX16(storage, reg, field) ? \
47
uint32_t word)
43
+ FIELD_DP16(storage, reg, field, 0x00) : storage)
48
{
49
@@ -XXX,XX +XXX,XX @@ static uint32_t riscv_aplic_idc_claimi(RISCVAPLICState *aplic, uint32_t idc)
50
return topi;
51
}
52
53
+static void riscv_kvm_aplic_request(void *opaque, int irq, int level)
54
+{
55
+ kvm_set_irq(kvm_state, irq, !!level);
56
+}
44
+
57
+
45
+#define FIELD32_1CLEAR(storage, reg, field) \
58
static void riscv_aplic_request(void *opaque, int irq, int level)
46
+ (FIELD_EX32(storage, reg, field) ? \
59
{
47
+ FIELD_DP32(storage, reg, field, 0x00) : storage)
60
bool update = false;
61
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
62
uint32_t i;
63
RISCVAPLICState *aplic = RISCV_APLIC(dev);
64
65
- aplic->bitfield_words = (aplic->num_irqs + 31) >> 5;
66
- aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs);
67
- aplic->state = g_new0(uint32_t, aplic->num_irqs);
68
- aplic->target = g_new0(uint32_t, aplic->num_irqs);
69
- if (!aplic->msimode) {
70
- for (i = 0; i < aplic->num_irqs; i++) {
71
- aplic->target[i] = 1;
72
+ if (!is_kvm_aia(aplic->msimode)) {
73
+ aplic->bitfield_words = (aplic->num_irqs + 31) >> 5;
74
+ aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs);
75
+ aplic->state = g_new0(uint32_t, aplic->num_irqs);
76
+ aplic->target = g_new0(uint32_t, aplic->num_irqs);
77
+ if (!aplic->msimode) {
78
+ for (i = 0; i < aplic->num_irqs; i++) {
79
+ aplic->target[i] = 1;
80
+ }
81
}
82
- }
83
- aplic->idelivery = g_new0(uint32_t, aplic->num_harts);
84
- aplic->iforce = g_new0(uint32_t, aplic->num_harts);
85
- aplic->ithreshold = g_new0(uint32_t, aplic->num_harts);
86
+ aplic->idelivery = g_new0(uint32_t, aplic->num_harts);
87
+ aplic->iforce = g_new0(uint32_t, aplic->num_harts);
88
+ aplic->ithreshold = g_new0(uint32_t, aplic->num_harts);
89
90
- memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops, aplic,
91
- TYPE_RISCV_APLIC, aplic->aperture_size);
92
- sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio);
93
+ memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops,
94
+ aplic, TYPE_RISCV_APLIC, aplic->aperture_size);
95
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio);
96
+ }
97
98
/*
99
* Only root APLICs have hardware IRQ lines. All non-root APLICs
100
* have IRQ lines delegated by their parent APLIC.
101
*/
102
if (!aplic->parent) {
103
- qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
104
+ if (is_kvm_aia(aplic->msimode)) {
105
+ qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs);
106
+ } else {
107
+ qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
108
+ }
109
}
110
111
/* Create output IRQ lines for non-MSI mode */
112
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
113
qdev_prop_set_bit(dev, "mmode", mmode);
114
115
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
116
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
48
+
117
+
49
+#define FIELD64_1CLEAR(storage, reg, field) \
118
+ if (!is_kvm_aia(msimode)) {
50
+ (FIELD_EX64(storage, reg, field) ? \
119
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
51
+ FIELD_DP64(storage, reg, field, 0x00) : storage)
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;
52
+
143
+
53
#define FIELD_SDP8(storage, reg, field, val) ({ \
144
+ msi.address_lo = extract64(imsic->mmio.addr + addr, 0, 32);
54
struct { \
145
+ msi.address_hi = extract64(imsic->mmio.addr + addr, 32, 32);
55
signed int v:R_ ## reg ## _ ## field ## _LENGTH; \
146
+ msi.data = le32_to_cpu(value);
147
+
148
+ kvm_vm_ioctl(kvm_state, KVM_SIGNAL_MSI, &msi);
149
+
150
+ return;
151
+ }
152
+#endif
153
+
154
/* Writes only supported for MSI little-endian registers */
155
page = addr >> IMSIC_MMIO_PAGE_SHIFT;
156
if ((addr & (IMSIC_MMIO_PAGE_SZ - 1)) == IMSIC_MMIO_PAGE_LE) {
157
@@ -XXX,XX +XXX,XX @@ static void riscv_imsic_realize(DeviceState *dev, Error **errp)
158
CPUState *cpu = cpu_by_arch_id(imsic->hartid);
159
CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
160
161
- imsic->num_eistate = imsic->num_pages * imsic->num_irqs;
162
- imsic->eidelivery = g_new0(uint32_t, imsic->num_pages);
163
- imsic->eithreshold = g_new0(uint32_t, imsic->num_pages);
164
- imsic->eistate = g_new0(uint32_t, imsic->num_eistate);
165
+ if (!kvm_irqchip_in_kernel()) {
166
+ imsic->num_eistate = imsic->num_pages * imsic->num_irqs;
167
+ imsic->eidelivery = g_new0(uint32_t, imsic->num_pages);
168
+ imsic->eithreshold = g_new0(uint32_t, imsic->num_pages);
169
+ imsic->eistate = g_new0(uint32_t, imsic->num_eistate);
170
+ }
171
172
memory_region_init_io(&imsic->mmio, OBJECT(dev), &riscv_imsic_ops,
173
imsic, TYPE_RISCV_IMSIC,
56
--
174
--
57
2.38.1
175
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
Commit 28d8c281200f ("hw/riscv: virt: Add optional AIA IMSIC support to virt machine")
3
Select KVM AIA when the host kernel has in-kernel AIA chip support.
4
changed the value of VIRT_IRQCHIP_NUM_SOURCES from 127 to 53, which
4
Since KVM AIA only has one APLIC instance, we map the QEMU APLIC
5
is VIRTIO_NDEV and also used as the value of "riscv,ndev" property
5
devices to KVM APLIC.
6
in the dtb. Unfortunately this is wrong as VIRT_IRQCHIP_NUM_SOURCES
7
should include interrupt source 0 but "riscv,ndev" does not.
8
6
9
While we are here, we also fix the comments of platform bus irq range
7
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
10
which is now "64 to 96", but should be "64 to 95", introduced since
8
Reviewed-by: Jim Shu <jim.shu@sifive.com>
11
commit 1832b7cb3f64 ("hw/riscv: virt: Create a platform bus").
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
10
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
13
Fixes: 28d8c281200f ("hw/riscv: virt: Add optional AIA IMSIC support to virt machine")
11
Message-ID: <20230727102439.22554-6-yongxuan.wang@sifive.com>
14
Signed-off-by: Bin Meng <bmeng@tinylab.org>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-Id: <20221211030829.802437-13-bmeng@tinylab.org>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
13
---
19
include/hw/riscv/virt.h | 5 ++---
14
hw/riscv/virt.c | 94 +++++++++++++++++++++++++++++++++----------------
20
hw/riscv/virt.c | 3 ++-
15
1 file changed, 63 insertions(+), 31 deletions(-)
21
2 files changed, 4 insertions(+), 4 deletions(-)
22
16
23
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/riscv/virt.h
26
+++ b/include/hw/riscv/virt.h
27
@@ -XXX,XX +XXX,XX @@ enum {
28
VIRTIO_IRQ = 1, /* 1 to 8 */
29
VIRTIO_COUNT = 8,
30
PCIE_IRQ = 0x20, /* 32 to 35 */
31
- VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 96 */
32
- VIRTIO_NDEV = 96 /* Arbitrary maximum number of interrupts */
33
+ VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 95 */
34
};
35
36
#define VIRT_PLATFORM_BUS_NUM_IRQS 32
37
38
#define VIRT_IRQCHIP_NUM_MSIS 255
39
-#define VIRT_IRQCHIP_NUM_SOURCES VIRTIO_NDEV
40
+#define VIRT_IRQCHIP_NUM_SOURCES 96
41
#define VIRT_IRQCHIP_NUM_PRIO_BITS 3
42
#define VIRT_IRQCHIP_MAX_GUESTS_BITS 3
43
#define VIRT_IRQCHIP_MAX_GUESTS ((1U << VIRT_IRQCHIP_MAX_GUESTS_BITS) - 1U)
44
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
45
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/riscv/virt.c
19
--- a/hw/riscv/virt.c
47
+++ b/hw/riscv/virt.c
20
+++ b/hw/riscv/virt.c
48
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_plic(RISCVVirtState *s,
21
@@ -XXX,XX +XXX,XX @@
49
plic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
22
#include "hw/riscv/virt.h"
50
qemu_fdt_setprop_cells(mc->fdt, plic_name, "reg",
23
#include "hw/riscv/boot.h"
51
0x0, plic_addr, 0x0, memmap[VIRT_PLIC].size);
24
#include "hw/riscv/numa.h"
52
- qemu_fdt_setprop_cell(mc->fdt, plic_name, "riscv,ndev", VIRTIO_NDEV);
25
+#include "kvm_riscv.h"
53
+ qemu_fdt_setprop_cell(mc->fdt, plic_name, "riscv,ndev",
26
#include "hw/intc/riscv_aclint.h"
54
+ VIRT_IRQCHIP_NUM_SOURCES - 1);
27
#include "hw/intc/riscv_aplic.h"
55
riscv_socket_fdt_write_id(mc, mc->fdt, plic_name, socket);
28
#include "hw/intc/riscv_imsic.h"
56
qemu_fdt_setprop_cell(mc->fdt, plic_name, "phandle",
29
@@ -XXX,XX +XXX,XX @@
57
plic_phandles[socket]);
30
#error "Can't accommodate all IMSIC groups in address space"
31
#endif
32
33
+/* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU. */
34
+static bool virt_use_kvm_aia(RISCVVirtState *s)
35
+{
36
+ return kvm_irqchip_in_kernel() && s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
37
+}
38
+
39
static const MemMapEntry virt_memmap[] = {
40
[VIRT_DEBUG] = { 0x0, 0x100 },
41
[VIRT_MROM] = { 0x1000, 0xf000 },
42
@@ -XXX,XX +XXX,XX @@ static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
43
uint32_t *intc_phandles,
44
uint32_t aplic_phandle,
45
uint32_t aplic_child_phandle,
46
- bool m_mode)
47
+ bool m_mode, int num_harts)
48
{
49
int cpu;
50
char *aplic_name;
51
uint32_t *aplic_cells;
52
MachineState *ms = MACHINE(s);
53
54
- aplic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
55
+ aplic_cells = g_new0(uint32_t, num_harts * 2);
56
57
- for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
58
+ for (cpu = 0; cpu < num_harts; cpu++) {
59
aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
60
aplic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
61
}
62
@@ -XXX,XX +XXX,XX @@ static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
63
64
if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
65
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
66
- aplic_cells,
67
- s->soc[socket].num_harts * sizeof(uint32_t) * 2);
68
+ aplic_cells, num_harts * sizeof(uint32_t) * 2);
69
} else {
70
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent", msi_phandle);
71
}
72
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
73
uint32_t msi_s_phandle,
74
uint32_t *phandle,
75
uint32_t *intc_phandles,
76
- uint32_t *aplic_phandles)
77
+ uint32_t *aplic_phandles,
78
+ int num_harts)
79
{
80
char *aplic_name;
81
unsigned long aplic_addr;
82
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
83
create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_M].size,
84
msi_m_phandle, intc_phandles,
85
aplic_m_phandle, aplic_s_phandle,
86
- true);
87
+ true, num_harts);
88
}
89
90
/* S-level APLIC node */
91
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
92
create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_S].size,
93
msi_s_phandle, intc_phandles,
94
aplic_s_phandle, 0,
95
- false);
96
+ false, num_harts);
97
98
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
99
100
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
101
*msi_pcie_phandle = msi_s_phandle;
102
}
103
104
- phandle_pos = ms->smp.cpus;
105
- for (socket = (socket_count - 1); socket >= 0; socket--) {
106
- phandle_pos -= s->soc[socket].num_harts;
107
-
108
- if (s->aia_type == VIRT_AIA_TYPE_NONE) {
109
- create_fdt_socket_plic(s, memmap, socket, phandle,
110
- &intc_phandles[phandle_pos], xplic_phandles);
111
- } else {
112
- create_fdt_socket_aplic(s, memmap, socket,
113
- msi_m_phandle, msi_s_phandle, phandle,
114
- &intc_phandles[phandle_pos], xplic_phandles);
115
+ /* KVM AIA only has one APLIC instance */
116
+ if (virt_use_kvm_aia(s)) {
117
+ create_fdt_socket_aplic(s, memmap, 0,
118
+ msi_m_phandle, msi_s_phandle, phandle,
119
+ &intc_phandles[0], xplic_phandles,
120
+ ms->smp.cpus);
121
+ } else {
122
+ phandle_pos = ms->smp.cpus;
123
+ for (socket = (socket_count - 1); socket >= 0; socket--) {
124
+ phandle_pos -= s->soc[socket].num_harts;
125
+
126
+ if (s->aia_type == VIRT_AIA_TYPE_NONE) {
127
+ create_fdt_socket_plic(s, memmap, socket, phandle,
128
+ &intc_phandles[phandle_pos],
129
+ xplic_phandles);
130
+ } else {
131
+ create_fdt_socket_aplic(s, memmap, socket,
132
+ msi_m_phandle, msi_s_phandle, phandle,
133
+ &intc_phandles[phandle_pos],
134
+ xplic_phandles,
135
+ s->soc[socket].num_harts);
136
+ }
137
}
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
175
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
176
}
177
}
178
179
+ if (virt_use_kvm_aia(s)) {
180
+ kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT,
181
+ VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS,
182
+ memmap[VIRT_APLIC_S].base,
183
+ memmap[VIRT_IMSIC_S].base,
184
+ s->aia_guests);
185
+ }
186
+
187
if (riscv_is_32bit(&s->soc[0])) {
188
#if HOST_LONG_BITS == 64
189
/* limit RAM size in a 32-bit system */
58
--
190
--
59
2.38.1
191
2.41.0
diff view generated by jsdifflib
1
From: Conor Dooley <conor.dooley@microchip.com>
1
From: Conor Dooley <conor.dooley@microchip.com>
2
2
3
The Fabric Interconnect Controllers provide interfaces between the FPGA
3
On a dtb dumped from the virt machine, dt-validate complains:
4
fabric and the core complex. There are 5 FICs on PolarFire SoC, numbered
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
0 through 4. FIC2 is an AXI4 slave interface from the FPGA fabric and
5
from schema $id: http://devicetree.org/schemas/simple-bus.yaml#
6
does not show up on the MSS memory map. FIC4 is dedicated to the User
6
That's pretty cryptic, but running the dtb back through dtc produces
7
Crypto Processor and does not show up on the MSS memory map either.
7
something a lot more reasonable:
8
Warning (simple_bus_reg): /soc/pmu: missing or empty reg/ranges property
8
9
9
FIC 0, 1 & 3 do show up in the MSS memory map and neither FICs 0 or 1
10
Moving the riscv,pmu node out of the soc bus solves the problem.
10
are represented in QEMU, leading to load access violations while booting
11
Linux for Icicle if PCIe is enabled as the root port is connected via
12
either FIC 0 or 1.
13
11
12
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
14
Acked-by: Alistair Francis <alistair.francis@wdc.com>
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
16
Message-Id: <20221117225518.4102575-3-conor@kernel.org>
15
Message-ID: <20230727-groom-decline-2c57ce42841c@spud>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
17
---
19
include/hw/riscv/microchip_pfsoc.h | 2 +
18
hw/riscv/virt.c | 2 +-
20
hw/riscv/microchip_pfsoc.c | 115 ++++++++++++++++-------------
19
1 file changed, 1 insertion(+), 1 deletion(-)
21
2 files changed, 65 insertions(+), 52 deletions(-)
22
20
23
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
21
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
24
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/riscv/microchip_pfsoc.h
23
--- a/hw/riscv/virt.c
26
+++ b/include/hw/riscv/microchip_pfsoc.h
24
+++ b/hw/riscv/virt.c
27
@@ -XXX,XX +XXX,XX @@ enum {
25
@@ -XXX,XX +XXX,XX @@ static void create_fdt_pmu(RISCVVirtState *s)
28
MICROCHIP_PFSOC_USB,
26
MachineState *ms = MACHINE(s);
29
MICROCHIP_PFSOC_QSPI_XIP,
27
RISCVCPU hart = s->soc[0].harts[0];
30
MICROCHIP_PFSOC_IOSCB,
28
31
+ MICROCHIP_PFSOC_FABRIC_FIC0,
29
- pmu_name = g_strdup_printf("/soc/pmu");
32
+ MICROCHIP_PFSOC_FABRIC_FIC1,
30
+ pmu_name = g_strdup_printf("/pmu");
33
MICROCHIP_PFSOC_FABRIC_FIC3,
31
qemu_fdt_add_subnode(ms->fdt, pmu_name);
34
MICROCHIP_PFSOC_DRAM_LO,
32
qemu_fdt_setprop_string(ms->fdt, pmu_name, "compatible", "riscv,pmu");
35
MICROCHIP_PFSOC_DRAM_LO_ALIAS,
33
riscv_pmu_generate_fdt_node(ms->fdt, hart.cfg.pmu_num, pmu_name);
36
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/riscv/microchip_pfsoc.c
39
+++ b/hw/riscv/microchip_pfsoc.c
40
@@ -XXX,XX +XXX,XX @@
41
* describes the complete IOSCB modules memory maps
42
*/
43
static const MemMapEntry microchip_pfsoc_memmap[] = {
44
- [MICROCHIP_PFSOC_RSVD0] = { 0x0, 0x100 },
45
- [MICROCHIP_PFSOC_DEBUG] = { 0x100, 0xf00 },
46
- [MICROCHIP_PFSOC_E51_DTIM] = { 0x1000000, 0x2000 },
47
- [MICROCHIP_PFSOC_BUSERR_UNIT0] = { 0x1700000, 0x1000 },
48
- [MICROCHIP_PFSOC_BUSERR_UNIT1] = { 0x1701000, 0x1000 },
49
- [MICROCHIP_PFSOC_BUSERR_UNIT2] = { 0x1702000, 0x1000 },
50
- [MICROCHIP_PFSOC_BUSERR_UNIT3] = { 0x1703000, 0x1000 },
51
- [MICROCHIP_PFSOC_BUSERR_UNIT4] = { 0x1704000, 0x1000 },
52
- [MICROCHIP_PFSOC_CLINT] = { 0x2000000, 0x10000 },
53
- [MICROCHIP_PFSOC_L2CC] = { 0x2010000, 0x1000 },
54
- [MICROCHIP_PFSOC_DMA] = { 0x3000000, 0x100000 },
55
- [MICROCHIP_PFSOC_L2LIM] = { 0x8000000, 0x2000000 },
56
- [MICROCHIP_PFSOC_PLIC] = { 0xc000000, 0x4000000 },
57
- [MICROCHIP_PFSOC_MMUART0] = { 0x20000000, 0x1000 },
58
- [MICROCHIP_PFSOC_WDOG0] = { 0x20001000, 0x1000 },
59
- [MICROCHIP_PFSOC_SYSREG] = { 0x20002000, 0x2000 },
60
- [MICROCHIP_PFSOC_AXISW] = { 0x20004000, 0x1000 },
61
- [MICROCHIP_PFSOC_MPUCFG] = { 0x20005000, 0x1000 },
62
- [MICROCHIP_PFSOC_FMETER] = { 0x20006000, 0x1000 },
63
- [MICROCHIP_PFSOC_DDR_SGMII_PHY] = { 0x20007000, 0x1000 },
64
- [MICROCHIP_PFSOC_EMMC_SD] = { 0x20008000, 0x1000 },
65
- [MICROCHIP_PFSOC_DDR_CFG] = { 0x20080000, 0x40000 },
66
- [MICROCHIP_PFSOC_MMUART1] = { 0x20100000, 0x1000 },
67
- [MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
68
- [MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
69
- [MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
70
- [MICROCHIP_PFSOC_WDOG1] = { 0x20101000, 0x1000 },
71
- [MICROCHIP_PFSOC_WDOG2] = { 0x20103000, 0x1000 },
72
- [MICROCHIP_PFSOC_WDOG3] = { 0x20105000, 0x1000 },
73
- [MICROCHIP_PFSOC_WDOG4] = { 0x20106000, 0x1000 },
74
- [MICROCHIP_PFSOC_SPI0] = { 0x20108000, 0x1000 },
75
- [MICROCHIP_PFSOC_SPI1] = { 0x20109000, 0x1000 },
76
- [MICROCHIP_PFSOC_I2C0] = { 0x2010a000, 0x1000 },
77
- [MICROCHIP_PFSOC_I2C1] = { 0x2010b000, 0x1000 },
78
- [MICROCHIP_PFSOC_CAN0] = { 0x2010c000, 0x1000 },
79
- [MICROCHIP_PFSOC_CAN1] = { 0x2010d000, 0x1000 },
80
- [MICROCHIP_PFSOC_GEM0] = { 0x20110000, 0x2000 },
81
- [MICROCHIP_PFSOC_GEM1] = { 0x20112000, 0x2000 },
82
- [MICROCHIP_PFSOC_GPIO0] = { 0x20120000, 0x1000 },
83
- [MICROCHIP_PFSOC_GPIO1] = { 0x20121000, 0x1000 },
84
- [MICROCHIP_PFSOC_GPIO2] = { 0x20122000, 0x1000 },
85
- [MICROCHIP_PFSOC_RTC] = { 0x20124000, 0x1000 },
86
- [MICROCHIP_PFSOC_ENVM_CFG] = { 0x20200000, 0x1000 },
87
- [MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
88
- [MICROCHIP_PFSOC_USB] = { 0x20201000, 0x1000 },
89
- [MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
90
- [MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
91
- [MICROCHIP_PFSOC_FABRIC_FIC3] = { 0x40000000, 0x20000000 },
92
- [MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
93
- [MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
94
- [MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 },
95
- [MICROCHIP_PFSOC_DRAM_HI_ALIAS] = { 0x1400000000, 0x0 },
96
+ [MICROCHIP_PFSOC_RSVD0] = { 0x0, 0x100 },
97
+ [MICROCHIP_PFSOC_DEBUG] = { 0x100, 0xf00 },
98
+ [MICROCHIP_PFSOC_E51_DTIM] = { 0x1000000, 0x2000 },
99
+ [MICROCHIP_PFSOC_BUSERR_UNIT0] = { 0x1700000, 0x1000 },
100
+ [MICROCHIP_PFSOC_BUSERR_UNIT1] = { 0x1701000, 0x1000 },
101
+ [MICROCHIP_PFSOC_BUSERR_UNIT2] = { 0x1702000, 0x1000 },
102
+ [MICROCHIP_PFSOC_BUSERR_UNIT3] = { 0x1703000, 0x1000 },
103
+ [MICROCHIP_PFSOC_BUSERR_UNIT4] = { 0x1704000, 0x1000 },
104
+ [MICROCHIP_PFSOC_CLINT] = { 0x2000000, 0x10000 },
105
+ [MICROCHIP_PFSOC_L2CC] = { 0x2010000, 0x1000 },
106
+ [MICROCHIP_PFSOC_DMA] = { 0x3000000, 0x100000 },
107
+ [MICROCHIP_PFSOC_L2LIM] = { 0x8000000, 0x2000000 },
108
+ [MICROCHIP_PFSOC_PLIC] = { 0xc000000, 0x4000000 },
109
+ [MICROCHIP_PFSOC_MMUART0] = { 0x20000000, 0x1000 },
110
+ [MICROCHIP_PFSOC_WDOG0] = { 0x20001000, 0x1000 },
111
+ [MICROCHIP_PFSOC_SYSREG] = { 0x20002000, 0x2000 },
112
+ [MICROCHIP_PFSOC_AXISW] = { 0x20004000, 0x1000 },
113
+ [MICROCHIP_PFSOC_MPUCFG] = { 0x20005000, 0x1000 },
114
+ [MICROCHIP_PFSOC_FMETER] = { 0x20006000, 0x1000 },
115
+ [MICROCHIP_PFSOC_DDR_SGMII_PHY] = { 0x20007000, 0x1000 },
116
+ [MICROCHIP_PFSOC_EMMC_SD] = { 0x20008000, 0x1000 },
117
+ [MICROCHIP_PFSOC_DDR_CFG] = { 0x20080000, 0x40000 },
118
+ [MICROCHIP_PFSOC_MMUART1] = { 0x20100000, 0x1000 },
119
+ [MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
120
+ [MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
121
+ [MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
122
+ [MICROCHIP_PFSOC_WDOG1] = { 0x20101000, 0x1000 },
123
+ [MICROCHIP_PFSOC_WDOG2] = { 0x20103000, 0x1000 },
124
+ [MICROCHIP_PFSOC_WDOG3] = { 0x20105000, 0x1000 },
125
+ [MICROCHIP_PFSOC_WDOG4] = { 0x20106000, 0x1000 },
126
+ [MICROCHIP_PFSOC_SPI0] = { 0x20108000, 0x1000 },
127
+ [MICROCHIP_PFSOC_SPI1] = { 0x20109000, 0x1000 },
128
+ [MICROCHIP_PFSOC_I2C0] = { 0x2010a000, 0x1000 },
129
+ [MICROCHIP_PFSOC_I2C1] = { 0x2010b000, 0x1000 },
130
+ [MICROCHIP_PFSOC_CAN0] = { 0x2010c000, 0x1000 },
131
+ [MICROCHIP_PFSOC_CAN1] = { 0x2010d000, 0x1000 },
132
+ [MICROCHIP_PFSOC_GEM0] = { 0x20110000, 0x2000 },
133
+ [MICROCHIP_PFSOC_GEM1] = { 0x20112000, 0x2000 },
134
+ [MICROCHIP_PFSOC_GPIO0] = { 0x20120000, 0x1000 },
135
+ [MICROCHIP_PFSOC_GPIO1] = { 0x20121000, 0x1000 },
136
+ [MICROCHIP_PFSOC_GPIO2] = { 0x20122000, 0x1000 },
137
+ [MICROCHIP_PFSOC_RTC] = { 0x20124000, 0x1000 },
138
+ [MICROCHIP_PFSOC_ENVM_CFG] = { 0x20200000, 0x1000 },
139
+ [MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
140
+ [MICROCHIP_PFSOC_USB] = { 0x20201000, 0x1000 },
141
+ [MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
142
+ [MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
143
+ [MICROCHIP_PFSOC_FABRIC_FIC0] = { 0x2000000000, 0x1000000000 },
144
+ [MICROCHIP_PFSOC_FABRIC_FIC1] = { 0x3000000000, 0x1000000000 },
145
+ [MICROCHIP_PFSOC_FABRIC_FIC3] = { 0x40000000, 0x20000000 },
146
+ [MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
147
+ [MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
148
+ [MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 },
149
+ [MICROCHIP_PFSOC_DRAM_HI_ALIAS] = { 0x1400000000, 0x0 },
150
+
151
};
152
153
static void microchip_pfsoc_soc_instance_init(Object *obj)
154
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
155
create_unimplemented_device("microchip.pfsoc.fabricfic3",
156
memmap[MICROCHIP_PFSOC_FABRIC_FIC3].base,
157
memmap[MICROCHIP_PFSOC_FABRIC_FIC3].size);
158
+ /* FPGA Fabric */
159
+ create_unimplemented_device("microchip.pfsoc.fabricfic0",
160
+ memmap[MICROCHIP_PFSOC_FABRIC_FIC0].base,
161
+ memmap[MICROCHIP_PFSOC_FABRIC_FIC0].size);
162
+ /* FPGA Fabric */
163
+ create_unimplemented_device("microchip.pfsoc.fabricfic1",
164
+ memmap[MICROCHIP_PFSOC_FABRIC_FIC1].base,
165
+ memmap[MICROCHIP_PFSOC_FABRIC_FIC1].size);
166
167
/* QSPI Flash */
168
memory_region_init_rom(qspi_xip_mem, OBJECT(dev),
169
--
34
--
170
2.38.1
35
2.41.0
diff view generated by jsdifflib
1
From: Mayuresh Chitale <mchitale@ventanamicro.com>
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
2
2
3
Accesses to henvcfg, henvcfgh and senvcfg are allowed only if the corresponding
3
The Svadu specification updated the name of the *envcfg bit from
4
bit in mstateen0/hstateen0 is enabled. Otherwise an illegal instruction trap is
4
HADE to ADUE.
5
generated.
6
5
7
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
6
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
Reviewed-by: Weiwei Li<liweiwei@iscas.ac.cn>
7
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Message-Id: <20221016124726.102129-3-mchitale@ventanamicro.com>
9
Message-ID: <20230816141916.66898-1-liweiwei@iscas.ac.cn>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
11
---
13
target/riscv/csr.c | 87 ++++++++++++++++++++++++++++++++++++++++++----
12
target/riscv/cpu_bits.h | 8 ++++----
14
1 file changed, 80 insertions(+), 7 deletions(-)
13
target/riscv/cpu.c | 4 ++--
14
target/riscv/cpu_helper.c | 6 +++---
15
target/riscv/csr.c | 12 ++++++------
16
4 files changed, 15 insertions(+), 15 deletions(-)
15
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++) {
68
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/riscv/cpu_helper.c
71
+++ b/target/riscv/cpu_helper.c
72
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
73
}
74
75
bool pbmte = env->menvcfg & MENVCFG_PBMTE;
76
- bool hade = env->menvcfg & MENVCFG_HADE;
77
+ bool adue = env->menvcfg & MENVCFG_ADUE;
78
79
if (first_stage && two_stage && env->virt_enabled) {
80
pbmte = pbmte && (env->henvcfg & HENVCFG_PBMTE);
81
- hade = hade && (env->henvcfg & HENVCFG_HADE);
82
+ adue = adue && (env->henvcfg & HENVCFG_ADUE);
83
}
84
85
int ptshift = (levels - 1) * ptidxbits;
86
@@ -XXX,XX +XXX,XX @@ restart:
87
88
/* Page table updates need to be atomic with MTTCG enabled */
89
if (updated_pte != pte && !is_debug) {
90
- if (!hade) {
91
+ if (!adue) {
92
return TRANSLATE_FAIL;
93
}
94
16
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
17
index XXXXXXX..XXXXXXX 100644
96
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/csr.c
97
--- a/target/riscv/csr.c
19
+++ b/target/riscv/csr.c
98
+++ b/target/riscv/csr.c
20
@@ -XXX,XX +XXX,XX @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
99
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
21
}
100
if (riscv_cpu_mxl(env) == MXL_RV64) {
22
101
mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
23
/* Predicates */
102
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
24
+#if !defined(CONFIG_USER_ONLY)
103
- (cfg->ext_svadu ? MENVCFG_HADE : 0);
25
+static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
104
+ (cfg->ext_svadu ? MENVCFG_ADUE : 0);
26
+ uint64_t bit)
105
}
27
+{
106
env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
28
+ bool virt = riscv_cpu_virt_enabled(env);
107
29
+ CPUState *cs = env_cpu(env);
30
+ RISCVCPU *cpu = RISCV_CPU(cs);
31
+
32
+ if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
33
+ return RISCV_EXCP_NONE;
34
+ }
35
+
36
+ if (!(env->mstateen[index] & bit)) {
37
+ return RISCV_EXCP_ILLEGAL_INST;
38
+ }
39
+
40
+ if (virt) {
41
+ if (!(env->hstateen[index] & bit)) {
42
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
43
+ }
44
+
45
+ if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
46
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
47
+ }
48
+ }
49
+
50
+ if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
51
+ if (!(env->sstateen[index] & bit)) {
52
+ return RISCV_EXCP_ILLEGAL_INST;
53
+ }
54
+ }
55
+
56
+ return RISCV_EXCP_NONE;
57
+}
58
+#endif
59
+
60
static RISCVException fs(CPURISCVState *env, int csrno)
61
{
62
#if !defined(CONFIG_USER_ONLY)
63
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
108
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
64
static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
109
const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
65
target_ulong *val)
110
uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
66
{
111
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
67
+ RISCVException ret;
112
- (cfg->ext_svadu ? MENVCFG_HADE : 0);
68
+
113
+ (cfg->ext_svadu ? MENVCFG_ADUE : 0);
69
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
114
uint64_t valh = (uint64_t)val << 32;
70
+ if (ret != RISCV_EXCP_NONE) {
115
71
+ return ret;
116
env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
72
+ }
117
@@ -XXX,XX +XXX,XX @@ static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
73
+
118
* henvcfg.stce is read_only 0 when menvcfg.stce = 0
74
*val = env->senvcfg;
119
* henvcfg.hade is read_only 0 when menvcfg.hade = 0
75
return RISCV_EXCP_NONE;
120
*/
76
}
121
- *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) |
77
@@ -XXX,XX +XXX,XX @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
122
+ *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
78
target_ulong val)
123
env->menvcfg);
79
{
80
uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
81
+ RISCVException ret;
82
83
- env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
84
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
85
+ if (ret != RISCV_EXCP_NONE) {
86
+ return ret;
87
+ }
88
89
+ env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
90
return RISCV_EXCP_NONE;
91
}
92
93
static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
94
target_ulong *val)
95
{
96
+ RISCVException ret;
97
+
98
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
99
+ if (ret != RISCV_EXCP_NONE) {
100
+ return ret;
101
+ }
102
+
103
*val = env->henvcfg;
104
return RISCV_EXCP_NONE;
124
return RISCV_EXCP_NONE;
105
}
125
}
106
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
126
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
107
target_ulong val)
127
}
108
{
109
uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
110
+ RISCVException ret;
111
+
112
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
113
+ if (ret != RISCV_EXCP_NONE) {
114
+ return ret;
115
+ }
116
128
117
if (riscv_cpu_mxl(env) == MXL_RV64) {
129
if (riscv_cpu_mxl(env) == MXL_RV64) {
118
mask |= HENVCFG_PBMTE | HENVCFG_STCE;
130
- mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE);
119
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
131
+ mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE);
120
static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
132
}
121
target_ulong *val)
133
122
{
134
env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
123
+ RISCVException ret;
135
@@ -XXX,XX +XXX,XX @@ static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
124
+
136
return ret;
125
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
137
}
126
+ if (ret != RISCV_EXCP_NONE) {
138
127
+ return ret;
139
- *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) |
128
+ }
140
+ *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
129
+
141
env->menvcfg)) >> 32;
130
*val = env->henvcfg >> 32;
131
return RISCV_EXCP_NONE;
142
return RISCV_EXCP_NONE;
132
}
143
}
133
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
144
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
145
target_ulong val)
134
{
146
{
135
uint64_t mask = HENVCFG_PBMTE | HENVCFG_STCE;
147
uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE |
148
- HENVCFG_HADE);
149
+ HENVCFG_ADUE);
136
uint64_t valh = (uint64_t)val << 32;
150
uint64_t valh = (uint64_t)val << 32;
137
+ RISCVException ret;
151
RISCVException ret;
138
152
139
- env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
140
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
141
+ if (ret != RISCV_EXCP_NONE) {
142
+ return ret;
143
+ }
144
145
+ env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
146
return RISCV_EXCP_NONE;
147
}
148
149
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstateen(CPURISCVState *env, int csrno,
150
static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
151
target_ulong new_val)
152
{
153
- uint64_t wr_mask = SMSTATEEN_STATEEN;
154
+ uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
155
156
return write_mstateen(env, csrno, wr_mask, new_val);
157
}
158
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstateenh(CPURISCVState *env, int csrno,
159
static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
160
target_ulong new_val)
161
{
162
- uint64_t wr_mask = SMSTATEEN_STATEEN;
163
+ uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
164
165
return write_mstateenh(env, csrno, wr_mask, new_val);
166
}
167
@@ -XXX,XX +XXX,XX @@ static RISCVException write_hstateen(CPURISCVState *env, int csrno,
168
static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
169
target_ulong new_val)
170
{
171
- uint64_t wr_mask = SMSTATEEN_STATEEN;
172
+ uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
173
174
return write_hstateen(env, csrno, wr_mask, new_val);
175
}
176
@@ -XXX,XX +XXX,XX @@ static RISCVException write_hstateenh(CPURISCVState *env, int csrno,
177
static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
178
target_ulong new_val)
179
{
180
- uint64_t wr_mask = SMSTATEEN_STATEEN;
181
+ uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
182
183
return write_hstateenh(env, csrno, wr_mask, new_val);
184
}
185
@@ -XXX,XX +XXX,XX @@ static RISCVException write_sstateen(CPURISCVState *env, int csrno,
186
static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
187
target_ulong new_val)
188
{
189
- uint64_t wr_mask = SMSTATEEN_STATEEN;
190
+ uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
191
192
return write_sstateen(env, csrno, wr_mask, new_val);
193
}
194
--
153
--
195
2.38.1
154
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
At present the default value of "num-sources" property is zero,
3
In the same emulated RISC-V host, the 'host' KVM CPU takes 4 times
4
which does not make a lot of sense, as in sifive_plic_realize()
4
longer to boot than the 'rv64' KVM CPU.
5
we see s->bitfield_words is calculated by:
6
5
7
s->bitfield_words = (s->num_sources + 31) >> 5;
6
The reason is an unintended behavior of riscv_cpu_satp_mode_finalize()
7
when satp_mode.supported = 0, i.e. when cpu_init() does not set
8
satp_mode_max_supported(). satp_mode_max_from_map(map) does:
8
9
9
if the we don't configure "num-sources" property its default value
10
31 - __builtin_clz(map)
10
zero makes s->bitfield_words zero too, which isn't true because
11
interrupt source 0 still occupies one word.
12
11
13
Let's change the default value to 1 meaning that only interrupt
12
This means that, if satp_mode.supported = 0, satp_mode_supported_max
14
source 0 is supported by default and a sanity check in realize().
13
wil be '31 - 32'. But this is C, so satp_mode_supported_max will gladly
14
set it to UINT_MAX (4294967295). After that, if the user didn't set a
15
satp_mode, set_satp_mode_default_map(cpu) will make
15
16
16
While we are here, add a comment to describe the exact meaning of
17
cfg.satp_mode.map = cfg.satp_mode.supported
17
this property that the number should include interrupt source 0.
18
18
19
Signed-off-by: Bin Meng <bmeng@tinylab.org>
19
So satp_mode.map = 0. And then satp_mode_map_max will be set to
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
20
satp_mode_max_from_map(cpu->cfg.satp_mode.map), i.e. also UINT_MAX. The
21
Message-Id: <20221211030829.802437-9-bmeng@tinylab.org>
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")
41
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
42
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
43
Message-ID: <20230817152903.694926-1-dbarboza@ventanamicro.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
44
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
45
---
24
hw/intc/sifive_plic.c | 8 +++++++-
46
target/riscv/cpu.c | 23 ++++++++++++++++++++---
25
1 file changed, 7 insertions(+), 1 deletion(-)
47
1 file changed, 20 insertions(+), 3 deletions(-)
26
48
27
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
49
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
28
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/intc/sifive_plic.c
51
--- a/target/riscv/cpu.c
30
+++ b/hw/intc/sifive_plic.c
52
+++ b/target/riscv/cpu.c
31
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
53
@@ -XXX,XX +XXX,XX @@ static uint8_t satp_mode_from_str(const char *satp_mode_str)
32
54
33
parse_hart_config(s);
55
uint8_t satp_mode_max_from_map(uint32_t map)
34
56
{
35
+ if (!s->num_sources) {
57
+ /*
36
+ error_setg(errp, "plic: invalid number of interrupt sources");
58
+ * 'map = 0' will make us return (31 - 32), which C will
59
+ * happily overflow to UINT_MAX. There's no good result to
60
+ * return if 'map = 0' (e.g. returning 0 will be ambiguous
61
+ * with the result for 'map = 1').
62
+ *
63
+ * Assert out if map = 0. Callers will have to deal with
64
+ * it outside of this function.
65
+ */
66
+ g_assert(map > 0);
67
+
68
/* map here has at least one bit set, so no problem with clz */
69
return 31 - __builtin_clz(map);
70
}
71
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
72
static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
73
{
74
bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
75
- uint8_t satp_mode_map_max;
76
- uint8_t satp_mode_supported_max =
77
- satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
78
+ uint8_t satp_mode_map_max, satp_mode_supported_max;
79
+
80
+ /* The CPU wants the OS to decide which satp mode to use */
81
+ if (cpu->cfg.satp_mode.supported == 0) {
37
+ return;
82
+ return;
38
+ }
83
+ }
39
+
84
+
40
s->bitfield_words = (s->num_sources + 31) >> 5;
85
+ satp_mode_supported_max =
41
s->num_enables = s->bitfield_words * s->num_addrs;
86
+ satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
42
s->source_priority = g_new0(uint32_t, s->num_sources);
87
43
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_sifive_plic = {
88
if (cpu->cfg.satp_mode.map == 0) {
44
static Property sifive_plic_properties[] = {
89
if (cpu->cfg.satp_mode.init == 0) {
45
DEFINE_PROP_STRING("hart-config", SiFivePLICState, hart_config),
46
DEFINE_PROP_UINT32("hartid-base", SiFivePLICState, hartid_base, 0),
47
- DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 0),
48
+ /* number of interrupt sources including interrupt source 0 */
49
+ DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 1),
50
DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
51
DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
52
DEFINE_PROP_UINT32("pending-base", SiFivePLICState, pending_base, 0),
53
--
90
--
54
2.38.1
91
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Vineet Gupta <vineetg@rivosinc.com>
2
2
3
Per chapter 6.5.2 in [1], the number of interupt sources including
3
zicond is now codegen supported in both llvm and gcc.
4
interrupt source 0 should be 187.
5
4
6
[1] PolarFire SoC MSS TRM:
5
This change allows seamless enabling/testing of zicond in downstream
7
https://ww1.microchip.com/downloads/aemDocuments/documents/FPGA/ProductDocuments/ReferenceManuals/PolarFire_SoC_FPGA_MSS_Technical_Reference_Manual_VC.pdf
6
projects. e.g. currently riscv-gnu-toolchain parses elf attributes
7
to create a cmdline for qemu but fails short of enabling it because of
8
the "x-" prefix.
8
9
9
Fixes: 56f6e31e7b7e ("hw/riscv: Initial support for Microchip PolarFire SoC Icicle Kit board")
10
Signed-off-by: Vineet Gupta <vineetg@rivosinc.com>
10
Signed-off-by: Bin Meng <bmeng@tinylab.org>
11
Message-ID: <20230808181715.436395-1-vineetg@rivosinc.com>
11
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
14
Message-Id: <20221211030829.802437-10-bmeng@tinylab.org>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
14
---
17
include/hw/riscv/microchip_pfsoc.h | 2 +-
15
target/riscv/cpu.c | 2 +-
18
1 file changed, 1 insertion(+), 1 deletion(-)
16
1 file changed, 1 insertion(+), 1 deletion(-)
19
17
20
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
18
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/riscv/microchip_pfsoc.h
20
--- a/target/riscv/cpu.c
23
+++ b/include/hw/riscv/microchip_pfsoc.h
21
+++ b/target/riscv/cpu.c
24
@@ -XXX,XX +XXX,XX @@ enum {
22
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
25
#define MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT 1
23
DEFINE_PROP_BOOL("zcf", RISCVCPU, cfg.ext_zcf, false),
26
#define MICROCHIP_PFSOC_COMPUTE_CPU_COUNT 4
24
DEFINE_PROP_BOOL("zcmp", RISCVCPU, cfg.ext_zcmp, false),
27
25
DEFINE_PROP_BOOL("zcmt", RISCVCPU, cfg.ext_zcmt, false),
28
-#define MICROCHIP_PFSOC_PLIC_NUM_SOURCES 185
26
+ DEFINE_PROP_BOOL("zicond", RISCVCPU, cfg.ext_zicond, false),
29
+#define MICROCHIP_PFSOC_PLIC_NUM_SOURCES 187
27
30
#define MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES 7
28
/* Vendor-specific custom extensions */
31
#define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE 0x04
29
DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
32
#define MICROCHIP_PFSOC_PLIC_PENDING_BASE 0x1000
30
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
31
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
32
33
/* These are experimental so mark with 'x-' */
34
- DEFINE_PROP_BOOL("x-zicond", RISCVCPU, cfg.ext_zicond, false),
35
36
/* ePMP 0.9.3 */
37
DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
33
--
38
--
34
2.38.1
39
2.41.0
diff view generated by jsdifflib
1
From: Atish Patra <atishp@rivosinc.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
The imsic DT binding[1] has changed and no longer require an ipi-id.
3
A build with --enable-debug and without KVM will fail as follows:
4
The latest IMSIC driver dynamically allocates ipi id if slow-ipi
5
is not defined.
6
4
7
Get rid of the unused dt property which may lead to confusion.
5
/usr/bin/ld: libqemu-riscv64-softmmu.fa.p/hw_riscv_virt.c.o: in function `virt_machine_init':
6
./qemu/build/../hw/riscv/virt.c:1465: undefined reference to `kvm_riscv_aia_create'
8
7
9
[1] https://lore.kernel.org/lkml/20221111044207.1478350-5-apatel@ventanamicro.com/
8
This happens because the code block with "if virt_use_kvm_aia(s)" isn't
9
being ignored by the debug build, resulting in an undefined reference to
10
a KVM only function.
10
11
11
Signed-off-by: Atish Patra <atishp@rivosinc.com>
12
Add a 'kvm_enabled()' conditional together with virt_use_kvm_aia() will
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
make the compiler crop the kvm_riscv_aia_create() call entirely from a
13
Message-Id: <20221122080529.1692533-1-atishp@rivosinc.com>
14
non-KVM build. Note that adding the 'kvm_enabled()' conditional inside
15
virt_use_kvm_aia() won't fix the build because this function would need
16
to be inlined multiple times to make the compiler zero out the entire
17
block.
18
19
While we're at it, use kvm_enabled() in all instances where
20
virt_use_kvm_aia() is checked to allow the compiler to elide these other
21
kvm-only instances as well.
22
23
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
24
Fixes: dbdb99948e ("target/riscv: select KVM AIA in riscv virt machine")
25
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
26
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
27
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Message-ID: <20230830133503.711138-2-dbarboza@ventanamicro.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
31
---
16
include/hw/riscv/virt.h | 1 -
32
hw/riscv/virt.c | 6 +++---
17
hw/riscv/virt.c | 4 ----
33
1 file changed, 3 insertions(+), 3 deletions(-)
18
2 files changed, 5 deletions(-)
19
34
20
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/riscv/virt.h
23
+++ b/include/hw/riscv/virt.h
24
@@ -XXX,XX +XXX,XX @@ enum {
25
26
#define VIRT_PLATFORM_BUS_NUM_IRQS 32
27
28
-#define VIRT_IRQCHIP_IPI_MSI 1
29
#define VIRT_IRQCHIP_NUM_MSIS 255
30
#define VIRT_IRQCHIP_NUM_SOURCES VIRTIO_NDEV
31
#define VIRT_IRQCHIP_NUM_PRIO_BITS 3
32
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
33
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/riscv/virt.c
37
--- a/hw/riscv/virt.c
35
+++ b/hw/riscv/virt.c
38
+++ b/hw/riscv/virt.c
36
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
39
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
37
riscv_socket_count(mc) * sizeof(uint32_t) * 4);
40
}
38
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
41
39
VIRT_IRQCHIP_NUM_MSIS);
42
/* KVM AIA only has one APLIC instance */
40
- qemu_fdt_setprop_cells(mc->fdt, imsic_name, "riscv,ipi-id",
43
- if (virt_use_kvm_aia(s)) {
41
- VIRT_IRQCHIP_IPI_MSI);
44
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
42
if (riscv_socket_count(mc) > 1) {
45
create_fdt_socket_aplic(s, memmap, 0,
43
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits",
46
msi_m_phandle, msi_s_phandle, phandle,
44
imsic_num_bits(imsic_max_hart_per_socket));
47
&intc_phandles[0], xplic_phandles,
45
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
48
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
46
riscv_socket_count(mc) * sizeof(uint32_t) * 4);
49
47
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
50
g_free(intc_phandles);
48
VIRT_IRQCHIP_NUM_MSIS);
51
49
- qemu_fdt_setprop_cells(mc->fdt, imsic_name, "riscv,ipi-id",
52
- if (virt_use_kvm_aia(s)) {
50
- VIRT_IRQCHIP_IPI_MSI);
53
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
51
if (imsic_guest_bits) {
54
*irq_mmio_phandle = xplic_phandles[0];
52
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,guest-index-bits",
55
*irq_virtio_phandle = xplic_phandles[0];
53
imsic_guest_bits);
56
*irq_pcie_phandle = xplic_phandles[0];
57
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
58
}
59
}
60
61
- if (virt_use_kvm_aia(s)) {
62
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
63
kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT,
64
VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS,
65
memmap[VIRT_APLIC_S].base,
54
--
66
--
55
2.38.1
67
2.41.0
68
69
diff view generated by jsdifflib
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
This patch updates the OpenTitan model to match
3
Commit 6df0b37e2ab breaks a --enable-debug build in a non-KVM
4
the specified register layout as per [1]. Which is also the latest
4
environment with the following error:
5
commit of OpenTitan supported by TockOS.
6
5
7
Note: Pinmux and Padctrl has been merged into Pinmux [2][3], this patch removes
6
/usr/bin/ld: libqemu-riscv64-softmmu.fa.p/hw_intc_riscv_aplic.c.o: in function `riscv_kvm_aplic_request':
8
any references to Padctrl. Note: OpenTitan doc [2] has not yet specified
7
./qemu/build/../hw/intc/riscv_aplic.c:486: undefined reference to `kvm_set_irq'
9
much detail regarding this, except for a note that states `TODO: this
8
collect2: error: ld returned 1 exit status
10
section needs to be updated to reflect the pinmux/padctrl merger`
11
9
12
[1] https://github.com/lowRISC/opentitan/blob/d072ac505f82152678d6e04be95c72b728a347b8/hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
10
This happens because the debug build will poke into the
13
[2] https://docs.opentitan.org/hw/top_earlgrey/doc/design/
11
'if (is_kvm_aia(aplic->msimode))' block and fail to find a reference to
14
[3] https://docs.opentitan.org/hw/ip/pinmux/doc/#overview
12
the KVM only function riscv_kvm_aplic_request().
15
13
16
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
14
There are multiple solutions to fix this. We'll go with the same
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
solution from the previous patch, i.e. add a kvm_enabled() conditional
18
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
16
to filter out the block. But there's a catch: riscv_kvm_aplic_request()
19
Message-Id: <20221025043335.339815-2-wilfred.mallawa@opensource.wdc.com>
17
is a local function that would end up being used if the compiler crops
18
the block, and this won't work. Quoting Richard Henderson's explanation
19
in [1]:
20
21
"(...) the compiler won't eliminate entire unused functions with -O0"
22
23
We'll solve it by moving riscv_kvm_aplic_request() to kvm.c and add its
24
declaration in kvm_riscv.h, where all other KVM specific public
25
functions are already declared. Other archs handles KVM specific code in
26
this manner and we expect to do the same from now on.
27
28
[1] https://lore.kernel.org/qemu-riscv/d2f1ad02-eb03-138f-9d08-db676deeed05@linaro.org/
29
30
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
31
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
32
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
34
Message-ID: <20230830133503.711138-3-dbarboza@ventanamicro.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
36
---
22
include/hw/riscv/opentitan.h | 9 ++++-----
37
target/riscv/kvm_riscv.h | 1 +
23
hw/riscv/opentitan.c | 21 +++++++++++++--------
38
hw/intc/riscv_aplic.c | 8 ++------
24
2 files changed, 17 insertions(+), 13 deletions(-)
39
target/riscv/kvm.c | 5 +++++
40
3 files changed, 8 insertions(+), 6 deletions(-)
25
41
26
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
42
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
27
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/riscv/opentitan.h
44
--- a/target/riscv/kvm_riscv.h
29
+++ b/include/hw/riscv/opentitan.h
45
+++ b/target/riscv/kvm_riscv.h
30
@@ -XXX,XX +XXX,XX @@ enum {
46
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
31
IBEX_DEV_RSTMGR,
47
uint64_t aia_irq_num, uint64_t aia_msi_num,
32
IBEX_DEV_CLKMGR,
48
uint64_t aplic_base, uint64_t imsic_base,
33
IBEX_DEV_PINMUX,
49
uint64_t guest_num);
34
- IBEX_DEV_PADCTRL,
50
+void riscv_kvm_aplic_request(void *opaque, int irq, int level);
35
IBEX_DEV_USBDEV,
36
IBEX_DEV_FLASH_CTRL,
37
IBEX_DEV_PLIC,
38
@@ -XXX,XX +XXX,XX @@ enum {
39
IBEX_UART0_RX_TIMEOUT_IRQ = 7,
40
IBEX_UART0_RX_PARITY_ERR_IRQ = 8,
41
IBEX_TIMER_TIMEREXPIRED0_0 = 127,
42
- IBEX_SPI_HOST0_ERR_IRQ = 151,
43
- IBEX_SPI_HOST0_SPI_EVENT_IRQ = 152,
44
- IBEX_SPI_HOST1_ERR_IRQ = 153,
45
- IBEX_SPI_HOST1_SPI_EVENT_IRQ = 154,
46
+ IBEX_SPI_HOST0_ERR_IRQ = 134,
47
+ IBEX_SPI_HOST0_SPI_EVENT_IRQ = 135,
48
+ IBEX_SPI_HOST1_ERR_IRQ = 136,
49
+ IBEX_SPI_HOST1_SPI_EVENT_IRQ = 137,
50
};
51
51
52
#endif
52
#endif
53
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
53
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
54
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/riscv/opentitan.c
55
--- a/hw/intc/riscv_aplic.c
56
+++ b/hw/riscv/opentitan.c
56
+++ b/hw/intc/riscv_aplic.c
57
@@ -XXX,XX +XXX,XX @@
57
@@ -XXX,XX +XXX,XX @@
58
#include "qemu/units.h"
58
#include "target/riscv/cpu.h"
59
#include "sysemu/sysemu.h"
59
#include "sysemu/sysemu.h"
60
60
#include "sysemu/kvm.h"
61
+/*
61
+#include "kvm_riscv.h"
62
+ * This version of the OpenTitan machine currently supports
62
#include "migration/vmstate.h"
63
+ * OpenTitan RTL version:
63
64
+ * <lowRISC/opentitan@d072ac505f82152678d6e04be95c72b728a347b8>
64
#define APLIC_MAX_IDC (1UL << 14)
65
+ *
65
@@ -XXX,XX +XXX,XX @@ static uint32_t riscv_aplic_idc_claimi(RISCVAPLICState *aplic, uint32_t idc)
66
+ * MMIO mapping as per (specified commit):
66
return topi;
67
+ * lowRISC/opentitan: hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
67
}
68
+ */
68
69
static const MemMapEntry ibex_memmap[] = {
69
-static void riscv_kvm_aplic_request(void *opaque, int irq, int level)
70
- [IBEX_DEV_ROM] = { 0x00008000, 0x8000 },
70
-{
71
+ [IBEX_DEV_ROM] = { 0x00008000, 0x8000 },
71
- kvm_set_irq(kvm_state, irq, !!level);
72
[IBEX_DEV_RAM] = { 0x10000000, 0x20000 },
72
-}
73
[IBEX_DEV_FLASH] = { 0x20000000, 0x100000 },
73
-
74
[IBEX_DEV_UART] = { 0x40000000, 0x1000 },
74
static void riscv_aplic_request(void *opaque, int irq, int level)
75
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = {
75
{
76
[IBEX_DEV_I2C] = { 0x40080000, 0x1000 },
76
bool update = false;
77
[IBEX_DEV_PATTGEN] = { 0x400e0000, 0x1000 },
77
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
78
[IBEX_DEV_TIMER] = { 0x40100000, 0x1000 },
78
* have IRQ lines delegated by their parent APLIC.
79
- [IBEX_DEV_SENSOR_CTRL] = { 0x40110000, 0x1000 },
79
*/
80
[IBEX_DEV_OTP_CTRL] = { 0x40130000, 0x4000 },
80
if (!aplic->parent) {
81
[IBEX_DEV_LC_CTRL] = { 0x40140000, 0x1000 },
81
- if (is_kvm_aia(aplic->msimode)) {
82
- [IBEX_DEV_USBDEV] = { 0x40150000, 0x1000 },
82
+ if (kvm_enabled() && is_kvm_aia(aplic->msimode)) {
83
+ [IBEX_DEV_ALERT_HANDLER] = { 0x40150000, 0x1000 },
83
qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs);
84
[IBEX_DEV_SPI_HOST0] = { 0x40300000, 0x1000 },
84
} else {
85
[IBEX_DEV_SPI_HOST1] = { 0x40310000, 0x1000 },
85
qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
86
+ [IBEX_DEV_USBDEV] = { 0x40320000, 0x1000 },
86
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
87
[IBEX_DEV_PWRMGR] = { 0x40400000, 0x1000 },
87
index XXXXXXX..XXXXXXX 100644
88
[IBEX_DEV_RSTMGR] = { 0x40410000, 0x1000 },
88
--- a/target/riscv/kvm.c
89
[IBEX_DEV_CLKMGR] = { 0x40420000, 0x1000 },
89
+++ b/target/riscv/kvm.c
90
[IBEX_DEV_PINMUX] = { 0x40460000, 0x1000 },
90
@@ -XXX,XX +XXX,XX @@
91
- [IBEX_DEV_PADCTRL] = { 0x40470000, 0x1000 },
91
#include "sysemu/runstate.h"
92
+ [IBEX_DEV_SENSOR_CTRL] = { 0x40490000, 0x1000 },
92
#include "hw/riscv/numa.h"
93
[IBEX_DEV_FLASH_CTRL] = { 0x41000000, 0x1000 },
93
94
[IBEX_DEV_AES] = { 0x41100000, 0x1000 },
94
+void riscv_kvm_aplic_request(void *opaque, int irq, int level)
95
[IBEX_DEV_HMAC] = { 0x41110000, 0x1000 },
95
+{
96
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = {
96
+ kvm_set_irq(kvm_state, irq, !!level);
97
[IBEX_DEV_ENTROPY] = { 0x41160000, 0x1000 },
97
+}
98
[IBEX_DEV_EDNO] = { 0x41170000, 0x1000 },
98
+
99
[IBEX_DEV_EDN1] = { 0x41180000, 0x1000 },
99
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
100
- [IBEX_DEV_ALERT_HANDLER] = { 0x411b0000, 0x1000 },
100
uint64_t idx)
101
[IBEX_DEV_NMI_GEN] = { 0x411c0000, 0x1000 },
101
{
102
[IBEX_DEV_PERI] = { 0x411f0000, 0x10000 },
103
- [IBEX_DEV_PLIC] = { 0x48000000, 0x4005000 },
104
+ [IBEX_DEV_PLIC] = { 0x48000000, 0x4005000 },
105
[IBEX_DEV_FLASH_VIRTUAL] = { 0x80000000, 0x80000 },
106
};
107
108
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
109
memmap[IBEX_DEV_CLKMGR].base, memmap[IBEX_DEV_CLKMGR].size);
110
create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
111
memmap[IBEX_DEV_PINMUX].base, memmap[IBEX_DEV_PINMUX].size);
112
- create_unimplemented_device("riscv.lowrisc.ibex.padctrl",
113
- memmap[IBEX_DEV_PADCTRL].base, memmap[IBEX_DEV_PADCTRL].size);
114
create_unimplemented_device("riscv.lowrisc.ibex.usbdev",
115
memmap[IBEX_DEV_USBDEV].base, memmap[IBEX_DEV_USBDEV].size);
116
create_unimplemented_device("riscv.lowrisc.ibex.flash_ctrl",
117
--
102
--
118
2.38.1
103
2.41.0
104
105
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Robbin Ehn <rehn@rivosinc.com>
2
2
3
We were matching a signed 13-bit range, not a 12-bit range.
3
This patch adds the new extensions in
4
Expand the commentary within the function and be explicit
4
linux 6.5 to the hwprobe syscall.
5
about all of the ranges.
6
5
7
Reported-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
6
And fixes RVC check to OR with correct value.
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
The previous variable contains 0 therefore it
9
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
did work.
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
11
Message-Id: <20221022095821.2441874-1-richard.henderson@linaro.org>
10
Signed-off-by: Robbin Ehn <rehn@rivosinc.com>
11
Acked-by: Richard Henderson <richard.henderson@linaro.org>
12
Acked-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <bc82203b72d7efb30f1b4a8f9eb3d94699799dc8.camel@rivosinc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
15
---
14
tcg/riscv/tcg-target.c.inc | 19 ++++++++++++++++---
16
linux-user/syscall.c | 14 +++++++++++++-
15
1 file changed, 16 insertions(+), 3 deletions(-)
17
1 file changed, 13 insertions(+), 1 deletion(-)
16
18
17
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
19
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/tcg/riscv/tcg-target.c.inc
21
--- a/linux-user/syscall.c
20
+++ b/tcg/riscv/tcg-target.c.inc
22
+++ b/linux-user/syscall.c
21
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
23
@@ -XXX,XX +XXX,XX @@ static int do_getdents64(abi_long dirfd, abi_long arg2, abi_long count)
22
if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
24
#define RISCV_HWPROBE_KEY_IMA_EXT_0 4
23
return 1;
25
#define RISCV_HWPROBE_IMA_FD (1 << 0)
24
}
26
#define RISCV_HWPROBE_IMA_C (1 << 1)
25
- if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) {
27
+#define RISCV_HWPROBE_IMA_V (1 << 2)
26
+ /*
28
+#define RISCV_HWPROBE_EXT_ZBA (1 << 3)
27
+ * Sign extended from 12 bits: [-0x800, 0x7ff].
29
+#define RISCV_HWPROBE_EXT_ZBB (1 << 4)
28
+ * Used for most arithmetic, as this is the isa field.
30
+#define RISCV_HWPROBE_EXT_ZBS (1 << 5)
29
+ */
31
30
+ if ((ct & TCG_CT_CONST_S12) && val >= -0x800 && val <= 0x7ff) {
32
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
31
return 1;
33
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
32
}
34
@@ -XXX,XX +XXX,XX @@ static void risc_hwprobe_fill_pairs(CPURISCVState *env,
33
- if ((ct & TCG_CT_CONST_N12) && -val == sextreg(-val, 0, 12)) {
35
riscv_has_ext(env, RVD) ?
34
+ /*
36
RISCV_HWPROBE_IMA_FD : 0;
35
+ * Sign extended from 12 bits, negated: [-0x7ff, 0x800].
37
value |= riscv_has_ext(env, RVC) ?
36
+ * Used for subtraction, where a constant must be handled by ADDI.
38
- RISCV_HWPROBE_IMA_C : pair->value;
37
+ */
39
+ RISCV_HWPROBE_IMA_C : 0;
38
+ if ((ct & TCG_CT_CONST_N12) && val >= -0x7ff && val <= 0x800) {
40
+ value |= riscv_has_ext(env, RVV) ?
39
return 1;
41
+ RISCV_HWPROBE_IMA_V : 0;
40
}
42
+ value |= cfg->ext_zba ?
41
- if ((ct & TCG_CT_CONST_M12) && val >= -0xfff && val <= 0xfff) {
43
+ RISCV_HWPROBE_EXT_ZBA : 0;
42
+ /*
44
+ value |= cfg->ext_zbb ?
43
+ * Sign extended from 12 bits, +/- matching: [-0x7ff, 0x7ff].
45
+ RISCV_HWPROBE_EXT_ZBB : 0;
44
+ * Used by addsub2, which may need the negative operation,
46
+ value |= cfg->ext_zbs ?
45
+ * and requires the modified constant to be representable.
47
+ RISCV_HWPROBE_EXT_ZBS : 0;
46
+ */
48
__put_user(value, &pair->value);
47
+ if ((ct & TCG_CT_CONST_M12) && val >= -0x7ff && val <= 0x7ff) {
49
break;
48
return 1;
50
case RISCV_HWPROBE_KEY_CPUPERF_0:
49
}
50
return 0;
51
--
51
--
52
2.38.1
52
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Ard Biesheuvel <ardb@kernel.org>
2
2
3
The priv spec v1.12 says:
3
Use the accelerated SubBytes/ShiftRows/AddRoundKey AES helper to
4
implement the first half of the key schedule derivation. This does not
5
actually involve shifting rows, so clone the same value into all four
6
columns of the AES vector to counter that operation.
4
7
5
If no PMP entry matches an M-mode access, the access succeeds. If
8
Cc: Richard Henderson <richard.henderson@linaro.org>
6
no PMP entry matches an S-mode or U-mode access, but at least one
9
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
7
PMP entry is implemented, the access fails. Failed accesses generate
10
Cc: Palmer Dabbelt <palmer@dabbelt.com>
8
an instruction, load, or store access-fault exception.
11
Cc: Alistair Francis <alistair.francis@wdc.com>
9
12
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
10
At present the exception cause is set to 'illegal instruction' but
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
should have been 'instruction access fault'.
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
15
Message-ID: <20230831154118.138727-1-ardb@kernel.org>
13
Fixes: d102f19a2085 ("target/riscv/pmp: Raise exception if no PMP entry is configured")
14
Signed-off-by: Bin Meng <bmeng@tinylab.org>
15
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-Id: <20221205065303.204095-1-bmeng@tinylab.org>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
17
---
20
target/riscv/op_helper.c | 2 +-
18
target/riscv/crypto_helper.c | 17 +++++------------
21
1 file changed, 1 insertion(+), 1 deletion(-)
19
1 file changed, 5 insertions(+), 12 deletions(-)
22
20
23
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
21
diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c
24
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
25
--- a/target/riscv/op_helper.c
23
--- a/target/riscv/crypto_helper.c
26
+++ b/target/riscv/op_helper.c
24
+++ b/target/riscv/crypto_helper.c
27
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mret(CPURISCVState *env)
25
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(aes64ks1i)(target_ulong rs1, target_ulong rnum)
28
26
29
if (riscv_feature(env, RISCV_FEATURE_PMP) &&
27
uint8_t enc_rnum = rnum;
30
!pmp_get_num_rules(env) && (prev_priv != PRV_M)) {
28
uint32_t temp = (RS1 >> 32) & 0xFFFFFFFF;
31
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
29
- uint8_t rcon_ = 0;
32
+ riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC());
30
- target_ulong result;
31
+ AESState t, rc = {};
32
33
if (enc_rnum != 0xA) {
34
temp = ror32(temp, 8); /* Rotate right by 8 */
35
- rcon_ = round_consts[enc_rnum];
36
+ rc.w[0] = rc.w[1] = round_consts[enc_rnum];
33
}
37
}
34
38
35
target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV);
39
- temp = ((uint32_t)AES_sbox[(temp >> 24) & 0xFF] << 24) |
40
- ((uint32_t)AES_sbox[(temp >> 16) & 0xFF] << 16) |
41
- ((uint32_t)AES_sbox[(temp >> 8) & 0xFF] << 8) |
42
- ((uint32_t)AES_sbox[(temp >> 0) & 0xFF] << 0);
43
+ t.w[0] = t.w[1] = t.w[2] = t.w[3] = temp;
44
+ aesenc_SB_SR_AK(&t, &t, &rc, false);
45
46
- temp ^= rcon_;
47
-
48
- result = ((uint64_t)temp << 32) | temp;
49
-
50
- return result;
51
+ return t.d[0];
52
}
53
54
target_ulong HELPER(aes64im)(target_ulong rs1)
36
--
55
--
37
2.38.1
56
2.41.0
57
58
diff view generated by jsdifflib
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
The max count in itrigger can be 0x3FFF, which will cause a no trivial
3
riscv_trigger_init() had been called on reset events that can happen
4
translation and execution overload.
4
several times for a CPU and it allocated timers for itrigger. If old
5
timers were present, they were simply overwritten by the new timers,
6
resulting in a memory leak.
5
7
6
When icount is enabled, QEMU provides API that can fetch guest
8
Divide riscv_trigger_init() into two functions, namely
7
instruction number. Thus, we can set an timer for itrigger with
9
riscv_trigger_realize() and riscv_trigger_reset() and call them in
8
the count as deadline.
10
appropriate timing. The timer allocation will happen only once for a
11
CPU in riscv_trigger_realize().
9
12
10
Only when timer expires or priviledge mode changes, do lazy update
13
Fixes: 5a4ae64cac ("target/riscv: Add itrigger support when icount is enabled")
11
to count.
14
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
12
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
16
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-Id: <20221013062946.7530-3-zhiwei_liu@linux.alibaba.com>
18
Message-ID: <20230818034059.9146-1-akihiko.odaki@daynix.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
20
---
18
target/riscv/cpu.h | 2 ++
21
target/riscv/debug.h | 3 ++-
19
target/riscv/debug.h | 1 +
22
target/riscv/cpu.c | 8 +++++++-
20
target/riscv/cpu_helper.c | 3 ++
23
target/riscv/debug.c | 15 ++++++++++++---
21
target/riscv/debug.c | 59 +++++++++++++++++++++++++++++++++++++++
24
3 files changed, 21 insertions(+), 5 deletions(-)
22
4 files changed, 65 insertions(+)
23
25
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
28
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
29
target_ulong tdata3[RV_MAX_TRIGGERS];
30
struct CPUBreakpoint *cpu_breakpoint[RV_MAX_TRIGGERS];
31
struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
32
+ QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
33
+ int64_t last_icount;
34
35
/* machine specific rdtime callback */
36
uint64_t (*rdtime_fn)(void *);
37
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
26
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
38
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
39
--- a/target/riscv/debug.h
28
--- a/target/riscv/debug.h
40
+++ b/target/riscv/debug.h
29
+++ b/target/riscv/debug.h
41
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
30
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_debug_excp_handler(CPUState *cs);
42
void riscv_trigger_init(CPURISCVState *env);
31
bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
32
bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
33
34
-void riscv_trigger_init(CPURISCVState *env);
35
+void riscv_trigger_realize(CPURISCVState *env);
36
+void riscv_trigger_reset_hold(CPURISCVState *env);
43
37
44
bool riscv_itrigger_enabled(CPURISCVState *env);
38
bool riscv_itrigger_enabled(CPURISCVState *env);
45
+void riscv_itrigger_update_priv(CPURISCVState *env);
39
void riscv_itrigger_update_priv(CPURISCVState *env);
46
#endif /* RISCV_DEBUG_H */
40
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
47
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
48
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
49
--- a/target/riscv/cpu_helper.c
42
--- a/target/riscv/cpu.c
50
+++ b/target/riscv/cpu_helper.c
43
+++ b/target/riscv/cpu.c
51
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
44
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj)
52
if (newpriv == PRV_H) {
45
53
newpriv = PRV_U;
46
#ifndef CONFIG_USER_ONLY
47
if (cpu->cfg.debug) {
48
- riscv_trigger_init(env);
49
+ riscv_trigger_reset_hold(env);
54
}
50
}
55
+ if (icount_enabled() && newpriv != env->priv) {
51
56
+ riscv_itrigger_update_priv(env);
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);
57
+ }
60
+ }
58
/* tlb_flush is unnecessary as mode is contained in mmu_idx */
61
+#endif
59
env->priv = newpriv;
62
+
60
env->xl = cpu_recompute_xl(env);
63
qemu_init_vcpu(cs);
64
cpu_reset(cs);
65
61
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
66
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
62
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
63
--- a/target/riscv/debug.c
68
--- a/target/riscv/debug.c
64
+++ b/target/riscv/debug.c
69
+++ b/target/riscv/debug.c
65
@@ -XXX,XX +XXX,XX @@
70
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
66
#include "trace.h"
71
return false;
67
#include "exec/exec-all.h"
68
#include "exec/helper-proto.h"
69
+#include "sysemu/cpu-timers.h"
70
71
/*
72
* The following M-mode trigger CSRs are implemented:
73
@@ -XXX,XX +XXX,XX @@ void helper_itrigger_match(CPURISCVState *env)
74
}
75
}
72
}
76
73
77
+static void riscv_itrigger_update_count(CPURISCVState *env)
74
-void riscv_trigger_init(CPURISCVState *env)
75
+void riscv_trigger_realize(CPURISCVState *env)
78
+{
76
+{
79
+ int count, executed;
77
+ int i;
80
+ /*
81
+ * Record last icount, so that we can evaluate the executed instructions
82
+ * since last priviledge mode change or timer expire.
83
+ */
84
+ int64_t last_icount = env->last_icount, current_icount;
85
+ current_icount = env->last_icount = icount_get_raw();
86
+
78
+
87
+ for (int i = 0; i < RV_MAX_TRIGGERS; i++) {
79
+ for (i = 0; i < RV_MAX_TRIGGERS; i++) {
88
+ if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) {
80
+ env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
89
+ continue;
81
+ riscv_itrigger_timer_cb, env);
90
+ }
91
+ count = itrigger_get_count(env, i);
92
+ if (!count) {
93
+ continue;
94
+ }
95
+ /*
96
+ * Only when priviledge is changed or itrigger timer expires,
97
+ * the count field in itrigger tdata1 register is updated.
98
+ * And the count field in itrigger only contains remaining value.
99
+ */
100
+ if (check_itrigger_priv(env, i)) {
101
+ /*
102
+ * If itrigger enabled in this priviledge mode, the number of
103
+ * executed instructions since last priviledge change
104
+ * should be reduced from current itrigger count.
105
+ */
106
+ executed = current_icount - last_icount;
107
+ itrigger_set_count(env, i, count - executed);
108
+ if (count == executed) {
109
+ do_trigger_action(env, i);
110
+ }
111
+ } else {
112
+ /*
113
+ * If itrigger is not enabled in this priviledge mode,
114
+ * the number of executed instructions will be discard and
115
+ * the count field in itrigger will not change.
116
+ */
117
+ timer_mod(env->itrigger_timer[i],
118
+ current_icount + count);
119
+ }
120
+ }
82
+ }
121
+}
83
+}
122
+
84
+
123
+static void riscv_itrigger_timer_cb(void *opaque)
85
+void riscv_trigger_reset_hold(CPURISCVState *env)
124
+{
125
+ riscv_itrigger_update_count((CPURISCVState *)opaque);
126
+}
127
+
128
+void riscv_itrigger_update_priv(CPURISCVState *env)
129
+{
130
+ riscv_itrigger_update_count(env);
131
+}
132
+
133
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
134
{
86
{
135
switch (tdata_index) {
87
target_ulong tdata1 = build_tdata1(env, TRIGGER_TYPE_AD_MATCH, 0, 0);
88
int i;
136
@@ -XXX,XX +XXX,XX @@ void riscv_trigger_init(CPURISCVState *env)
89
@@ -XXX,XX +XXX,XX @@ void riscv_trigger_init(CPURISCVState *env)
137
env->tdata3[i] = 0;
90
env->tdata3[i] = 0;
138
env->cpu_breakpoint[i] = NULL;
91
env->cpu_breakpoint[i] = NULL;
139
env->cpu_watchpoint[i] = NULL;
92
env->cpu_watchpoint[i] = NULL;
140
+ env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
93
- env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
141
+ riscv_itrigger_timer_cb, env);
94
- riscv_itrigger_timer_cb, env);
95
+ timer_del(env->itrigger_timer[i]);
142
}
96
}
143
}
97
}
144
--
98
--
145
2.38.1
99
2.41.0
100
101
diff view generated by jsdifflib
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
From: Leon Schuermann <leons@opentitan.org>
2
2
3
use the `FIELD32_1CLEAR` macro to implement register
3
When the rule-lock bypass (RLB) bit is set in the mseccfg CSR, the PMP
4
`rw1c` functionality to `ibex_spi`.
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.
5
9
6
This change was tested by running the `SPI_HOST` from TockOS.
10
Signed-off-by: Leon Schuermann <leons@opentitan.org>
7
11
Reviewed-by: Mayuresh Chitale <mchitale@ventanamicro.com>
8
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20221017054950.317584-3-wilfred.mallawa@opensource.wdc.com>
13
Message-ID: <20230829215046.1430463-1-leon@is.currently.online>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
15
---
13
hw/ssi/ibex_spi_host.c | 21 +++++++++------------
16
target/riscv/pmp.c | 4 ++++
14
1 file changed, 9 insertions(+), 12 deletions(-)
17
1 file changed, 4 insertions(+)
15
18
16
diff --git a/hw/ssi/ibex_spi_host.c b/hw/ssi/ibex_spi_host.c
19
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/ssi/ibex_spi_host.c
21
--- a/target/riscv/pmp.c
19
+++ b/hw/ssi/ibex_spi_host.c
22
+++ b/target/riscv/pmp.c
20
@@ -XXX,XX +XXX,XX @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
23
@@ -XXX,XX +XXX,XX @@ static inline uint8_t pmp_get_a_field(uint8_t cfg)
24
*/
25
static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
21
{
26
{
22
IbexSPIHostState *s = opaque;
27
+ /* mseccfg.RLB is set */
23
uint32_t val32 = val64;
28
+ if (MSECCFG_RLB_ISSET(env)) {
24
- uint32_t shift_mask = 0xff, status = 0, data = 0;
29
+ return 0;
25
+ uint32_t shift_mask = 0xff, status = 0;
30
+ }
26
uint8_t txqd_len;
31
27
32
if (env->pmp_state.pmp[pmp_index].cfg_reg & PMP_LOCK) {
28
trace_ibex_spi_host_write(addr, size, val64);
33
return 1;
29
@@ -XXX,XX +XXX,XX @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
30
case IBEX_SPI_HOST_INTR_STATE:
31
/* rw1c status register */
32
if (FIELD_EX32(val32, INTR_STATE, ERROR)) {
33
- data = FIELD_DP32(data, INTR_STATE, ERROR, 0);
34
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], INTR_STATE, ERROR);
35
}
36
if (FIELD_EX32(val32, INTR_STATE, SPI_EVENT)) {
37
- data = FIELD_DP32(data, INTR_STATE, SPI_EVENT, 0);
38
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], INTR_STATE, SPI_EVENT);
39
}
40
- s->regs[addr] = data;
41
break;
42
case IBEX_SPI_HOST_INTR_ENABLE:
43
s->regs[addr] = val32;
44
@@ -XXX,XX +XXX,XX @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
45
* When an error occurs, the corresponding bit must be cleared
46
* here before issuing any further commands
47
*/
48
- status = s->regs[addr];
49
/* rw1c status register */
50
if (FIELD_EX32(val32, ERROR_STATUS, CMDBUSY)) {
51
- status = FIELD_DP32(status, ERROR_STATUS, CMDBUSY, 0);
52
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, CMDBUSY);
53
}
54
if (FIELD_EX32(val32, ERROR_STATUS, OVERFLOW)) {
55
- status = FIELD_DP32(status, ERROR_STATUS, OVERFLOW, 0);
56
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, OVERFLOW);
57
}
58
if (FIELD_EX32(val32, ERROR_STATUS, UNDERFLOW)) {
59
- status = FIELD_DP32(status, ERROR_STATUS, UNDERFLOW, 0);
60
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, UNDERFLOW);
61
}
62
if (FIELD_EX32(val32, ERROR_STATUS, CMDINVAL)) {
63
- status = FIELD_DP32(status, ERROR_STATUS, CMDINVAL, 0);
64
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, CMDINVAL);
65
}
66
if (FIELD_EX32(val32, ERROR_STATUS, CSIDINVAL)) {
67
- status = FIELD_DP32(status, ERROR_STATUS, CSIDINVAL, 0);
68
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, CSIDINVAL);
69
}
70
if (FIELD_EX32(val32, ERROR_STATUS, ACCESSINVAL)) {
71
- status = FIELD_DP32(status, ERROR_STATUS, ACCESSINVAL, 0);
72
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, ACCESSINVAL);
73
}
74
- s->regs[addr] = status;
75
break;
76
case IBEX_SPI_HOST_EVENT_ENABLE:
77
/* Controls which classes of SPI events raise an interrupt. */
78
--
34
--
79
2.38.1
35
2.41.0
diff view generated by jsdifflib
1
From: Anup Patel <apatel@ventanamicro.com>
1
From: Tommy Wu <tommy.wu@sifive.com>
2
2
3
We should use "&&" instead of "&" when checking hcounteren.TM and
3
According to the new spec, when vsiselect has a reserved value, attempts
4
henvcfg.STCE bits.
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
Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp suppor")
7
Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
7
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20230816061647.600672-1-tommy.wu@sifive.com>
9
Message-Id: <20221108125703.1463577-2-apatel@ventanamicro.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
11
---
12
target/riscv/csr.c | 2 +-
12
target/riscv/csr.c | 7 +++++--
13
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 5 insertions(+), 2 deletions(-)
14
14
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/csr.c
17
--- a/target/riscv/csr.c
18
+++ b/target/riscv/csr.c
18
+++ b/target/riscv/csr.c
19
@@ -XXX,XX +XXX,XX @@ static RISCVException sstc(CPURISCVState *env, int csrno)
19
@@ -XXX,XX +XXX,XX @@ static int rmw_iprio(target_ulong xlen,
20
static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
21
target_ulong new_val, target_ulong wr_mask)
22
{
23
- bool virt;
24
+ bool virt, isel_reserved;
25
uint8_t *iprio;
26
int ret = -EINVAL;
27
target_ulong priv, isel, vgein;
28
@@ -XXX,XX +XXX,XX @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
29
30
/* Decode register details from CSR number */
31
virt = false;
32
+ isel_reserved = false;
33
switch (csrno) {
34
case CSR_MIREG:
35
iprio = env->miprio;
36
@@ -XXX,XX +XXX,XX @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
37
riscv_cpu_mxl_bits(env)),
38
val, new_val, wr_mask);
39
}
40
+ } else {
41
+ isel_reserved = true;
20
}
42
}
21
43
22
if (riscv_cpu_virt_enabled(env)) {
44
done:
23
- if (!(get_field(env->hcounteren, COUNTEREN_TM) &
45
if (ret) {
24
+ if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
46
- return (env->virt_enabled && virt) ?
25
get_field(env->henvcfg, HENVCFG_STCE))) {
47
+ return (env->virt_enabled && virt && !isel_reserved) ?
26
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
48
RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
27
}
49
}
50
return RISCV_EXCP_NONE;
28
--
51
--
29
2.38.1
52
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Nikita Shubin <n.shubin@yadro.com>
2
2
3
There are 2 paths in helper_sret() and the same mstatus update codes
3
As per ISA:
4
are replicated. Extract the common parts to simplify it a little bit.
5
4
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
5
"For CSRRWI, if rd=x0, then the instruction shall not read the CSR and
6
shall not cause any of the side effects that might occur on a CSR read."
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>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20221207090037.281452-1-bmeng@tinylab.org>
13
Message-ID: <20230808090914.17634-1-nikita.shubin@maquefel.me>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
15
---
11
target/riscv/op_helper.c | 20 ++++++--------------
16
target/riscv/csr.c | 24 +++++++++++++++---------
12
1 file changed, 6 insertions(+), 14 deletions(-)
17
1 file changed, 15 insertions(+), 9 deletions(-)
13
18
14
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
19
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/op_helper.c
21
--- a/target/riscv/csr.c
17
+++ b/target/riscv/op_helper.c
22
+++ b/target/riscv/csr.c
18
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env)
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);
19
}
33
}
20
34
21
mstatus = env->mstatus;
35
- /* if no accessor exists then return failure */
22
+ prev_priv = get_field(mstatus, MSTATUS_SPP);
36
- if (!csr_ops[csrno].read) {
23
+ mstatus = set_field(mstatus, MSTATUS_SIE,
37
- return RISCV_EXCP_ILLEGAL_INST;
24
+ get_field(mstatus, MSTATUS_SPIE));
38
- }
25
+ mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
39
- /* read old value */
26
+ mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
40
- ret = csr_ops[csrno].read(env, csrno, &old_value);
27
+ env->mstatus = mstatus;
41
- if (ret != RISCV_EXCP_NONE) {
28
42
- return ret;
29
if (riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
43
+ /*
30
/* We support Hypervisor extensions and virtulisation is disabled */
44
+ * ret_value == NULL means that rd=x0 and we're coming from helper_csrw()
31
target_ulong hstatus = env->hstatus;
45
+ * and we can't throw side effects caused by CSR reads.
32
46
+ */
33
- prev_priv = get_field(mstatus, MSTATUS_SPP);
47
+ if (ret_value) {
34
prev_virt = get_field(hstatus, HSTATUS_SPV);
48
+ /* if no accessor exists then return failure */
35
49
+ if (!csr_ops[csrno].read) {
36
hstatus = set_field(hstatus, HSTATUS_SPV, 0);
50
+ return RISCV_EXCP_ILLEGAL_INST;
37
- mstatus = set_field(mstatus, MSTATUS_SPP, 0);
51
+ }
38
- mstatus = set_field(mstatus, SSTATUS_SIE,
52
+ /* read old value */
39
- get_field(mstatus, SSTATUS_SPIE));
53
+ ret = csr_ops[csrno].read(env, csrno, &old_value);
40
- mstatus = set_field(mstatus, SSTATUS_SPIE, 1);
54
+ if (ret != RISCV_EXCP_NONE) {
41
55
+ return ret;
42
- env->mstatus = mstatus;
56
+ }
43
env->hstatus = hstatus;
44
45
if (prev_virt) {
46
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env)
47
}
48
49
riscv_cpu_set_virt_enabled(env, prev_virt);
50
- } else {
51
- prev_priv = get_field(mstatus, MSTATUS_SPP);
52
-
53
- mstatus = set_field(mstatus, MSTATUS_SIE,
54
- get_field(mstatus, MSTATUS_SPIE));
55
- mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
56
- mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
57
- env->mstatus = mstatus;
58
}
57
}
59
58
60
riscv_cpu_set_mode(env, prev_priv);
59
/* write value if writable and write mask set, otherwise drop writes */
61
--
60
--
62
2.38.1
61
2.41.0
diff view generated by jsdifflib