1
The following changes since commit 4d285821c5055ed68a6f6b7693fd11a06a1aa426:
1
The following changes since commit c5ea91da443b458352c1b629b490ee6631775cb4:
2
2
3
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20200618' into staging (2020-06-19 11:44:03 +0100)
3
Merge tag 'pull-trivial-patches' of https://gitlab.com/mjt0k/qemu into staging (2023-09-08 10:06:25 -0400)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20200619-3
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20230911
8
8
9
for you to fetch changes up to 3eaea6eb4e534f7b87c6eca808149bb671976800:
9
for you to fetch changes up to e7a03409f29e2da59297d55afbaec98c96e43e3a:
10
10
11
hw/riscv: sifive_u: Add a dummy DDR memory controller device (2020-06-19 08:25:27 -0700)
11
target/riscv: don't read CSR in riscv_csrrw_do64 (2023-09-11 11:45:55 +1000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
This is a range of patches for RISC-V.
14
First RISC-V PR for 8.2
15
15
16
Some key points are:
16
* Remove 'host' CPU from TCG
17
- Generalise the CPU init functions
17
* riscv_htif Fixup printing on big endian hosts
18
- Support the SiFive revB machine
18
* Add zmmul isa string
19
- Improvements to the Hypervisor implementation and error checking
19
* Add smepmp isa string
20
- Connect some OpenTitan devices
20
* Fix page_check_range use in fault-only-first
21
- Changes to the sifive_u machine to support U-boot
21
* Use existing lookup tables for MixColumns
22
22
* Add RISC-V vector cryptographic instruction set support
23
v2:
23
* Implement WARL behaviour for mcountinhibit/mcounteren
24
- Fix missing realise assert
24
* Add Zihintntl extension ISA string to DTS
25
* Fix zfa fleq.d and fltq.d
26
* Fix upper/lower mtime write calculation
27
* Make rtc variable names consistent
28
* Use abi type for linux-user target_ucontext
29
* Add RISC-V KVM AIA Support
30
* Fix riscv,pmu DT node path in the virt machine
31
* Update CSR bits name for svadu extension
32
* Mark zicond non-experimental
33
* Fix satp_mode_finalize() when satp_mode.supported = 0
34
* Fix non-KVM --enable-debug build
35
* Add new extensions to hwprobe
36
* Use accelerated helper for AES64KS1I
37
* Allocate itrigger timers only once
38
* Respect mseccfg.RLB for pmpaddrX changes
39
* Align the AIA model to v1.0 ratified spec
40
* Don't read the CSR in riscv_csrrw_do64
25
41
26
----------------------------------------------------------------
42
----------------------------------------------------------------
27
Alistair Francis (11):
43
Akihiko Odaki (1):
28
sifive_e: Support the revB machine
44
target/riscv: Allocate itrigger timers only once
29
target/riscv: Set access as data_load when validating stage-2 PTEs
30
target/riscv: Report errors validating 2nd-stage PTEs
31
target/riscv: Move the hfence instructions to the rvh decode
32
target/riscv: Implement checks for hfence
33
riscv/opentitan: Fix the ROM size
34
hw/char: Initial commit of Ibex UART
35
hw/intc: Initial commit of lowRISC Ibex PLIC
36
riscv/opentitan: Connect the PLIC device
37
riscv/opentitan: Connect the UART device
38
target/riscv: Use a smaller guess size for no-MMU PMP
39
45
40
Bin Meng (20):
46
Ard Biesheuvel (2):
41
riscv: Generalize CPU init routine for the base CPU
47
target/riscv: Use existing lookup tables for MixColumns
42
riscv: Generalize CPU init routine for the gcsu CPU
48
target/riscv: Use accelerated helper for AES64KS1I
43
riscv: Generalize CPU init routine for the imacu CPU
44
riscv: Keep the CPU init routine names consistent
45
hw/riscv: sifive_e: Remove the riscv_ prefix of the machine* and soc* functions
46
hw/riscv: opentitan: Remove the riscv_ prefix of the machine* and soc* functions
47
hw/riscv: sifive_u: Simplify the GEM IRQ connect code a little bit
48
hw/riscv: sifive_u: Generate device tree node for OTP
49
hw/riscv: sifive_gpio: Clean up the codes
50
hw/riscv: sifive_gpio: Add a new 'ngpio' property
51
hw/riscv: sifive_u: Hook a GPIO controller
52
hw/riscv: sifive_gpio: Do not blindly trigger output IRQs
53
hw/riscv: sifive_u: Add reset functionality
54
hw/riscv: sifive_u: Rename serial property get/set functions to a generic name
55
hw/riscv: sifive_u: Add a new property msel for MSEL pin state
56
target/riscv: Rename IBEX CPU init routine
57
hw/riscv: sifive: Change SiFive E/U CPU reset vector to 0x1004
58
hw/riscv: sifive_u: Support different boot source per MSEL pin state
59
hw/riscv: sifive_u: Sort the SoC memmap table entries
60
hw/riscv: sifive_u: Add a dummy DDR memory controller device
61
49
62
Ian Jiang (1):
50
Conor Dooley (1):
63
riscv: Add helper to make NaN-boxing for FP register
51
hw/riscv: virt: Fix riscv,pmu DT node path
64
52
65
include/hw/char/ibex_uart.h | 110 ++++++
53
Daniel Henrique Barboza (6):
66
include/hw/intc/ibex_plic.h | 63 ++++
54
target/riscv/cpu.c: do not run 'host' CPU with TCG
67
include/hw/riscv/opentitan.h | 16 +
55
target/riscv/cpu.c: add zmmul isa string
68
include/hw/riscv/sifive_e.h | 1 +
56
target/riscv/cpu.c: add smepmp isa string
69
include/hw/riscv/sifive_gpio.h | 8 +-
57
target/riscv: fix satp_mode_finalize() when satp_mode.supported = 0
70
include/hw/riscv/sifive_u.h | 27 ++
58
hw/riscv/virt.c: fix non-KVM --enable-debug build
71
target/riscv/helper.h | 5 +
59
hw/intc/riscv_aplic.c fix non-KVM --enable-debug build
72
target/riscv/insn32.decode | 8 +-
73
hw/char/ibex_uart.c | 492 +++++++++++++++++++++++++
74
hw/intc/ibex_plic.c | 261 +++++++++++++
75
hw/riscv/opentitan.c | 71 +++-
76
hw/riscv/sifive_e.c | 60 ++-
77
hw/riscv/sifive_gpio.c | 45 ++-
78
hw/riscv/sifive_u.c | 157 ++++++--
79
target/riscv/cpu.c | 69 ++--
80
target/riscv/cpu_helper.c | 9 +-
81
target/riscv/insn_trans/trans_privileged.inc.c | 38 --
82
target/riscv/insn_trans/trans_rvf.inc.c | 17 +-
83
target/riscv/insn_trans/trans_rvh.inc.c | 37 ++
84
target/riscv/op_helper.c | 13 +
85
target/riscv/pmp.c | 14 +-
86
target/riscv/translate.c | 1 +
87
MAINTAINERS | 4 +
88
hw/char/Makefile.objs | 1 +
89
hw/intc/Makefile.objs | 1 +
90
hw/riscv/Kconfig | 4 +
91
26 files changed, 1350 insertions(+), 182 deletions(-)
92
create mode 100644 include/hw/char/ibex_uart.h
93
create mode 100644 include/hw/intc/ibex_plic.h
94
create mode 100644 hw/char/ibex_uart.c
95
create mode 100644 hw/intc/ibex_plic.c
96
create mode 100644 target/riscv/insn_trans/trans_rvh.inc.c
97
60
61
Dickon Hood (2):
62
target/riscv: Refactor translation of vector-widening instruction
63
target/riscv: Add Zvbb ISA extension support
64
65
Jason Chien (3):
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
69
70
Kiran Ostrolenk (4):
71
target/riscv: Refactor some of the generic vector functionality
72
target/riscv: Refactor vector-vector translation macro
73
target/riscv: Refactor some of the generic vector functionality
74
target/riscv: Add Zvknh ISA extension support
75
76
LIU Zhiwei (3):
77
target/riscv: Fix page_check_range use in fault-only-first
78
target/riscv: Fix zfa fleq.d and fltq.d
79
linux-user/riscv: Use abi type for target_ucontext
80
81
Lawrence Hunter (2):
82
target/riscv: Add Zvbc ISA extension support
83
target/riscv: Add Zvksh ISA extension support
84
85
Leon Schuermann (1):
86
target/riscv/pmp.c: respect mseccfg.RLB for pmpaddrX changes
87
88
Max Chou (3):
89
crypto: Create sm4_subword
90
crypto: Add SM4 constant parameter CK
91
target/riscv: Add Zvksed ISA extension support
92
93
Nazar Kazakov (4):
94
target/riscv: Remove redundant "cpu_vl == 0" checks
95
target/riscv: Move vector translation checks
96
target/riscv: Add Zvkned ISA extension support
97
target/riscv: Add Zvkg ISA extension support
98
99
Nikita Shubin (1):
100
target/riscv: don't read CSR in riscv_csrrw_do64
101
102
Rob Bradford (1):
103
target/riscv: Implement WARL behaviour for mcountinhibit/mcounteren
104
105
Robbin Ehn (1):
106
linux-user/riscv: Add new extensions to hwprobe
107
108
Thomas Huth (2):
109
hw/char/riscv_htif: Fix printing of console characters on big endian hosts
110
hw/char/riscv_htif: Fix the console syscall on big endian hosts
111
112
Tommy Wu (1):
113
target/riscv: Align the AIA model to v1.0 ratified spec
114
115
Vineet Gupta (1):
116
riscv: zicond: make non-experimental
117
118
Weiwei Li (1):
119
target/riscv: Update CSR bits name for svadu extension
120
121
Yong-Xuan Wang (5):
122
target/riscv: support the AIA device emulation with KVM enabled
123
target/riscv: check the in-kernel irqchip support
124
target/riscv: Create an KVM AIA irqchip
125
target/riscv: update APLIC and IMSIC to support KVM AIA
126
target/riscv: select KVM AIA in riscv virt machine
127
128
include/crypto/aes.h | 7 +
129
include/crypto/sm4.h | 9 +
130
target/riscv/cpu_bits.h | 8 +-
131
target/riscv/cpu_cfg.h | 9 +
132
target/riscv/debug.h | 3 +-
133
target/riscv/helper.h | 98 +++
134
target/riscv/kvm_riscv.h | 5 +
135
target/riscv/vector_internals.h | 228 +++++++
136
target/riscv/insn32.decode | 58 ++
137
crypto/aes.c | 4 +-
138
crypto/sm4.c | 10 +
139
hw/char/riscv_htif.c | 12 +-
140
hw/intc/riscv_aclint.c | 11 +-
141
hw/intc/riscv_aplic.c | 52 +-
142
hw/intc/riscv_imsic.c | 25 +-
143
hw/riscv/virt.c | 374 ++++++------
144
linux-user/riscv/signal.c | 4 +-
145
linux-user/syscall.c | 14 +-
146
target/arm/tcg/crypto_helper.c | 10 +-
147
target/riscv/cpu.c | 83 ++-
148
target/riscv/cpu_helper.c | 6 +-
149
target/riscv/crypto_helper.c | 51 +-
150
target/riscv/csr.c | 54 +-
151
target/riscv/debug.c | 15 +-
152
target/riscv/kvm.c | 201 ++++++-
153
target/riscv/pmp.c | 4 +
154
target/riscv/translate.c | 1 +
155
target/riscv/vcrypto_helper.c | 970 ++++++++++++++++++++++++++++++
156
target/riscv/vector_helper.c | 245 +-------
157
target/riscv/vector_internals.c | 81 +++
158
target/riscv/insn_trans/trans_rvv.c.inc | 171 +++---
159
target/riscv/insn_trans/trans_rvvk.c.inc | 606 +++++++++++++++++++
160
target/riscv/insn_trans/trans_rvzfa.c.inc | 4 +-
161
target/riscv/meson.build | 4 +-
162
34 files changed, 2785 insertions(+), 652 deletions(-)
163
create mode 100644 target/riscv/vector_internals.h
164
create mode 100644 target/riscv/vcrypto_helper.c
165
create mode 100644 target/riscv/vector_internals.c
166
create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Current IBEX CPU init routine name seems to be too generic.
3
The 'host' CPU is available in a CONFIG_KVM build and it's currently
4
Since it uses a different reset vector from the generic one,
4
available for all accels, but is a KVM only CPU. This means that in a
5
it merits a dedicated name.
5
RISC-V KVM capable host we can do things like this:
6
6
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
$ ./build/qemu-system-riscv64 -M virt,accel=tcg -cpu host --nographic
8
qemu-system-riscv64: H extension requires priv spec 1.12.0
9
10
This CPU does not have a priv spec because we don't filter its extensions
11
via priv spec. We shouldn't be reaching riscv_cpu_realize_tcg() at all
12
with the 'host' CPU.
13
14
We don't have a way to filter the 'host' CPU out of the available CPU
15
options (-cpu help) if the build includes both KVM and TCG. What we can
16
do is to error out during riscv_cpu_realize_tcg() if the user chooses
17
the 'host' CPU with accel=tcg:
18
19
$ ./build/qemu-system-riscv64 -M virt,accel=tcg -cpu host --nographic
20
qemu-system-riscv64: 'host' CPU is not compatible with TCG acceleration
21
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 1592268641-7478-2-git-send-email-bmeng.cn@gmail.com
24
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-Id: <1592268641-7478-2-git-send-email-bmeng.cn@gmail.com>
25
Message-Id: <20230721133411.474105-1-dbarboza@ventanamicro.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
26
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
27
---
13
target/riscv/cpu.c | 4 ++--
28
target/riscv/cpu.c | 5 +++++
14
1 file changed, 2 insertions(+), 2 deletions(-)
29
1 file changed, 5 insertions(+)
15
30
16
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
31
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
17
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/cpu.c
33
--- a/target/riscv/cpu.c
19
+++ b/target/riscv/cpu.c
34
+++ b/target/riscv/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static void rvxx_imacu_nommu_cpu_init(Object *obj)
35
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize_tcg(DeviceState *dev, Error **errp)
21
36
CPURISCVState *env = &cpu->env;
22
#if defined(TARGET_RISCV32)
37
Error *local_err = NULL;
23
38
24
-static void rv32_imcu_nommu_cpu_init(Object *obj)
39
+ if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_CPU_HOST)) {
25
+static void rv32_ibex_cpu_init(Object *obj)
40
+ error_setg(errp, "'host' CPU is not compatible with TCG acceleration");
26
{
41
+ return;
27
CPURISCVState *env = &RISCV_CPU(obj)->env;
42
+ }
28
set_misa(env, RV32 | RVI | RVM | RVC | RVU);
43
+
29
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
44
riscv_cpu_validate_misa_mxl(cpu, &local_err);
30
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
45
if (local_err != NULL) {
31
#if defined(TARGET_RISCV32)
46
error_propagate(errp, local_err);
32
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
33
- DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_imcu_nommu_cpu_init),
34
+ DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
35
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_imacu_nommu_cpu_init),
36
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
37
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
38
--
47
--
39
2.27.0
48
2.41.0
40
49
41
50
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
2
3
The character that should be printed is stored in the 64 bit "payload"
4
variable. The code currently tries to print it by taking the address
5
of the variable and passing this pointer to qemu_chr_fe_write(). However,
6
this only works on little endian hosts where the least significant bits
7
are stored on the lowest address. To do this in a portable way, we have
8
to store the value in an uint8_t variable instead.
9
10
Fixes: 5033606780 ("RISC-V HTIF Console")
11
Signed-off-by: Thomas Huth <thuth@redhat.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Bin Meng <bmeng@tinylab.org>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Message-Id: <20230721094720.902454-2-thuth@redhat.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reported-by: Damien Hedde <damien.hedde@greensocs.com>
3
---
18
---
4
hw/riscv/opentitan.c | 3 ++-
19
hw/char/riscv_htif.c | 3 ++-
5
1 file changed, 2 insertions(+), 1 deletion(-)
20
1 file changed, 2 insertions(+), 1 deletion(-)
6
21
7
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
22
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
8
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
9
--- a/hw/riscv/opentitan.c
24
--- a/hw/char/riscv_htif.c
10
+++ b/hw/riscv/opentitan.c
25
+++ b/hw/char/riscv_htif.c
11
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
12
#include "hw/misc/unimp.h"
27
s->tohost = 0; /* clear to indicate we read */
13
#include "hw/riscv/boot.h"
28
return;
14
#include "exec/address-spaces.h"
29
} else if (cmd == HTIF_CONSOLE_CMD_PUTC) {
15
+#include "qemu/units.h"
30
- qemu_chr_fe_write(&s->chr, (uint8_t *)&payload, 1);
16
31
+ uint8_t ch = (uint8_t)payload;
17
static const struct MemmapEntry {
32
+ qemu_chr_fe_write(&s->chr, &ch, 1);
18
hwaddr base;
33
resp = 0x100 | (uint8_t)payload;
19
hwaddr size;
34
} else {
20
} ibex_memmap[] = {
35
qemu_log("HTIF device %d: unknown command\n", device);
21
- [IBEX_ROM] = { 0x00008000, 0xc000 },
22
+ [IBEX_ROM] = { 0x00008000, 16 * KiB },
23
[IBEX_RAM] = { 0x10000000, 0x10000 },
24
[IBEX_FLASH] = { 0x20000000, 0x80000 },
25
[IBEX_UART] = { 0x40000000, 0x10000 },
26
--
36
--
27
2.27.0
37
2.41.0
28
38
29
39
diff view generated by jsdifflib
New patch
1
From: Thomas Huth <thuth@redhat.com>
1
2
3
Values that have been read via cpu_physical_memory_read() from the
4
guest's memory have to be swapped in case the host endianess differs
5
from the guest.
6
7
Fixes: a6e13e31d5 ("riscv_htif: Support console output via proxy syscall")
8
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Bin Meng <bmeng@tinylab.org>
11
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
Message-Id: <20230721094720.902454-3-thuth@redhat.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
hw/char/riscv_htif.c | 9 +++++----
16
1 file changed, 5 insertions(+), 4 deletions(-)
17
18
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/char/riscv_htif.c
21
+++ b/hw/char/riscv_htif.c
22
@@ -XXX,XX +XXX,XX @@
23
#include "qemu/timer.h"
24
#include "qemu/error-report.h"
25
#include "exec/address-spaces.h"
26
+#include "exec/tswap.h"
27
#include "sysemu/dma.h"
28
29
#define RISCV_DEBUG_HTIF 0
30
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
31
} else {
32
uint64_t syscall[8];
33
cpu_physical_memory_read(payload, syscall, sizeof(syscall));
34
- if (syscall[0] == PK_SYS_WRITE &&
35
- syscall[1] == HTIF_DEV_CONSOLE &&
36
- syscall[3] == HTIF_CONSOLE_CMD_PUTC) {
37
+ if (tswap64(syscall[0]) == PK_SYS_WRITE &&
38
+ tswap64(syscall[1]) == HTIF_DEV_CONSOLE &&
39
+ tswap64(syscall[3]) == HTIF_CONSOLE_CMD_PUTC) {
40
uint8_t ch;
41
- cpu_physical_memory_read(syscall[2], &ch, 1);
42
+ cpu_physical_memory_read(tswap64(syscall[2]), &ch, 1);
43
qemu_chr_fe_write(&s->chr, &ch, 1);
44
resp = 0x100 | (uint8_t)payload;
45
} else {
46
--
47
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Adding a _ to keep some consistency among the CPU init routines.
3
zmmul was promoted from experimental to ratified in commit 6d00ffad4e95.
4
Add a riscv,isa string for it.
4
5
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Fixes: 6d00ffad4e95 ("target/riscv: move zmmul out of the experimental properties")
7
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <1591837729-27486-4-git-send-email-bmeng.cn@gmail.com>
10
Message-Id: <20230720132424.371132-2-dbarboza@ventanamicro.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
12
---
10
target/riscv/cpu.c | 8 ++++----
13
target/riscv/cpu.c | 1 +
11
1 file changed, 4 insertions(+), 4 deletions(-)
14
1 file changed, 1 insertion(+)
12
15
13
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
16
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/cpu.c
18
--- a/target/riscv/cpu.c
16
+++ b/target/riscv/cpu.c
19
+++ b/target/riscv/cpu.c
17
@@ -XXX,XX +XXX,XX @@ static void rvxx_imacu_nommu_cpu_init(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
18
21
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
19
#if defined(TARGET_RISCV32)
22
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
20
23
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
21
-static void rv32imcu_nommu_cpu_init(Object *obj)
24
+ ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
22
+static void rv32_imcu_nommu_cpu_init(Object *obj)
25
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
23
{
26
ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa),
24
CPURISCVState *env = &RISCV_CPU(obj)->env;
27
ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin),
25
set_misa(env, RV32 | RVI | RVM | RVC | RVU);
26
@@ -XXX,XX +XXX,XX @@ static void rv32imcu_nommu_cpu_init(Object *obj)
27
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
28
}
29
30
-static void rv32imafcu_nommu_cpu_init(Object *obj)
31
+static void rv32_imafcu_nommu_cpu_init(Object *obj)
32
{
33
CPURISCVState *env = &RISCV_CPU(obj)->env;
34
set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVC | RVU);
35
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
36
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
37
#if defined(TARGET_RISCV32)
38
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
39
- DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
40
+ DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_imcu_nommu_cpu_init),
41
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_imacu_nommu_cpu_init),
42
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
43
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
44
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
45
#elif defined(TARGET_RISCV64)
46
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
47
--
28
--
48
2.27.0
29
2.41.0
49
50
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
There is no need to have two functions that have almost the same
3
The cpu->cfg.epmp extension is still experimental, but it already has a
4
codes for 32-bit and 64-bit imacu CPUs.
4
'smepmp' riscv,isa string. Add it.
5
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <1591837729-27486-3-git-send-email-bmeng.cn@gmail.com>
9
Message-Id: <20230720132424.371132-3-dbarboza@ventanamicro.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
---
11
target/riscv/cpu.c | 31 ++++++++++---------------------
12
target/riscv/cpu.c | 1 +
12
1 file changed, 10 insertions(+), 21 deletions(-)
13
1 file changed, 1 insertion(+)
13
14
14
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
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu.c
17
--- a/target/riscv/cpu.c
17
+++ b/target/riscv/cpu.c
18
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void rvxx_gcsu_priv1_10_0_cpu_init(Object *obj)
19
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
19
set_resetvec(env, DEFAULT_RSTVEC);
20
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
20
}
21
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
21
22
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
22
-#if defined(TARGET_RISCV32)
23
+ ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, epmp),
23
-
24
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
24
-static void rv32imcu_nommu_cpu_init(Object *obj)
25
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
25
+static void rvxx_imacu_nommu_cpu_init(Object *obj)
26
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
26
{
27
CPURISCVState *env = &RISCV_CPU(obj)->env;
28
- set_misa(env, RV32 | RVI | RVM | RVC | RVU);
29
+ set_misa(env, RVXLEN | RVI | RVM | RVA | RVC | RVU);
30
set_priv_version(env, PRIV_VERSION_1_10_0);
31
- set_resetvec(env, 0x8090);
32
+ set_resetvec(env, DEFAULT_RSTVEC);
33
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
34
}
35
36
-static void rv32imacu_nommu_cpu_init(Object *obj)
37
+#if defined(TARGET_RISCV32)
38
+
39
+static void rv32imcu_nommu_cpu_init(Object *obj)
40
{
41
CPURISCVState *env = &RISCV_CPU(obj)->env;
42
- set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
43
+ set_misa(env, RV32 | RVI | RVM | RVC | RVU);
44
set_priv_version(env, PRIV_VERSION_1_10_0);
45
- set_resetvec(env, DEFAULT_RSTVEC);
46
+ set_resetvec(env, 0x8090);
47
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
48
}
49
50
@@ -XXX,XX +XXX,XX @@ static void rv32imafcu_nommu_cpu_init(Object *obj)
51
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
52
}
53
54
-#elif defined(TARGET_RISCV64)
55
-
56
-static void rv64imacu_nommu_cpu_init(Object *obj)
57
-{
58
- CPURISCVState *env = &RISCV_CPU(obj)->env;
59
- set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU);
60
- set_priv_version(env, PRIV_VERSION_1_10_0);
61
- set_resetvec(env, DEFAULT_RSTVEC);
62
- qdev_prop_set_bit(DEVICE(obj), "mmu", false);
63
-}
64
-
65
#endif
66
67
static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
68
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
69
#if defined(TARGET_RISCV32)
70
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
71
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
72
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
73
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_imacu_nommu_cpu_init),
74
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
75
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
76
#elif defined(TARGET_RISCV64)
77
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
78
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init),
79
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rvxx_imacu_nommu_cpu_init),
80
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_gcsu_priv1_10_0_cpu_init),
81
#endif
82
};
83
--
27
--
84
2.27.0
28
2.41.0
85
86
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
2
3
Commit bef6f008b98(accel/tcg: Return bool from page_check_range) converts
4
integer return value to bool type. However, it wrongly converted the use
5
of the API in riscv fault-only-first, where page_check_range < = 0, should
6
be converted to !page_check_range.
7
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-ID: <20230729031618.821-1-zhiwei_liu@linux.alibaba.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/vector_helper.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/vector_helper.c
19
+++ b/target/riscv/vector_helper.c
20
@@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base,
21
cpu_mmu_index(env, false));
22
if (host) {
23
#ifdef CONFIG_USER_ONLY
24
- if (page_check_range(addr, offset, PAGE_READ)) {
25
+ if (!page_check_range(addr, offset, PAGE_READ)) {
26
vl = i;
27
goto ProbeSuccess;
28
}
29
--
30
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Ard Biesheuvel <ardb@kernel.org>
2
2
3
This was done in the virt & sifive_u codes, but sifive_e codes were
3
The AES MixColumns and InvMixColumns operations are relatively
4
missed. Remove the riscv_ prefix of the machine* and soc* functions.
4
expensive 4x4 matrix multiplications in GF(2^8), which is why C
5
implementations usually rely on precomputed lookup tables rather than
6
performing the calculations on demand.
5
7
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Given that we already carry those tables in QEMU, we can just grab the
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
right value in the implementation of the RISC-V AES32 instructions. Note
8
Message-id: 1591625864-31494-2-git-send-email-bmeng.cn@gmail.com
10
that the tables in question are permuted according to the respective
9
Message-Id: <1591625864-31494-2-git-send-email-bmeng.cn@gmail.com>
11
Sbox, so we can omit the Sbox lookup as well in this case.
12
13
Cc: Richard Henderson <richard.henderson@linaro.org>
14
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Cc: Zewen Ye <lustrew@foxmail.com>
16
Cc: Weiwei Li <liweiwei@iscas.ac.cn>
17
Cc: Junqiang Wang <wangjunqiang@iscas.ac.cn>
18
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-ID: <20230731084043.1791984-1-ardb@kernel.org>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
22
---
12
hw/riscv/sifive_e.c | 24 ++++++++++++------------
23
include/crypto/aes.h | 7 +++++++
13
1 file changed, 12 insertions(+), 12 deletions(-)
24
crypto/aes.c | 4 ++--
25
target/riscv/crypto_helper.c | 34 ++++------------------------------
26
3 files changed, 13 insertions(+), 32 deletions(-)
14
27
15
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
28
diff --git a/include/crypto/aes.h b/include/crypto/aes.h
16
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/sifive_e.c
30
--- a/include/crypto/aes.h
18
+++ b/hw/riscv/sifive_e.c
31
+++ b/include/crypto/aes.h
19
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
32
@@ -XXX,XX +XXX,XX @@ void AES_decrypt(const unsigned char *in, unsigned char *out,
20
[SIFIVE_E_DTIM] = { 0x80000000, 0x4000 }
33
extern const uint8_t AES_sbox[256];
34
extern const uint8_t AES_isbox[256];
35
36
+/*
37
+AES_Te0[x] = S [x].[02, 01, 01, 03];
38
+AES_Td0[x] = Si[x].[0e, 09, 0d, 0b];
39
+*/
40
+
41
+extern const uint32_t AES_Te0[256], AES_Td0[256];
42
+
43
#endif
44
diff --git a/crypto/aes.c b/crypto/aes.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/crypto/aes.c
47
+++ b/crypto/aes.c
48
@@ -XXX,XX +XXX,XX @@ AES_Td3[x] = Si[x].[09, 0d, 0b, 0e];
49
AES_Td4[x] = Si[x].[01, 01, 01, 01];
50
*/
51
52
-static const uint32_t AES_Te0[256] = {
53
+const uint32_t AES_Te0[256] = {
54
0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
55
0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
56
0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
57
@@ -XXX,XX +XXX,XX @@ static const uint32_t AES_Te4[256] = {
58
0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
21
};
59
};
22
60
23
-static void riscv_sifive_e_init(MachineState *machine)
61
-static const uint32_t AES_Td0[256] = {
24
+static void sifive_e_machine_init(MachineState *machine)
62
+const uint32_t AES_Td0[256] = {
63
0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
64
0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
65
0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
66
diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/crypto_helper.c
69
+++ b/target/riscv/crypto_helper.c
70
@@ -XXX,XX +XXX,XX @@
71
#include "crypto/aes-round.h"
72
#include "crypto/sm4.h"
73
74
-#define AES_XTIME(a) \
75
- ((a << 1) ^ ((a & 0x80) ? 0x1b : 0))
76
-
77
-#define AES_GFMUL(a, b) (( \
78
- (((b) & 0x1) ? (a) : 0) ^ \
79
- (((b) & 0x2) ? AES_XTIME(a) : 0) ^ \
80
- (((b) & 0x4) ? AES_XTIME(AES_XTIME(a)) : 0) ^ \
81
- (((b) & 0x8) ? AES_XTIME(AES_XTIME(AES_XTIME(a))) : 0)) & 0xFF)
82
-
83
-static inline uint32_t aes_mixcolumn_byte(uint8_t x, bool fwd)
84
-{
85
- uint32_t u;
86
-
87
- if (fwd) {
88
- u = (AES_GFMUL(x, 3) << 24) | (x << 16) | (x << 8) |
89
- (AES_GFMUL(x, 2) << 0);
90
- } else {
91
- u = (AES_GFMUL(x, 0xb) << 24) | (AES_GFMUL(x, 0xd) << 16) |
92
- (AES_GFMUL(x, 0x9) << 8) | (AES_GFMUL(x, 0xe) << 0);
93
- }
94
- return u;
95
-}
96
-
97
#define sext32_xlen(x) (target_ulong)(int32_t)(x)
98
99
static inline target_ulong aes32_operation(target_ulong shamt,
100
@@ -XXX,XX +XXX,XX @@ static inline target_ulong aes32_operation(target_ulong shamt,
101
bool enc, bool mix)
25
{
102
{
26
const struct MemmapEntry *memmap = sifive_e_memmap;
103
uint8_t si = rs2 >> shamt;
27
104
- uint8_t so;
28
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_class_init(ObjectClass *oc, void *data)
105
uint32_t mixed;
29
MachineClass *mc = MACHINE_CLASS(oc);
106
target_ulong res;
30
107
31
mc->desc = "RISC-V Board compatible with SiFive E SDK";
108
if (enc) {
32
- mc->init = riscv_sifive_e_init;
109
- so = AES_sbox[si];
33
+ mc->init = sifive_e_machine_init;
110
if (mix) {
34
mc->max_cpus = 1;
111
- mixed = aes_mixcolumn_byte(so, true);
35
mc->default_cpu_type = SIFIVE_E_CPU;
112
+ mixed = be32_to_cpu(AES_Te0[si]);
36
}
113
} else {
37
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_init_register_types(void)
114
- mixed = so;
38
115
+ mixed = AES_sbox[si];
39
type_init(sifive_e_machine_init_register_types)
116
}
40
117
} else {
41
-static void riscv_sifive_e_soc_init(Object *obj)
118
- so = AES_isbox[si];
42
+static void sifive_e_soc_init(Object *obj)
119
if (mix) {
43
{
120
- mixed = aes_mixcolumn_byte(so, false);
44
MachineState *ms = MACHINE(qdev_get_machine());
121
+ mixed = be32_to_cpu(AES_Td0[si]);
45
SiFiveESoCState *s = RISCV_E_SOC(obj);
122
} else {
46
@@ -XXX,XX +XXX,XX @@ static void riscv_sifive_e_soc_init(Object *obj)
123
- mixed = so;
47
TYPE_SIFIVE_GPIO);
124
+ mixed = AES_isbox[si];
48
}
125
}
49
126
}
50
-static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp)
127
mixed = rol32(mixed, shamt);
51
+static void sifive_e_soc_realize(DeviceState *dev, Error **errp)
52
{
53
MachineState *ms = MACHINE(qdev_get_machine());
54
const struct MemmapEntry *memmap = sifive_e_memmap;
55
@@ -XXX,XX +XXX,XX @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp)
56
&s->xip_mem);
57
}
58
59
-static void riscv_sifive_e_soc_class_init(ObjectClass *oc, void *data)
60
+static void sifive_e_soc_class_init(ObjectClass *oc, void *data)
61
{
62
DeviceClass *dc = DEVICE_CLASS(oc);
63
64
- dc->realize = riscv_sifive_e_soc_realize;
65
+ dc->realize = sifive_e_soc_realize;
66
/* Reason: Uses serial_hds in realize function, thus can't be used twice */
67
dc->user_creatable = false;
68
}
69
70
-static const TypeInfo riscv_sifive_e_soc_type_info = {
71
+static const TypeInfo sifive_e_soc_type_info = {
72
.name = TYPE_RISCV_E_SOC,
73
.parent = TYPE_DEVICE,
74
.instance_size = sizeof(SiFiveESoCState),
75
- .instance_init = riscv_sifive_e_soc_init,
76
- .class_init = riscv_sifive_e_soc_class_init,
77
+ .instance_init = sifive_e_soc_init,
78
+ .class_init = sifive_e_soc_class_init,
79
};
80
81
-static void riscv_sifive_e_soc_register_types(void)
82
+static void sifive_e_soc_register_types(void)
83
{
84
- type_register_static(&riscv_sifive_e_soc_type_info);
85
+ type_register_static(&sifive_e_soc_type_info);
86
}
87
88
-type_init(riscv_sifive_e_soc_register_types)
89
+type_init(sifive_e_soc_register_types)
90
--
128
--
91
2.27.0
129
2.41.0
92
130
93
131
diff view generated by jsdifflib
1
The Ibex core contains a PLIC that although similar to the RISC-V spec
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
2
is not RISC-V spec compliant.
3
2
4
This patch implements a Ibex PLIC in a somewhat generic way.
3
Take some functions/macros out of `vector_helper` and put them in a new
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
As the current RISC-V PLIC needs tidying up, my hope is that as the Ibex
8
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
7
PLIC move towards spec compliance this PLIC implementation can be
9
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
8
updated until it can replace the current PLIC.
10
Signed-off-by: Max Chou <max.chou@sifive.com>
11
Acked-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-ID: <20230711165917.2629866-2-max.chou@sifive.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/vector_internals.h | 182 +++++++++++++++++++++++++++++
16
target/riscv/vector_helper.c | 201 +-------------------------------
17
target/riscv/vector_internals.c | 81 +++++++++++++
18
target/riscv/meson.build | 1 +
19
4 files changed, 265 insertions(+), 200 deletions(-)
20
create mode 100644 target/riscv/vector_internals.h
21
create mode 100644 target/riscv/vector_internals.c
9
22
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
---
13
include/hw/intc/ibex_plic.h | 63 +++++++++
14
hw/intc/ibex_plic.c | 261 ++++++++++++++++++++++++++++++++++++
15
MAINTAINERS | 2 +
16
hw/intc/Makefile.objs | 1 +
17
4 files changed, 327 insertions(+)
18
create mode 100644 include/hw/intc/ibex_plic.h
19
create mode 100644 hw/intc/ibex_plic.c
20
21
diff --git a/include/hw/intc/ibex_plic.h b/include/hw/intc/ibex_plic.h
22
new file mode 100644
24
new file mode 100644
23
index XXXXXXX..XXXXXXX
25
index XXXXXXX..XXXXXXX
24
--- /dev/null
26
--- /dev/null
25
+++ b/include/hw/intc/ibex_plic.h
27
+++ b/target/riscv/vector_internals.h
26
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
27
+/*
29
+/*
28
+ * QEMU RISC-V lowRISC Ibex PLIC
30
+ * RISC-V Vector Extension Internals
29
+ *
31
+ *
30
+ * Copyright (c) 2020 Western Digital
32
+ * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
31
+ *
33
+ *
32
+ * This program is free software; you can redistribute it and/or modify it
34
+ * This program is free software; you can redistribute it and/or modify it
33
+ * under the terms and conditions of the GNU General Public License,
35
+ * under the terms and conditions of the GNU General Public License,
34
+ * version 2 or later, as published by the Free Software Foundation.
36
+ * version 2 or later, as published by the Free Software Foundation.
35
+ *
37
+ *
...
...
40
+ *
42
+ *
41
+ * You should have received a copy of the GNU General Public License along with
43
+ * You should have received a copy of the GNU General Public License along with
42
+ * this program. If not, see <http://www.gnu.org/licenses/>.
44
+ * this program. If not, see <http://www.gnu.org/licenses/>.
43
+ */
45
+ */
44
+
46
+
45
+#ifndef HW_IBEX_PLIC_H
47
+#ifndef TARGET_RISCV_VECTOR_INTERNALS_H
46
+#define HW_IBEX_PLIC_H
48
+#define TARGET_RISCV_VECTOR_INTERNALS_H
47
+
49
+
48
+#include "hw/sysbus.h"
50
+#include "qemu/osdep.h"
49
+
51
+#include "qemu/bitops.h"
50
+#define TYPE_IBEX_PLIC "ibex-plic"
52
+#include "cpu.h"
51
+#define IBEX_PLIC(obj) \
53
+#include "tcg/tcg-gvec-desc.h"
52
+ OBJECT_CHECK(IbexPlicState, (obj), TYPE_IBEX_PLIC)
54
+#include "internals.h"
53
+
55
+
54
+typedef struct IbexPlicState {
56
+static inline uint32_t vext_nf(uint32_t desc)
55
+ /*< private >*/
57
+{
56
+ SysBusDevice parent_obj;
58
+ return FIELD_EX32(simd_data(desc), VDATA, NF);
57
+
59
+}
58
+ /*< public >*/
60
+
59
+ MemoryRegion mmio;
61
+/*
60
+
62
+ * Note that vector data is stored in host-endian 64-bit chunks,
61
+ uint32_t *pending;
63
+ * so addressing units smaller than that needs a host-endian fixup.
62
+ uint32_t *source;
64
+ */
63
+ uint32_t *priority;
65
+#if HOST_BIG_ENDIAN
64
+ uint32_t *enable;
66
+#define H1(x) ((x) ^ 7)
65
+ uint32_t threshold;
67
+#define H1_2(x) ((x) ^ 6)
66
+ uint32_t claim;
68
+#define H1_4(x) ((x) ^ 4)
67
+
69
+#define H2(x) ((x) ^ 3)
68
+ /* config */
70
+#define H4(x) ((x) ^ 1)
69
+ uint32_t num_cpus;
71
+#define H8(x) ((x))
70
+ uint32_t num_sources;
72
+#else
71
+
73
+#define H1(x) (x)
72
+ uint32_t pending_base;
74
+#define H1_2(x) (x)
73
+ uint32_t pending_num;
75
+#define H1_4(x) (x)
74
+
76
+#define H2(x) (x)
75
+ uint32_t source_base;
77
+#define H4(x) (x)
76
+ uint32_t source_num;
78
+#define H8(x) (x)
77
+
79
+#endif
78
+ uint32_t priority_base;
80
+
79
+ uint32_t priority_num;
81
+/*
80
+
82
+ * Encode LMUL to lmul as following:
81
+ uint32_t enable_base;
83
+ * LMUL vlmul lmul
82
+ uint32_t enable_num;
84
+ * 1 000 0
83
+
85
+ * 2 001 1
84
+ uint32_t threshold_base;
86
+ * 4 010 2
85
+
87
+ * 8 011 3
86
+ uint32_t claim_base;
88
+ * - 100 -
87
+} IbexPlicState;
89
+ * 1/8 101 -3
88
+
90
+ * 1/4 110 -2
89
+#endif /* HW_IBEX_PLIC_H */
91
+ * 1/2 111 -1
90
diff --git a/hw/intc/ibex_plic.c b/hw/intc/ibex_plic.c
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
91
new file mode 100644
492
new file mode 100644
92
index XXXXXXX..XXXXXXX
493
index XXXXXXX..XXXXXXX
93
--- /dev/null
494
--- /dev/null
94
+++ b/hw/intc/ibex_plic.c
495
+++ b/target/riscv/vector_internals.c
95
@@ -XXX,XX +XXX,XX @@
496
@@ -XXX,XX +XXX,XX @@
96
+/*
497
+/*
97
+ * QEMU RISC-V lowRISC Ibex PLIC
498
+ * RISC-V Vector Extension Internals
98
+ *
499
+ *
99
+ * Copyright (c) 2020 Western Digital
500
+ * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
100
+ *
101
+ * Documentation avaliable: https://docs.opentitan.org/hw/ip/rv_plic/doc/
102
+ *
501
+ *
103
+ * This program is free software; you can redistribute it and/or modify it
502
+ * This program is free software; you can redistribute it and/or modify it
104
+ * under the terms and conditions of the GNU General Public License,
503
+ * under the terms and conditions of the GNU General Public License,
105
+ * version 2 or later, as published by the Free Software Foundation.
504
+ * version 2 or later, as published by the Free Software Foundation.
106
+ *
505
+ *
...
...
111
+ *
510
+ *
112
+ * You should have received a copy of the GNU General Public License along with
511
+ * You should have received a copy of the GNU General Public License along with
113
+ * this program. If not, see <http://www.gnu.org/licenses/>.
512
+ * this program. If not, see <http://www.gnu.org/licenses/>.
114
+ */
513
+ */
115
+
514
+
116
+#include "qemu/osdep.h"
515
+#include "vector_internals.h"
117
+#include "qemu/log.h"
516
+
118
+#include "hw/qdev-properties.h"
517
+/* set agnostic elements to 1s */
119
+#include "hw/core/cpu.h"
518
+void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
120
+#include "hw/boards.h"
519
+ uint32_t tot)
121
+#include "hw/pci/msi.h"
520
+{
122
+#include "target/riscv/cpu_bits.h"
521
+ if (is_agnostic == 0) {
123
+#include "target/riscv/cpu.h"
522
+ /* policy undisturbed */
124
+#include "hw/intc/ibex_plic.h"
523
+ return;
125
+
126
+static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
127
+{
128
+ uint32_t end = base + (num * 0x04);
129
+
130
+ if (addr >= base && addr < end) {
131
+ return true;
132
+ }
524
+ }
133
+
525
+ if (tot - cnt == 0) {
134
+ return false;
526
+ return ;
135
+}
527
+ }
136
+
528
+ memset(base + cnt, -1, tot - cnt);
137
+static void ibex_plic_irqs_set_pending(IbexPlicState *s, int irq, bool level)
529
+}
138
+{
530
+
139
+ int pending_num = irq / 32;
531
+void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
140
+
532
+ CPURISCVState *env, uint32_t desc,
141
+ s->pending[pending_num] |= level << (irq % 32);
533
+ opivv2_fn *fn, uint32_t esz)
142
+}
534
+{
143
+
535
+ uint32_t vm = vext_vm(desc);
144
+static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context)
536
+ uint32_t vl = env->vl;
145
+{
537
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
146
+ int i;
538
+ uint32_t vta = vext_vta(desc);
147
+
539
+ uint32_t vma = vext_vma(desc);
148
+ for (i = 0; i < s->pending_num; i++) {
540
+ uint32_t i;
149
+ uint32_t irq_num = ctz64(s->pending[i]) + (i * 32);
541
+
150
+
542
+ for (i = env->vstart; i < vl; i++) {
151
+ if (!(s->pending[i] & s->enable[i])) {
543
+ if (!vm && !vext_elem_mask(v0, i)) {
152
+ /* No pending and enabled IRQ */
544
+ /* set masked-off elements to 1s */
545
+ vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
153
+ continue;
546
+ continue;
154
+ }
547
+ }
155
+
548
+ fn(vd, vs1, vs2, i);
156
+ if (s->priority[irq_num] > s->threshold) {
157
+ if (!s->claim) {
158
+ s->claim = irq_num;
159
+ }
160
+ return true;
161
+ }
162
+ }
549
+ }
163
+
550
+ env->vstart = 0;
164
+ return false;
551
+ /* set tail elements to 1s */
165
+}
552
+ vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
166
+
553
+}
167
+static void ibex_plic_update(IbexPlicState *s)
554
+
168
+{
555
+void do_vext_vx(void *vd, void *v0, target_long s1, void *vs2,
169
+ CPUState *cpu;
556
+ CPURISCVState *env, uint32_t desc,
170
+ int level, i;
557
+ opivx2_fn fn, uint32_t esz)
171
+
558
+{
172
+ for (i = 0; i < s->num_cpus; i++) {
559
+ uint32_t vm = vext_vm(desc);
173
+ cpu = qemu_get_cpu(i);
560
+ uint32_t vl = env->vl;
174
+
561
+ uint32_t total_elems = vext_get_total_elems(env, desc, esz);
175
+ if (!cpu) {
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);
176
+ continue;
570
+ continue;
177
+ }
571
+ }
178
+
572
+ fn(vd, s1, vs2, i);
179
+ level = ibex_plic_irqs_pending(s, 0);
180
+
181
+ riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level));
182
+ }
573
+ }
183
+}
574
+ env->vstart = 0;
184
+
575
+ /* set tail elements to 1s */
185
+static void ibex_plic_reset(DeviceState *dev)
576
+ vext_set_elems_1s(vd, vta, vl * esz, total_elems * esz);
186
+{
577
+}
187
+ IbexPlicState *s = IBEX_PLIC(dev);
578
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
188
+
189
+ s->threshold = 0x00000000;
190
+ s->claim = 0x00000000;
191
+}
192
+
193
+static uint64_t ibex_plic_read(void *opaque, hwaddr addr,
194
+ unsigned int size)
195
+{
196
+ IbexPlicState *s = opaque;
197
+ int offset;
198
+ uint32_t ret = 0;
199
+
200
+ if (addr_between(addr, s->pending_base, s->pending_num)) {
201
+ offset = (addr - s->pending_base) / 4;
202
+ ret = s->pending[offset];
203
+ } else if (addr_between(addr, s->source_base, s->source_num)) {
204
+ qemu_log_mask(LOG_UNIMP,
205
+ "%s: Interrupt source mode not supported\n", __func__);
206
+ } else if (addr_between(addr, s->priority_base, s->priority_num)) {
207
+ offset = (addr - s->priority_base) / 4;
208
+ ret = s->priority[offset];
209
+ } else if (addr_between(addr, s->enable_base, s->enable_num)) {
210
+ offset = (addr - s->enable_base) / 4;
211
+ ret = s->enable[offset];
212
+ } else if (addr_between(addr, s->threshold_base, 1)) {
213
+ ret = s->threshold;
214
+ } else if (addr_between(addr, s->claim_base, 1)) {
215
+ int pending_num = s->claim / 32;
216
+ s->pending[pending_num] &= ~(1 << (s->claim % 32));
217
+
218
+ ret = s->claim;
219
+ }
220
+
221
+ return ret;
222
+}
223
+
224
+static void ibex_plic_write(void *opaque, hwaddr addr,
225
+ uint64_t value, unsigned int size)
226
+{
227
+ IbexPlicState *s = opaque;
228
+
229
+ if (addr_between(addr, s->pending_base, s->pending_num)) {
230
+ qemu_log_mask(LOG_GUEST_ERROR,
231
+ "%s: Pending registers are read only\n", __func__);
232
+ } else if (addr_between(addr, s->source_base, s->source_num)) {
233
+ qemu_log_mask(LOG_UNIMP,
234
+ "%s: Interrupt source mode not supported\n", __func__);
235
+ } else if (addr_between(addr, s->priority_base, s->priority_num)) {
236
+ uint32_t irq = ((addr - s->priority_base) >> 2) + 1;
237
+ s->priority[irq] = value & 7;
238
+ } else if (addr_between(addr, s->enable_base, s->enable_num)) {
239
+ uint32_t enable_reg = (addr - s->enable_base) / 4;
240
+
241
+ s->enable[enable_reg] = value;
242
+ } else if (addr_between(addr, s->threshold_base, 1)) {
243
+ s->threshold = value & 3;
244
+ } else if (addr_between(addr, s->claim_base, 1)) {
245
+ if (s->claim == value) {
246
+ /* Interrupt was completed */
247
+ s->claim = 0;
248
+ }
249
+ }
250
+
251
+ ibex_plic_update(s);
252
+}
253
+
254
+static const MemoryRegionOps ibex_plic_ops = {
255
+ .read = ibex_plic_read,
256
+ .write = ibex_plic_write,
257
+ .endianness = DEVICE_NATIVE_ENDIAN,
258
+ .valid = {
259
+ .min_access_size = 4,
260
+ .max_access_size = 4
261
+ }
262
+};
263
+
264
+static void ibex_plic_irq_request(void *opaque, int irq, int level)
265
+{
266
+ IbexPlicState *s = opaque;
267
+
268
+ ibex_plic_irqs_set_pending(s, irq, level > 0);
269
+ ibex_plic_update(s);
270
+}
271
+
272
+static Property ibex_plic_properties[] = {
273
+ DEFINE_PROP_UINT32("num-cpus", IbexPlicState, num_cpus, 1),
274
+ DEFINE_PROP_UINT32("num-sources", IbexPlicState, num_sources, 80),
275
+
276
+ DEFINE_PROP_UINT32("pending-base", IbexPlicState, pending_base, 0),
277
+ DEFINE_PROP_UINT32("pending-num", IbexPlicState, pending_num, 3),
278
+
279
+ DEFINE_PROP_UINT32("source-base", IbexPlicState, source_base, 0x0c),
280
+ DEFINE_PROP_UINT32("source-num", IbexPlicState, source_num, 3),
281
+
282
+ DEFINE_PROP_UINT32("priority-base", IbexPlicState, priority_base, 0x18),
283
+ DEFINE_PROP_UINT32("priority-num", IbexPlicState, priority_num, 80),
284
+
285
+ DEFINE_PROP_UINT32("enable-base", IbexPlicState, enable_base, 0x200),
286
+ DEFINE_PROP_UINT32("enable-num", IbexPlicState, enable_num, 3),
287
+
288
+ DEFINE_PROP_UINT32("threshold-base", IbexPlicState, threshold_base, 0x20c),
289
+
290
+ DEFINE_PROP_UINT32("claim-base", IbexPlicState, claim_base, 0x210),
291
+ DEFINE_PROP_END_OF_LIST(),
292
+};
293
+
294
+static void ibex_plic_init(Object *obj)
295
+{
296
+ IbexPlicState *s = IBEX_PLIC(obj);
297
+
298
+ memory_region_init_io(&s->mmio, obj, &ibex_plic_ops, s,
299
+ TYPE_IBEX_PLIC, 0x400);
300
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
301
+}
302
+
303
+static void ibex_plic_realize(DeviceState *dev, Error **errp)
304
+{
305
+ IbexPlicState *s = IBEX_PLIC(dev);
306
+ int i;
307
+
308
+ s->pending = g_new0(uint32_t, s->pending_num);
309
+ s->source = g_new0(uint32_t, s->source_num);
310
+ s->priority = g_new0(uint32_t, s->priority_num);
311
+ s->enable = g_new0(uint32_t, s->enable_num);
312
+
313
+ qdev_init_gpio_in(dev, ibex_plic_irq_request, s->num_sources);
314
+
315
+ /*
316
+ * We can't allow the supervisor to control SEIP as this would allow the
317
+ * supervisor to clear a pending external interrupt which will result in
318
+ * a lost interrupt in the case a PLIC is attached. The SEIP bit must be
319
+ * hardware controlled when a PLIC is attached.
320
+ */
321
+ MachineState *ms = MACHINE(qdev_get_machine());
322
+ unsigned int smp_cpus = ms->smp.cpus;
323
+ for (i = 0; i < smp_cpus; i++) {
324
+ RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(i));
325
+ if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
326
+ error_report("SEIP already claimed");
327
+ exit(1);
328
+ }
329
+ }
330
+
331
+ msi_nonbroken = true;
332
+}
333
+
334
+static void ibex_plic_class_init(ObjectClass *klass, void *data)
335
+{
336
+ DeviceClass *dc = DEVICE_CLASS(klass);
337
+
338
+ dc->reset = ibex_plic_reset;
339
+ device_class_set_props(dc, ibex_plic_properties);
340
+ dc->realize = ibex_plic_realize;
341
+}
342
+
343
+static const TypeInfo ibex_plic_info = {
344
+ .name = TYPE_IBEX_PLIC,
345
+ .parent = TYPE_SYS_BUS_DEVICE,
346
+ .instance_size = sizeof(IbexPlicState),
347
+ .instance_init = ibex_plic_init,
348
+ .class_init = ibex_plic_class_init,
349
+};
350
+
351
+static void ibex_plic_register_types(void)
352
+{
353
+ type_register_static(&ibex_plic_info);
354
+}
355
+
356
+type_init(ibex_plic_register_types)
357
diff --git a/MAINTAINERS b/MAINTAINERS
358
index XXXXXXX..XXXXXXX 100644
579
index XXXXXXX..XXXXXXX 100644
359
--- a/MAINTAINERS
580
--- a/target/riscv/meson.build
360
+++ b/MAINTAINERS
581
+++ b/target/riscv/meson.build
361
@@ -XXX,XX +XXX,XX @@ L: qemu-riscv@nongnu.org
582
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(files(
362
S: Supported
583
'gdbstub.c',
363
F: hw/riscv/opentitan.c
584
'op_helper.c',
364
F: hw/char/ibex_uart.c
585
'vector_helper.c',
365
+F: hw/intc/ibex_plic.c
586
+ 'vector_internals.c',
366
F: include/hw/riscv/opentitan.h
587
'bitmanip_helper.c',
367
F: include/hw/char/ibex_uart.h
588
'translate.c',
368
+F: include/hw/intc/ibex_plic.h
589
'm128_helper.c',
369
370
SH4 Machines
371
------------
372
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
373
index XXXXXXX..XXXXXXX 100644
374
--- a/hw/intc/Makefile.objs
375
+++ b/hw/intc/Makefile.objs
376
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpuif.o
377
obj-$(CONFIG_MIPS_CPS) += mips_gic.o
378
obj-$(CONFIG_NIOS2) += nios2_iic.o
379
obj-$(CONFIG_OMPIC) += ompic.o
380
+obj-$(CONFIG_IBEX) += ibex_plic.o
381
--
590
--
382
2.27.0
591
2.41.0
383
384
diff view generated by jsdifflib
New patch
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
1
2
3
Refactor the non SEW-specific stuff out of `GEN_OPIVV_TRANS` into
4
function `opivv_trans` (similar to `opivi_trans`). `opivv_trans` will be
5
used in proceeding vector-crypto commits.
6
7
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
12
Message-ID: <20230711165917.2629866-3-max.chou@sifive.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/insn_trans/trans_rvv.c.inc | 62 +++++++++++++------------
16
1 file changed, 32 insertions(+), 30 deletions(-)
17
18
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/insn_trans/trans_rvv.c.inc
21
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
22
@@ -XXX,XX +XXX,XX @@ GEN_OPIWX_WIDEN_TRANS(vwadd_wx)
23
GEN_OPIWX_WIDEN_TRANS(vwsubu_wx)
24
GEN_OPIWX_WIDEN_TRANS(vwsub_wx)
25
26
+static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
27
+ gen_helper_gvec_4_ptr *fn, DisasContext *s)
28
+{
29
+ uint32_t data = 0;
30
+ TCGLabel *over = gen_new_label();
31
+ tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
32
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
33
+
34
+ data = FIELD_DP32(data, VDATA, VM, vm);
35
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
36
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
37
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
38
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
39
+ tcg_gen_gvec_4_ptr(vreg_ofs(s, vd), vreg_ofs(s, 0), vreg_ofs(s, vs1),
40
+ vreg_ofs(s, vs2), cpu_env, s->cfg_ptr->vlen / 8,
41
+ s->cfg_ptr->vlen / 8, data, fn);
42
+ mark_vs_dirty(s);
43
+ gen_set_label(over);
44
+ return true;
45
+}
46
+
47
/* Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions */
48
/* OPIVV without GVEC IR */
49
-#define GEN_OPIVV_TRANS(NAME, CHECK) \
50
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
51
-{ \
52
- if (CHECK(s, a)) { \
53
- uint32_t data = 0; \
54
- static gen_helper_gvec_4_ptr * const fns[4] = { \
55
- gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
56
- gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
57
- }; \
58
- TCGLabel *over = gen_new_label(); \
59
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
60
- tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
61
- \
62
- data = FIELD_DP32(data, VDATA, VM, a->vm); \
63
- data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
64
- data = FIELD_DP32(data, VDATA, VTA, s->vta); \
65
- data = \
66
- FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);\
67
- data = FIELD_DP32(data, VDATA, VMA, s->vma); \
68
- tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
69
- vreg_ofs(s, a->rs1), \
70
- vreg_ofs(s, a->rs2), cpu_env, \
71
- s->cfg_ptr->vlen / 8, \
72
- s->cfg_ptr->vlen / 8, data, \
73
- fns[s->sew]); \
74
- mark_vs_dirty(s); \
75
- gen_set_label(over); \
76
- return true; \
77
- } \
78
- return false; \
79
+#define GEN_OPIVV_TRANS(NAME, CHECK) \
80
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
81
+{ \
82
+ if (CHECK(s, a)) { \
83
+ static gen_helper_gvec_4_ptr * const fns[4] = { \
84
+ gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
85
+ gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
86
+ }; \
87
+ return opivv_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s);\
88
+ } \
89
+ return false; \
90
}
91
92
/*
93
--
94
2.41.0
diff view generated by jsdifflib
New patch
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
1
2
3
Remove the redundant "vl == 0" check which is already included within the vstart >= vl check, when vl == 0.
4
5
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
6
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
7
Signed-off-by: Max Chou <max.chou@sifive.com>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20230711165917.2629866-4-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/insn_trans/trans_rvv.c.inc | 31 +------------------------
13
1 file changed, 1 insertion(+), 30 deletions(-)
14
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
@@ -XXX,XX +XXX,XX @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
20
TCGv_i32 desc;
21
22
TCGLabel *over = gen_new_label();
23
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
24
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
25
26
dest = tcg_temp_new_ptr();
27
@@ -XXX,XX +XXX,XX @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
28
TCGv_i32 desc;
29
30
TCGLabel *over = gen_new_label();
31
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
32
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
33
34
dest = tcg_temp_new_ptr();
35
@@ -XXX,XX +XXX,XX @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
36
TCGv_i32 desc;
37
38
TCGLabel *over = gen_new_label();
39
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
40
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
41
42
dest = tcg_temp_new_ptr();
43
@@ -XXX,XX +XXX,XX @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
44
TCGv_i32 desc;
45
46
TCGLabel *over = gen_new_label();
47
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
48
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
49
50
dest = tcg_temp_new_ptr();
51
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
52
return false;
53
}
54
55
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
56
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
57
58
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
59
@@ -XXX,XX +XXX,XX @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
60
uint32_t data = 0;
61
62
TCGLabel *over = gen_new_label();
63
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
64
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
65
66
dest = tcg_temp_new_ptr();
67
@@ -XXX,XX +XXX,XX @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
68
uint32_t data = 0;
69
70
TCGLabel *over = gen_new_label();
71
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
72
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
73
74
dest = tcg_temp_new_ptr();
75
@@ -XXX,XX +XXX,XX @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
76
if (checkfn(s, a)) {
77
uint32_t data = 0;
78
TCGLabel *over = gen_new_label();
79
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
80
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
81
82
data = FIELD_DP32(data, VDATA, VM, a->vm);
83
@@ -XXX,XX +XXX,XX @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
84
if (opiwv_widen_check(s, a)) {
85
uint32_t data = 0;
86
TCGLabel *over = gen_new_label();
87
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
88
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
89
90
data = FIELD_DP32(data, VDATA, VM, a->vm);
91
@@ -XXX,XX +XXX,XX @@ static bool opivv_trans(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t vm,
92
{
93
uint32_t data = 0;
94
TCGLabel *over = gen_new_label();
95
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
96
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
97
98
data = FIELD_DP32(data, VDATA, VM, vm);
99
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
100
gen_helper_##NAME##_w, \
101
}; \
102
TCGLabel *over = gen_new_label(); \
103
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
104
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
105
\
106
data = FIELD_DP32(data, VDATA, VM, a->vm); \
107
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
108
gen_helper_vmv_v_v_w, gen_helper_vmv_v_v_d,
109
};
110
TCGLabel *over = gen_new_label();
111
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
112
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
113
114
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
115
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
116
vext_check_ss(s, a->rd, 0, 1)) {
117
TCGv s1;
118
TCGLabel *over = gen_new_label();
119
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
120
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
121
122
s1 = get_gpr(s, a->rs1, EXT_SIGN);
123
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
124
gen_helper_vmv_v_x_w, gen_helper_vmv_v_x_d,
125
};
126
TCGLabel *over = gen_new_label();
127
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
128
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
129
130
s1 = tcg_constant_i64(simm);
131
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
132
}; \
133
TCGLabel *over = gen_new_label(); \
134
gen_set_rm(s, RISCV_FRM_DYN); \
135
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
136
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
137
\
138
data = FIELD_DP32(data, VDATA, VM, a->vm); \
139
@@ -XXX,XX +XXX,XX @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
140
TCGv_i64 t1;
141
142
TCGLabel *over = gen_new_label();
143
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
144
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
145
146
dest = tcg_temp_new_ptr();
147
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
148
}; \
149
TCGLabel *over = gen_new_label(); \
150
gen_set_rm(s, RISCV_FRM_DYN); \
151
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
152
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);\
153
\
154
data = FIELD_DP32(data, VDATA, VM, a->vm); \
155
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
156
}; \
157
TCGLabel *over = gen_new_label(); \
158
gen_set_rm(s, RISCV_FRM_DYN); \
159
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
160
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
161
\
162
data = FIELD_DP32(data, VDATA, VM, a->vm); \
163
@@ -XXX,XX +XXX,XX @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
164
uint32_t data = 0;
165
TCGLabel *over = gen_new_label();
166
gen_set_rm_chkfrm(s, rm);
167
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
168
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
169
170
data = FIELD_DP32(data, VDATA, VM, a->vm);
171
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
172
gen_helper_vmv_v_x_d,
173
};
174
TCGLabel *over = gen_new_label();
175
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
176
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
177
178
t1 = tcg_temp_new_i64();
179
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
180
}; \
181
TCGLabel *over = gen_new_label(); \
182
gen_set_rm_chkfrm(s, FRM); \
183
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
184
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
185
\
186
data = FIELD_DP32(data, VDATA, VM, a->vm); \
187
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
188
}; \
189
TCGLabel *over = gen_new_label(); \
190
gen_set_rm(s, RISCV_FRM_DYN); \
191
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
192
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
193
\
194
data = FIELD_DP32(data, VDATA, VM, a->vm); \
195
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
196
}; \
197
TCGLabel *over = gen_new_label(); \
198
gen_set_rm_chkfrm(s, FRM); \
199
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
200
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
201
\
202
data = FIELD_DP32(data, VDATA, VM, a->vm); \
203
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
204
}; \
205
TCGLabel *over = gen_new_label(); \
206
gen_set_rm_chkfrm(s, FRM); \
207
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
208
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
209
\
210
data = FIELD_DP32(data, VDATA, VM, a->vm); \
211
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_r *a) \
212
uint32_t data = 0; \
213
gen_helper_gvec_4_ptr *fn = gen_helper_##NAME; \
214
TCGLabel *over = gen_new_label(); \
215
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
216
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
217
\
218
data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
219
@@ -XXX,XX +XXX,XX @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
220
require_vm(a->vm, a->rd)) {
221
uint32_t data = 0;
222
TCGLabel *over = gen_new_label();
223
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
224
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
225
226
data = FIELD_DP32(data, VDATA, VM, a->vm);
227
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
228
TCGv s1;
229
TCGLabel *over = gen_new_label();
230
231
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
232
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
233
234
t1 = tcg_temp_new_i64();
235
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
236
TCGv_i64 t1;
237
TCGLabel *over = gen_new_label();
238
239
- /* if vl == 0 or vstart >= vl, skip vector register write back */
240
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
241
+ /* if vstart >= vl, skip vector register write back */
242
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
243
244
/* NaN-box f[rs1] */
245
@@ -XXX,XX +XXX,XX @@ static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
246
uint32_t data = 0;
247
gen_helper_gvec_3_ptr *fn;
248
TCGLabel *over = gen_new_label();
249
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
250
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
251
252
static gen_helper_gvec_3_ptr * const fns[6][4] = {
253
--
254
2.41.0
diff view generated by jsdifflib
1
Also correct the name of the VVMA instruction.
1
From: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
2
2
3
This commit adds support for the Zvbc vector-crypto extension, which
4
consists of the following instructions:
5
6
* vclmulh.[vx,vv]
7
* vclmul.[vx,vv]
8
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
14
Co-authored-by: Max Chou <max.chou@sifive.com>
15
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
16
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
17
Signed-off-by: Max Chou <max.chou@sifive.com>
18
[max.chou@sifive.com: Exposed x-zvbc property]
19
Message-ID: <20230711165917.2629866-5-max.chou@sifive.com>
3
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
---
21
---
6
target/riscv/insn32.decode | 8 ++-
22
target/riscv/cpu_cfg.h | 1 +
7
.../riscv/insn_trans/trans_privileged.inc.c | 38 -------------
23
target/riscv/helper.h | 6 +++
8
target/riscv/insn_trans/trans_rvh.inc.c | 57 +++++++++++++++++++
24
target/riscv/insn32.decode | 6 +++
9
target/riscv/translate.c | 1 +
25
target/riscv/cpu.c | 9 ++++
10
4 files changed, 63 insertions(+), 41 deletions(-)
26
target/riscv/translate.c | 1 +
11
create mode 100644 target/riscv/insn_trans/trans_rvh.inc.c
27
target/riscv/vcrypto_helper.c | 59 ++++++++++++++++++++++
12
28
target/riscv/insn_trans/trans_rvvk.c.inc | 62 ++++++++++++++++++++++++
29
target/riscv/meson.build | 3 +-
30
8 files changed, 146 insertions(+), 1 deletion(-)
31
create mode 100644 target/riscv/vcrypto_helper.c
32
create mode 100644 target/riscv/insn_trans/trans_rvvk.c.inc
33
34
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/riscv/cpu_cfg.h
37
+++ b/target/riscv/cpu_cfg.h
38
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
39
bool ext_zve32f;
40
bool ext_zve64f;
41
bool ext_zve64d;
42
+ bool ext_zvbc;
43
bool ext_zmmul;
44
bool ext_zvfbfmin;
45
bool ext_zvfbfwma;
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)
13
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
14
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/insn32.decode
62
--- a/target/riscv/insn32.decode
16
+++ b/target/riscv/insn32.decode
63
+++ b/target/riscv/insn32.decode
17
@@ -XXX,XX +XXX,XX @@
64
@@ -XXX,XX +XXX,XX @@ vfwcvtbf16_f_f_v 010010 . ..... 01101 001 ..... 1010111 @r2_vm
18
@r2 ....... ..... ..... ... ..... ....... %rs1 %rd
65
# *** Zvfbfwma Standard Extension ***
19
66
vfwmaccbf16_vv 111011 . ..... ..... 001 ..... 1010111 @r_vm
20
@hfence_gvma ....... ..... ..... ... ..... ....... %rs2 %rs1
67
vfwmaccbf16_vf 111011 . ..... ..... 101 ..... 1010111 @r_vm
21
-@hfence_bvma ....... ..... ..... ... ..... ....... %rs2 %rs1
68
+
22
+@hfence_vvma ....... ..... ..... ... ..... ....... %rs2 %rs1
69
+# *** Zvbc vector crypto extension ***
23
70
+vclmul_vv 001100 . ..... ..... 010 ..... 1010111 @r_vm
24
@sfence_vma ....... ..... ..... ... ..... ....... %rs2 %rs1
71
+vclmul_vx 001100 . ..... ..... 110 ..... 1010111 @r_vm
25
@sfence_vm ....... ..... ..... ... ..... ....... %rs1
72
+vclmulh_vv 001101 . ..... ..... 010 ..... 1010111 @r_vm
26
@@ -XXX,XX +XXX,XX @@ uret 0000000 00010 00000 000 00000 1110011
73
+vclmulh_vx 001101 . ..... ..... 110 ..... 1010111 @r_vm
27
sret 0001000 00010 00000 000 00000 1110011
74
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
28
mret 0011000 00010 00000 000 00000 1110011
75
index XXXXXXX..XXXXXXX 100644
29
wfi 0001000 00101 00000 000 00000 1110011
76
--- a/target/riscv/cpu.c
30
-hfence_gvma 0110001 ..... ..... 000 00000 1110011 @hfence_gvma
77
+++ b/target/riscv/cpu.c
31
-hfence_bvma 0010001 ..... ..... 000 00000 1110011 @hfence_bvma
78
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
32
sfence_vma 0001001 ..... ..... 000 00000 1110011 @sfence_vma
79
ISA_EXT_DATA_ENTRY(zksed, PRIV_VERSION_1_12_0, ext_zksed),
33
sfence_vm 0001000 00100 ..... 000 00000 1110011 @sfence_vm
80
ISA_EXT_DATA_ENTRY(zksh, PRIV_VERSION_1_12_0, ext_zksh),
34
81
ISA_EXT_DATA_ENTRY(zkt, PRIV_VERSION_1_12_0, ext_zkt),
35
@@ -XXX,XX +XXX,XX @@ fcvt_w_d 1100001 00000 ..... ... ..... 1010011 @r2_rm
82
+ ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
36
fcvt_wu_d 1100001 00001 ..... ... ..... 1010011 @r2_rm
83
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
37
fcvt_d_w 1101001 00000 ..... ... ..... 1010011 @r2_rm
84
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
38
fcvt_d_wu 1101001 00001 ..... ... ..... 1010011 @r2_rm
85
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
39
+
86
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
40
+# *** RV32H Base Instruction Set ***
87
return;
41
+hfence_gvma 0110001 ..... ..... 000 00000 1110011 @hfence_gvma
88
}
42
+hfence_vvma 0010001 ..... ..... 000 00000 1110011 @hfence_vvma
89
43
diff --git a/target/riscv/insn_trans/trans_privileged.inc.c b/target/riscv/insn_trans/trans_privileged.inc.c
90
+ if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
44
index XXXXXXX..XXXXXXX 100644
91
+ error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
45
--- a/target/riscv/insn_trans/trans_privileged.inc.c
92
+ return;
46
+++ b/target/riscv/insn_trans/trans_privileged.inc.c
93
+ }
47
@@ -XXX,XX +XXX,XX @@ static bool trans_sfence_vm(DisasContext *ctx, arg_sfence_vm *a)
94
+
48
{
95
if (cpu->cfg.ext_zk) {
49
return false;
96
cpu->cfg.ext_zkn = true;
50
}
97
cpu->cfg.ext_zkr = true;
51
-
98
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
52
-static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
99
DEFINE_PROP_BOOL("x-zvfbfmin", RISCVCPU, cfg.ext_zvfbfmin, false),
53
-{
100
DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
54
-#ifndef CONFIG_USER_ONLY
101
55
- if (has_ext(ctx, RVH)) {
102
+ /* Vector cryptography extensions */
56
- /* Hpervisor extensions exist */
103
+ DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
57
- /*
104
+
58
- * if (env->priv == PRV_M ||
105
DEFINE_PROP_END_OF_LIST(),
59
- * (env->priv == PRV_S &&
106
};
60
- * !riscv_cpu_virt_enabled(env) &&
107
61
- * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
108
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
62
- */
109
index XXXXXXX..XXXXXXX 100644
63
- gen_helper_tlb_flush(cpu_env);
110
--- a/target/riscv/translate.c
64
- return true;
111
+++ b/target/riscv/translate.c
65
- /* } */
112
@@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
66
- }
113
#include "insn_trans/trans_rvzfa.c.inc"
67
-#endif
114
#include "insn_trans/trans_rvzfh.c.inc"
68
- return false;
115
#include "insn_trans/trans_rvk.c.inc"
69
-}
116
+#include "insn_trans/trans_rvvk.c.inc"
70
-
117
#include "insn_trans/trans_privileged.c.inc"
71
-static bool trans_hfence_bvma(DisasContext *ctx, arg_sfence_vma *a)
118
#include "insn_trans/trans_svinval.c.inc"
72
-{
119
#include "insn_trans/trans_rvbf16.c.inc"
73
-#ifndef CONFIG_USER_ONLY
120
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
74
- if (has_ext(ctx, RVH)) {
75
- /* Hpervisor extensions exist */
76
- /*
77
- * if (env->priv == PRV_M ||
78
- * (env->priv == PRV_S &&
79
- * !riscv_cpu_virt_enabled(env) &&
80
- * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
81
- */
82
- gen_helper_tlb_flush(cpu_env);
83
- return true;
84
- /* } */
85
- }
86
-#endif
87
- return false;
88
-}
89
diff --git a/target/riscv/insn_trans/trans_rvh.inc.c b/target/riscv/insn_trans/trans_rvh.inc.c
90
new file mode 100644
121
new file mode 100644
91
index XXXXXXX..XXXXXXX
122
index XXXXXXX..XXXXXXX
92
--- /dev/null
123
--- /dev/null
93
+++ b/target/riscv/insn_trans/trans_rvh.inc.c
124
+++ b/target/riscv/vcrypto_helper.c
94
@@ -XXX,XX +XXX,XX @@
125
@@ -XXX,XX +XXX,XX @@
95
+/*
126
+/*
96
+ * RISC-V translation routines for the RVXI Base Integer Instruction Set.
127
+ * RISC-V Vector Crypto Extension Helpers for QEMU.
97
+ *
128
+ *
98
+ * Copyright (c) 2020 Western Digital
129
+ * Copyright (C) 2023 SiFive, Inc.
130
+ * Written by Codethink Ltd and SiFive.
99
+ *
131
+ *
100
+ * 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
101
+ * under the terms and conditions of the GNU General Public License,
133
+ * under the terms and conditions of the GNU General Public License,
102
+ * version 2 or later, as published by the Free Software Foundation.
134
+ * version 2 or later, as published by the Free Software Foundation.
103
+ *
135
+ *
...
...
108
+ *
140
+ *
109
+ * 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
110
+ * this program. If not, see <http://www.gnu.org/licenses/>.
142
+ * this program. If not, see <http://www.gnu.org/licenses/>.
111
+ */
143
+ */
112
+
144
+
113
+static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
145
+#include "qemu/osdep.h"
114
+{
146
+#include "qemu/host-utils.h"
115
+#ifndef CONFIG_USER_ONLY
147
+#include "qemu/bitops.h"
116
+ if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
148
+#include "cpu.h"
117
+ has_ext(ctx, RVH)) {
149
+#include "exec/memop.h"
118
+ /* Hpervisor extensions exist */
150
+#include "exec/exec-all.h"
119
+ /*
151
+#include "exec/helper-proto.h"
120
+ * if (env->priv == PRV_M ||
152
+#include "internals.h"
121
+ * (env->priv == PRV_S &&
153
+#include "vector_internals.h"
122
+ * !riscv_cpu_virt_enabled(env) &&
154
+
123
+ * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
155
+static uint64_t clmul64(uint64_t y, uint64_t x)
124
+ */
156
+{
125
+ gen_helper_tlb_flush(cpu_env);
157
+ uint64_t result = 0;
126
+ return true;
158
+ for (int j = 63; j >= 0; j--) {
127
+ /* } */
159
+ if ((y >> j) & 1) {
128
+ }
160
+ result ^= (x << j);
129
+#endif
161
+ }
130
+ return false;
162
+ }
131
+}
163
+ return result;
132
+
164
+}
133
+static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a)
165
+
134
+{
166
+static uint64_t clmulh64(uint64_t y, uint64_t x)
135
+#ifndef CONFIG_USER_ONLY
167
+{
136
+ if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
168
+ uint64_t result = 0;
137
+ has_ext(ctx, RVH)) {
169
+ for (int j = 63; j >= 1; j--) {
138
+ /* Hpervisor extensions exist */
170
+ if ((y >> j) & 1) {
139
+ /*
171
+ result ^= (x >> (64 - j));
140
+ * if (env->priv == PRV_M ||
172
+ }
141
+ * (env->priv == PRV_S &&
173
+ }
142
+ * !riscv_cpu_virt_enabled(env) &&
174
+ return result;
143
+ * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
175
+}
144
+ */
176
+
145
+ gen_helper_tlb_flush(cpu_env);
177
+RVVCALL(OPIVV2, vclmul_vv, OP_UUU_D, H8, H8, H8, clmul64)
146
+ return true;
178
+GEN_VEXT_VV(vclmul_vv, 8)
147
+ /* } */
179
+RVVCALL(OPIVX2, vclmul_vx, OP_UUU_D, H8, H8, clmul64)
148
+ }
180
+GEN_VEXT_VX(vclmul_vx, 8)
149
+#endif
181
+RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64)
150
+ return false;
182
+GEN_VEXT_VV(vclmulh_vv, 8)
151
+}
183
+RVVCALL(OPIVX2, vclmulh_vx, OP_UUU_D, H8, H8, clmulh64)
152
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
184
+GEN_VEXT_VX(vclmulh_vx, 8)
153
index XXXXXXX..XXXXXXX 100644
185
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
154
--- a/target/riscv/translate.c
186
new file mode 100644
155
+++ b/target/riscv/translate.c
187
index XXXXXXX..XXXXXXX
156
@@ -XXX,XX +XXX,XX @@ static bool gen_shift(DisasContext *ctx, arg_r *a,
188
--- /dev/null
157
#include "insn_trans/trans_rva.inc.c"
189
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
158
#include "insn_trans/trans_rvf.inc.c"
190
@@ -XXX,XX +XXX,XX @@
159
#include "insn_trans/trans_rvd.inc.c"
191
+/*
160
+#include "insn_trans/trans_rvh.inc.c"
192
+ * RISC-V translation routines for the vector crypto extension.
161
#include "insn_trans/trans_privileged.inc.c"
193
+ *
162
194
+ * Copyright (C) 2023 SiFive, Inc.
163
/* Include the auto-generated decoder for 16 bit insn */
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
164
--
267
--
165
2.27.0
268
2.41.0
166
167
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
2
3
In prepration to add more properties to this machine, rename the
3
Move the checks out of `do_opiv{v,x,i}_gvec{,_shift}` functions
4
existing serial property get/set functions to a generic name.
4
and into the corresponding macros. This enables the functions to be
5
reused in proceeding commits without check duplication.
5
6
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 1591625864-31494-11-git-send-email-bmeng.cn@gmail.com
9
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
Message-Id: <1591625864-31494-11-git-send-email-bmeng.cn@gmail.com>
10
Signed-off-by: Max Chou <max.chou@sifive.com>
11
Message-ID: <20230711165917.2629866-6-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
13
---
12
hw/riscv/sifive_u.c | 14 ++++++++------
14
target/riscv/insn_trans/trans_rvv.c.inc | 28 +++++++++++--------------
13
1 file changed, 8 insertions(+), 6 deletions(-)
15
1 file changed, 12 insertions(+), 16 deletions(-)
14
16
15
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
17
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
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/sifive_u.c
19
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/hw/riscv/sifive_u.c
20
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_set_start_in_flash(Object *obj, bool value, Error *
21
@@ -XXX,XX +XXX,XX @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn *gvec_fn,
20
s->start_in_flash = value;
22
gen_helper_gvec_4_ptr *fn)
23
{
24
TCGLabel *over = gen_new_label();
25
- if (!opivv_check(s, a)) {
26
- return false;
27
- }
28
29
tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
30
31
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
32
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
33
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
34
}; \
35
+ if (!opivv_check(s, a)) { \
36
+ return false; \
37
+ } \
38
return do_opivv_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
21
}
39
}
22
40
23
-static void sifive_u_machine_get_serial(Object *obj, Visitor *v, const char *name,
41
@@ -XXX,XX +XXX,XX @@ static inline bool
24
- void *opaque, Error **errp)
42
do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
25
+static void sifive_u_machine_get_uint32_prop(Object *obj, Visitor *v,
43
gen_helper_opivx *fn)
26
+ const char *name, void *opaque,
27
+ Error **errp)
28
{
44
{
29
visit_type_uint32(v, name, (uint32_t *)opaque, errp);
45
- if (!opivx_check(s, a)) {
46
- return false;
47
- }
48
-
49
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
50
TCGv_i64 src1 = tcg_temp_new_i64();
51
52
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
53
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
54
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
55
}; \
56
+ if (!opivx_check(s, a)) { \
57
+ return false; \
58
+ } \
59
return do_opivx_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
30
}
60
}
31
61
32
-static void sifive_u_machine_set_serial(Object *obj, Visitor *v, const char *name,
62
@@ -XXX,XX +XXX,XX @@ static inline bool
33
- void *opaque, Error **errp)
63
do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn,
34
+static void sifive_u_machine_set_uint32_prop(Object *obj, Visitor *v,
64
gen_helper_opivx *fn, imm_mode_t imm_mode)
35
+ const char *name, void *opaque,
36
+ Error **errp)
37
{
65
{
38
visit_type_uint32(v, name, (uint32_t *)opaque, errp);
66
- if (!opivx_check(s, a)) {
67
- return false;
68
- }
69
-
70
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
71
gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
72
extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s));
73
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
74
gen_helper_##OPIVX##_b, gen_helper_##OPIVX##_h, \
75
gen_helper_##OPIVX##_w, gen_helper_##OPIVX##_d, \
76
}; \
77
+ if (!opivx_check(s, a)) { \
78
+ return false; \
79
+ } \
80
return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, \
81
fns[s->sew], IMM_MODE); \
39
}
82
}
40
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_instance_init(Object *obj)
83
@@ -XXX,XX +XXX,XX @@ static inline bool
41
84
do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
42
s->serial = OTP_SERIAL;
85
gen_helper_opivx *fn)
43
object_property_add(obj, "serial", "uint32",
86
{
44
- sifive_u_machine_get_serial,
87
- if (!opivx_check(s, a)) {
45
- sifive_u_machine_set_serial, NULL, &s->serial);
88
- return false;
46
+ sifive_u_machine_get_uint32_prop,
89
- }
47
+ sifive_u_machine_set_uint32_prop, NULL, &s->serial);
90
-
48
object_property_set_description(obj, "serial", "Board serial number");
91
if (a->vm && s->vl_eq_vlmax && !(s->vta && s->lmul < 0)) {
92
TCGv_i32 src1 = tcg_temp_new_i32();
93
94
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
95
gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
96
gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
97
}; \
98
- \
99
+ if (!opivx_check(s, a)) { \
100
+ return false; \
101
+ } \
102
return do_opivx_gvec_shift(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
49
}
103
}
50
104
51
--
105
--
52
2.27.0
106
2.41.0
53
54
diff view generated by jsdifflib
New patch
1
From: Dickon Hood <dickon.hood@codethink.co.uk>
1
2
3
Zvbb (implemented in later commit) has a widening instruction, which
4
requires an extra check on the enabled extensions. Refactor
5
GEN_OPIVX_WIDEN_TRANS() to take a check function to avoid reimplementing
6
it.
7
8
Signed-off-by: Dickon Hood <dickon.hood@codethink.co.uk>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
12
Message-ID: <20230711165917.2629866-7-max.chou@sifive.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/insn_trans/trans_rvv.c.inc | 52 +++++++++++--------------
16
1 file changed, 23 insertions(+), 29 deletions(-)
17
18
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/insn_trans/trans_rvv.c.inc
21
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
22
@@ -XXX,XX +XXX,XX @@ static bool opivx_widen_check(DisasContext *s, arg_rmrr *a)
23
vext_check_ds(s, a->rd, a->rs2, a->vm);
24
}
25
26
-static bool do_opivx_widen(DisasContext *s, arg_rmrr *a,
27
- gen_helper_opivx *fn)
28
-{
29
- if (opivx_widen_check(s, a)) {
30
- return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
31
- }
32
- return false;
33
-}
34
-
35
-#define GEN_OPIVX_WIDEN_TRANS(NAME) \
36
-static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
37
-{ \
38
- static gen_helper_opivx * const fns[3] = { \
39
- gen_helper_##NAME##_b, \
40
- gen_helper_##NAME##_h, \
41
- gen_helper_##NAME##_w \
42
- }; \
43
- return do_opivx_widen(s, a, fns[s->sew]); \
44
+#define GEN_OPIVX_WIDEN_TRANS(NAME, CHECK) \
45
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
46
+{ \
47
+ if (CHECK(s, a)) { \
48
+ static gen_helper_opivx * const fns[3] = { \
49
+ gen_helper_##NAME##_b, \
50
+ gen_helper_##NAME##_h, \
51
+ gen_helper_##NAME##_w \
52
+ }; \
53
+ return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s); \
54
+ } \
55
+ return false; \
56
}
57
58
-GEN_OPIVX_WIDEN_TRANS(vwaddu_vx)
59
-GEN_OPIVX_WIDEN_TRANS(vwadd_vx)
60
-GEN_OPIVX_WIDEN_TRANS(vwsubu_vx)
61
-GEN_OPIVX_WIDEN_TRANS(vwsub_vx)
62
+GEN_OPIVX_WIDEN_TRANS(vwaddu_vx, opivx_widen_check)
63
+GEN_OPIVX_WIDEN_TRANS(vwadd_vx, opivx_widen_check)
64
+GEN_OPIVX_WIDEN_TRANS(vwsubu_vx, opivx_widen_check)
65
+GEN_OPIVX_WIDEN_TRANS(vwsub_vx, opivx_widen_check)
66
67
/* WIDEN OPIVV with WIDEN */
68
static bool opiwv_widen_check(DisasContext *s, arg_rmrr *a)
69
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vrem_vx, opivx_check)
70
GEN_OPIVV_WIDEN_TRANS(vwmul_vv, opivv_widen_check)
71
GEN_OPIVV_WIDEN_TRANS(vwmulu_vv, opivv_widen_check)
72
GEN_OPIVV_WIDEN_TRANS(vwmulsu_vv, opivv_widen_check)
73
-GEN_OPIVX_WIDEN_TRANS(vwmul_vx)
74
-GEN_OPIVX_WIDEN_TRANS(vwmulu_vx)
75
-GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx)
76
+GEN_OPIVX_WIDEN_TRANS(vwmul_vx, opivx_widen_check)
77
+GEN_OPIVX_WIDEN_TRANS(vwmulu_vx, opivx_widen_check)
78
+GEN_OPIVX_WIDEN_TRANS(vwmulsu_vx, opivx_widen_check)
79
80
/* Vector Single-Width Integer Multiply-Add Instructions */
81
GEN_OPIVV_TRANS(vmacc_vv, opivv_check)
82
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vnmsub_vx, opivx_check)
83
GEN_OPIVV_WIDEN_TRANS(vwmaccu_vv, opivv_widen_check)
84
GEN_OPIVV_WIDEN_TRANS(vwmacc_vv, opivv_widen_check)
85
GEN_OPIVV_WIDEN_TRANS(vwmaccsu_vv, opivv_widen_check)
86
-GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx)
87
-GEN_OPIVX_WIDEN_TRANS(vwmacc_vx)
88
-GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx)
89
-GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx)
90
+GEN_OPIVX_WIDEN_TRANS(vwmaccu_vx, opivx_widen_check)
91
+GEN_OPIVX_WIDEN_TRANS(vwmacc_vx, opivx_widen_check)
92
+GEN_OPIVX_WIDEN_TRANS(vwmaccsu_vx, opivx_widen_check)
93
+GEN_OPIVX_WIDEN_TRANS(vwmaccus_vx, opivx_widen_check)
94
95
/* Vector Integer Merge and Move Instructions */
96
static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
97
--
98
2.41.0
diff view generated by jsdifflib
New patch
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
1
2
3
Move some macros out of `vector_helper` and into `vector_internals`.
4
This ensures they can be used by both vector and vector-crypto helpers
5
(latter implemented in proceeding commits).
6
7
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
8
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
Signed-off-by: Max Chou <max.chou@sifive.com>
10
Message-ID: <20230711165917.2629866-8-max.chou@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/vector_internals.h | 46 +++++++++++++++++++++++++++++++++
14
target/riscv/vector_helper.c | 42 ------------------------------
15
2 files changed, 46 insertions(+), 42 deletions(-)
16
17
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/vector_internals.h
20
+++ b/target/riscv/vector_internals.h
21
@@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
22
/* expand macro args before macro */
23
#define RVVCALL(macro, ...) macro(__VA_ARGS__)
24
25
+/* (TD, T2, TX2) */
26
+#define OP_UU_B uint8_t, uint8_t, uint8_t
27
+#define OP_UU_H uint16_t, uint16_t, uint16_t
28
+#define OP_UU_W uint32_t, uint32_t, uint32_t
29
+#define OP_UU_D uint64_t, uint64_t, uint64_t
30
+
31
/* (TD, T1, T2, TX1, TX2) */
32
#define OP_UUU_B uint8_t, uint8_t, uint8_t, uint8_t, uint8_t
33
#define OP_UUU_H uint16_t, uint16_t, uint16_t, uint16_t, uint16_t
34
#define OP_UUU_W uint32_t, uint32_t, uint32_t, uint32_t, uint32_t
35
#define OP_UUU_D uint64_t, uint64_t, uint64_t, uint64_t, uint64_t
36
37
+#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
38
+static void do_##NAME(void *vd, void *vs2, int i) \
39
+{ \
40
+ TX2 s2 = *((T2 *)vs2 + HS2(i)); \
41
+ *((TD *)vd + HD(i)) = OP(s2); \
42
+}
43
+
44
+#define GEN_VEXT_V(NAME, ESZ) \
45
+void HELPER(NAME)(void *vd, void *v0, void *vs2, \
46
+ CPURISCVState *env, uint32_t desc) \
47
+{ \
48
+ uint32_t vm = vext_vm(desc); \
49
+ uint32_t vl = env->vl; \
50
+ uint32_t total_elems = \
51
+ vext_get_total_elems(env, desc, ESZ); \
52
+ uint32_t vta = vext_vta(desc); \
53
+ uint32_t vma = vext_vma(desc); \
54
+ uint32_t i; \
55
+ \
56
+ for (i = env->vstart; i < vl; i++) { \
57
+ if (!vm && !vext_elem_mask(v0, i)) { \
58
+ /* set masked-off elements to 1s */ \
59
+ vext_set_elems_1s(vd, vma, i * ESZ, \
60
+ (i + 1) * ESZ); \
61
+ continue; \
62
+ } \
63
+ do_##NAME(vd, vs2, i); \
64
+ } \
65
+ env->vstart = 0; \
66
+ /* set tail elements to 1s */ \
67
+ vext_set_elems_1s(vd, vta, vl * ESZ, \
68
+ total_elems * ESZ); \
69
+}
70
+
71
/* operation of two vector elements */
72
typedef void opivv2_fn(void *vd, void *vs1, void *vs2, int i);
73
74
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, \
75
do_##NAME, ESZ); \
76
}
77
78
+/* Three of the widening shortening macros: */
79
+/* (TD, T1, T2, TX1, TX2) */
80
+#define WOP_UUU_B uint16_t, uint8_t, uint8_t, uint16_t, uint16_t
81
+#define WOP_UUU_H uint32_t, uint16_t, uint16_t, uint32_t, uint32_t
82
+#define WOP_UUU_W uint64_t, uint32_t, uint32_t, uint64_t, uint64_t
83
+
84
#endif /* TARGET_RISCV_VECTOR_INTERNALS_H */
85
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/riscv/vector_helper.c
88
+++ b/target/riscv/vector_helper.c
89
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
90
#define OP_SUS_H int16_t, uint16_t, int16_t, uint16_t, int16_t
91
#define OP_SUS_W int32_t, uint32_t, int32_t, uint32_t, int32_t
92
#define OP_SUS_D int64_t, uint64_t, int64_t, uint64_t, int64_t
93
-#define WOP_UUU_B uint16_t, uint8_t, uint8_t, uint16_t, uint16_t
94
-#define WOP_UUU_H uint32_t, uint16_t, uint16_t, uint32_t, uint32_t
95
-#define WOP_UUU_W uint64_t, uint32_t, uint32_t, uint64_t, uint64_t
96
#define WOP_SSS_B int16_t, int8_t, int8_t, int16_t, int16_t
97
#define WOP_SSS_H int32_t, int16_t, int16_t, int32_t, int32_t
98
#define WOP_SSS_W int64_t, int32_t, int32_t, int64_t, int64_t
99
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_VF(vfwnmsac_vf_h, 4)
100
GEN_VEXT_VF(vfwnmsac_vf_w, 8)
101
102
/* Vector Floating-Point Square-Root Instruction */
103
-/* (TD, T2, TX2) */
104
-#define OP_UU_H uint16_t, uint16_t, uint16_t
105
-#define OP_UU_W uint32_t, uint32_t, uint32_t
106
-#define OP_UU_D uint64_t, uint64_t, uint64_t
107
-
108
#define OPFVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
109
static void do_##NAME(void *vd, void *vs2, int i, \
110
CPURISCVState *env) \
111
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_CMP_VF(vmfge_vf_w, uint32_t, H4, vmfge32)
112
GEN_VEXT_CMP_VF(vmfge_vf_d, uint64_t, H8, vmfge64)
113
114
/* Vector Floating-Point Classify Instruction */
115
-#define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
116
-static void do_##NAME(void *vd, void *vs2, int i) \
117
-{ \
118
- TX2 s2 = *((T2 *)vs2 + HS2(i)); \
119
- *((TD *)vd + HD(i)) = OP(s2); \
120
-}
121
-
122
-#define GEN_VEXT_V(NAME, ESZ) \
123
-void HELPER(NAME)(void *vd, void *v0, void *vs2, \
124
- CPURISCVState *env, uint32_t desc) \
125
-{ \
126
- uint32_t vm = vext_vm(desc); \
127
- uint32_t vl = env->vl; \
128
- uint32_t total_elems = \
129
- vext_get_total_elems(env, desc, ESZ); \
130
- uint32_t vta = vext_vta(desc); \
131
- uint32_t vma = vext_vma(desc); \
132
- uint32_t i; \
133
- \
134
- for (i = env->vstart; i < vl; i++) { \
135
- if (!vm && !vext_elem_mask(v0, i)) { \
136
- /* set masked-off elements to 1s */ \
137
- vext_set_elems_1s(vd, vma, i * ESZ, \
138
- (i + 1) * ESZ); \
139
- continue; \
140
- } \
141
- do_##NAME(vd, vs2, i); \
142
- } \
143
- env->vstart = 0; \
144
- /* set tail elements to 1s */ \
145
- vext_set_elems_1s(vd, vta, vl * ESZ, \
146
- total_elems * ESZ); \
147
-}
148
-
149
target_ulong fclass_h(uint64_t frs1)
150
{
151
float16 f = frs1;
152
--
153
2.41.0
diff view generated by jsdifflib
1
This is the initial commit of the Ibex UART device. Serial TX is
1
From: Dickon Hood <dickon.hood@codethink.co.uk>
2
working, while RX has been implemeneted but untested.
3
2
4
This is based on the documentation from:
3
This commit adds support for the Zvbb vector-crypto extension, which
5
https://docs.opentitan.org/hw/ip/uart/doc/
4
consists of the following instructions:
6
5
6
* vrol.[vv,vx]
7
* vror.[vv,vx,vi]
8
* vbrev8.v
9
* vrev8.v
10
* vandn.[vv,vx]
11
* vbrev.v
12
* vclz.v
13
* vctz.v
14
* vcpop.v
15
* vwsll.[vv,vx,vi]
16
17
Translation functions are defined in
18
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
19
`target/riscv/vcrypto_helper.c`.
20
21
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
22
Co-authored-by: William Salmon <will.salmon@codethink.co.uk>
23
Co-authored-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
24
[max.chou@sifive.com: Fix imm mode of vror.vi]
25
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
26
Signed-off-by: William Salmon <will.salmon@codethink.co.uk>
27
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
28
Signed-off-by: Dickon Hood <dickon.hood@codethink.co.uk>
29
Signed-off-by: Max Chou <max.chou@sifive.com>
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>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: LIU Zhiwei<zhiwei_liu@c-sky.com>
9
---
34
---
10
include/hw/char/ibex_uart.h | 110 ++++++++
35
target/riscv/cpu_cfg.h | 1 +
11
hw/char/ibex_uart.c | 492 ++++++++++++++++++++++++++++++++++++
36
target/riscv/helper.h | 62 +++++++++
12
MAINTAINERS | 2 +
37
target/riscv/insn32.decode | 20 +++
13
hw/char/Makefile.objs | 1 +
38
target/riscv/cpu.c | 12 ++
14
hw/riscv/Kconfig | 4 +
39
target/riscv/vcrypto_helper.c | 138 +++++++++++++++++++
15
5 files changed, 609 insertions(+)
40
target/riscv/insn_trans/trans_rvvk.c.inc | 164 +++++++++++++++++++++++
16
create mode 100644 include/hw/char/ibex_uart.h
41
6 files changed, 397 insertions(+)
17
create mode 100644 hw/char/ibex_uart.c
18
42
19
diff --git a/include/hw/char/ibex_uart.h b/include/hw/char/ibex_uart.h
43
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
20
new file mode 100644
44
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX
45
--- a/target/riscv/cpu_cfg.h
22
--- /dev/null
46
+++ b/target/riscv/cpu_cfg.h
23
+++ b/include/hw/char/ibex_uart.h
47
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
48
bool ext_zve32f;
49
bool ext_zve64f;
50
bool ext_zve64d;
51
+ bool ext_zvbb;
52
bool ext_zvbc;
53
bool ext_zmmul;
54
bool ext_zvfbfmin;
55
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/riscv/helper.h
58
+++ b/target/riscv/helper.h
59
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vclmul_vv, void, ptr, ptr, ptr, ptr, env, i32)
60
DEF_HELPER_6(vclmul_vx, void, ptr, ptr, tl, ptr, env, i32)
61
DEF_HELPER_6(vclmulh_vv, void, ptr, ptr, ptr, ptr, env, i32)
62
DEF_HELPER_6(vclmulh_vx, void, ptr, ptr, tl, ptr, env, i32)
63
+
64
+DEF_HELPER_6(vror_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
65
+DEF_HELPER_6(vror_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
66
+DEF_HELPER_6(vror_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
67
+DEF_HELPER_6(vror_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
68
+
69
+DEF_HELPER_6(vror_vx_b, void, ptr, ptr, tl, ptr, env, i32)
70
+DEF_HELPER_6(vror_vx_h, void, ptr, ptr, tl, ptr, env, i32)
71
+DEF_HELPER_6(vror_vx_w, void, ptr, ptr, tl, ptr, env, i32)
72
+DEF_HELPER_6(vror_vx_d, void, ptr, ptr, tl, ptr, env, i32)
73
+
74
+DEF_HELPER_6(vrol_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
75
+DEF_HELPER_6(vrol_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
76
+DEF_HELPER_6(vrol_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
77
+DEF_HELPER_6(vrol_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
78
+
79
+DEF_HELPER_6(vrol_vx_b, void, ptr, ptr, tl, ptr, env, i32)
80
+DEF_HELPER_6(vrol_vx_h, void, ptr, ptr, tl, ptr, env, i32)
81
+DEF_HELPER_6(vrol_vx_w, void, ptr, ptr, tl, ptr, env, i32)
82
+DEF_HELPER_6(vrol_vx_d, void, ptr, ptr, tl, ptr, env, i32)
83
+
84
+DEF_HELPER_5(vrev8_v_b, void, ptr, ptr, ptr, env, i32)
85
+DEF_HELPER_5(vrev8_v_h, void, ptr, ptr, ptr, env, i32)
86
+DEF_HELPER_5(vrev8_v_w, void, ptr, ptr, ptr, env, i32)
87
+DEF_HELPER_5(vrev8_v_d, void, ptr, ptr, ptr, env, i32)
88
+DEF_HELPER_5(vbrev8_v_b, void, ptr, ptr, ptr, env, i32)
89
+DEF_HELPER_5(vbrev8_v_h, void, ptr, ptr, ptr, env, i32)
90
+DEF_HELPER_5(vbrev8_v_w, void, ptr, ptr, ptr, env, i32)
91
+DEF_HELPER_5(vbrev8_v_d, void, ptr, ptr, ptr, env, i32)
92
+DEF_HELPER_5(vbrev_v_b, void, ptr, ptr, ptr, env, i32)
93
+DEF_HELPER_5(vbrev_v_h, void, ptr, ptr, ptr, env, i32)
94
+DEF_HELPER_5(vbrev_v_w, void, ptr, ptr, ptr, env, i32)
95
+DEF_HELPER_5(vbrev_v_d, void, ptr, ptr, ptr, env, i32)
96
+
97
+DEF_HELPER_5(vclz_v_b, void, ptr, ptr, ptr, env, i32)
98
+DEF_HELPER_5(vclz_v_h, void, ptr, ptr, ptr, env, i32)
99
+DEF_HELPER_5(vclz_v_w, void, ptr, ptr, ptr, env, i32)
100
+DEF_HELPER_5(vclz_v_d, void, ptr, ptr, ptr, env, i32)
101
+DEF_HELPER_5(vctz_v_b, void, ptr, ptr, ptr, env, i32)
102
+DEF_HELPER_5(vctz_v_h, void, ptr, ptr, ptr, env, i32)
103
+DEF_HELPER_5(vctz_v_w, void, ptr, ptr, ptr, env, i32)
104
+DEF_HELPER_5(vctz_v_d, void, ptr, ptr, ptr, env, i32)
105
+DEF_HELPER_5(vcpop_v_b, void, ptr, ptr, ptr, env, i32)
106
+DEF_HELPER_5(vcpop_v_h, void, ptr, ptr, ptr, env, i32)
107
+DEF_HELPER_5(vcpop_v_w, void, ptr, ptr, ptr, env, i32)
108
+DEF_HELPER_5(vcpop_v_d, void, ptr, ptr, ptr, env, i32)
109
+
110
+DEF_HELPER_6(vwsll_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
111
+DEF_HELPER_6(vwsll_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
112
+DEF_HELPER_6(vwsll_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
113
+DEF_HELPER_6(vwsll_vx_b, void, ptr, ptr, tl, ptr, env, i32)
114
+DEF_HELPER_6(vwsll_vx_h, void, ptr, ptr, tl, ptr, env, i32)
115
+DEF_HELPER_6(vwsll_vx_w, void, ptr, ptr, tl, ptr, env, i32)
116
+
117
+DEF_HELPER_6(vandn_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
118
+DEF_HELPER_6(vandn_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
119
+DEF_HELPER_6(vandn_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
120
+DEF_HELPER_6(vandn_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
121
+DEF_HELPER_6(vandn_vx_b, void, ptr, ptr, tl, ptr, env, i32)
122
+DEF_HELPER_6(vandn_vx_h, void, ptr, ptr, tl, ptr, env, i32)
123
+DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, i32)
124
+DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32)
125
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
126
index XXXXXXX..XXXXXXX 100644
127
--- a/target/riscv/insn32.decode
128
+++ b/target/riscv/insn32.decode
24
@@ -XXX,XX +XXX,XX @@
129
@@ -XXX,XX +XXX,XX @@
130
%imm_u 12:s20 !function=ex_shift_12
131
%imm_bs 30:2 !function=ex_shift_3
132
%imm_rnum 20:4
133
+%imm_z6 26:1 15:5
134
135
# Argument sets:
136
&empty
137
@@ -XXX,XX +XXX,XX @@
138
@r_vm ...... vm:1 ..... ..... ... ..... ....... &rmrr %rs2 %rs1 %rd
139
@r_vm_1 ...... . ..... ..... ... ..... ....... &rmrr vm=1 %rs2 %rs1 %rd
140
@r_vm_0 ...... . ..... ..... ... ..... ....... &rmrr vm=0 %rs2 %rs1 %rd
141
+@r2_zimm6 ..... . vm:1 ..... ..... ... ..... ....... &rmrr %rs2 rs1=%imm_z6 %rd
142
@r2_zimm11 . zimm:11 ..... ... ..... ....... %rs1 %rd
143
@r2_zimm10 .. zimm:10 ..... ... ..... ....... %rs1 %rd
144
@r2_s ....... ..... ..... ... ..... ....... %rs2 %rs1
145
@@ -XXX,XX +XXX,XX @@ vclmul_vv 001100 . ..... ..... 010 ..... 1010111 @r_vm
146
vclmul_vx 001100 . ..... ..... 110 ..... 1010111 @r_vm
147
vclmulh_vv 001101 . ..... ..... 010 ..... 1010111 @r_vm
148
vclmulh_vx 001101 . ..... ..... 110 ..... 1010111 @r_vm
149
+
150
+# *** Zvbb vector crypto extension ***
151
+vrol_vv 010101 . ..... ..... 000 ..... 1010111 @r_vm
152
+vrol_vx 010101 . ..... ..... 100 ..... 1010111 @r_vm
153
+vror_vv 010100 . ..... ..... 000 ..... 1010111 @r_vm
154
+vror_vx 010100 . ..... ..... 100 ..... 1010111 @r_vm
155
+vror_vi 01010. . ..... ..... 011 ..... 1010111 @r2_zimm6
156
+vbrev8_v 010010 . ..... 01000 010 ..... 1010111 @r2_vm
157
+vrev8_v 010010 . ..... 01001 010 ..... 1010111 @r2_vm
158
+vandn_vv 000001 . ..... ..... 000 ..... 1010111 @r_vm
159
+vandn_vx 000001 . ..... ..... 100 ..... 1010111 @r_vm
160
+vbrev_v 010010 . ..... 01010 010 ..... 1010111 @r2_vm
161
+vclz_v 010010 . ..... 01100 010 ..... 1010111 @r2_vm
162
+vctz_v 010010 . ..... 01101 010 ..... 1010111 @r2_vm
163
+vcpop_v 010010 . ..... 01110 010 ..... 1010111 @r2_vm
164
+vwsll_vv 110101 . ..... ..... 000 ..... 1010111 @r_vm
165
+vwsll_vx 110101 . ..... ..... 100 ..... 1010111 @r_vm
166
+vwsll_vi 110101 . ..... ..... 011 ..... 1010111 @r_vm
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;
181
}
182
183
+ /*
184
+ * In principle Zve*x would also suffice here, were they supported
185
+ * in qemu
186
+ */
187
+ if (cpu->cfg.ext_zvbb && !cpu->cfg.ext_zve32f) {
188
+ error_setg(errp,
189
+ "Vector crypto extensions require V or Zve* extensions");
190
+ return;
191
+ }
192
+
193
if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
194
error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
195
return;
196
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
197
DEFINE_PROP_BOOL("x-zvfbfwma", RISCVCPU, cfg.ext_zvfbfwma, false),
198
199
/* Vector cryptography extensions */
200
+ DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
201
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
202
203
DEFINE_PROP_END_OF_LIST(),
204
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
205
index XXXXXXX..XXXXXXX 100644
206
--- a/target/riscv/vcrypto_helper.c
207
+++ b/target/riscv/vcrypto_helper.c
208
@@ -XXX,XX +XXX,XX @@
209
#include "qemu/osdep.h"
210
#include "qemu/host-utils.h"
211
#include "qemu/bitops.h"
212
+#include "qemu/bswap.h"
213
#include "cpu.h"
214
#include "exec/memop.h"
215
#include "exec/exec-all.h"
216
@@ -XXX,XX +XXX,XX @@ RVVCALL(OPIVV2, vclmulh_vv, OP_UUU_D, H8, H8, H8, clmulh64)
217
GEN_VEXT_VV(vclmulh_vv, 8)
218
RVVCALL(OPIVX2, vclmulh_vx, OP_UUU_D, H8, H8, clmulh64)
219
GEN_VEXT_VX(vclmulh_vx, 8)
220
+
221
+RVVCALL(OPIVV2, vror_vv_b, OP_UUU_B, H1, H1, H1, ror8)
222
+RVVCALL(OPIVV2, vror_vv_h, OP_UUU_H, H2, H2, H2, ror16)
223
+RVVCALL(OPIVV2, vror_vv_w, OP_UUU_W, H4, H4, H4, ror32)
224
+RVVCALL(OPIVV2, vror_vv_d, OP_UUU_D, H8, H8, H8, ror64)
225
+GEN_VEXT_VV(vror_vv_b, 1)
226
+GEN_VEXT_VV(vror_vv_h, 2)
227
+GEN_VEXT_VV(vror_vv_w, 4)
228
+GEN_VEXT_VV(vror_vv_d, 8)
229
+
230
+RVVCALL(OPIVX2, vror_vx_b, OP_UUU_B, H1, H1, ror8)
231
+RVVCALL(OPIVX2, vror_vx_h, OP_UUU_H, H2, H2, ror16)
232
+RVVCALL(OPIVX2, vror_vx_w, OP_UUU_W, H4, H4, ror32)
233
+RVVCALL(OPIVX2, vror_vx_d, OP_UUU_D, H8, H8, ror64)
234
+GEN_VEXT_VX(vror_vx_b, 1)
235
+GEN_VEXT_VX(vror_vx_h, 2)
236
+GEN_VEXT_VX(vror_vx_w, 4)
237
+GEN_VEXT_VX(vror_vx_d, 8)
238
+
239
+RVVCALL(OPIVV2, vrol_vv_b, OP_UUU_B, H1, H1, H1, rol8)
240
+RVVCALL(OPIVV2, vrol_vv_h, OP_UUU_H, H2, H2, H2, rol16)
241
+RVVCALL(OPIVV2, vrol_vv_w, OP_UUU_W, H4, H4, H4, rol32)
242
+RVVCALL(OPIVV2, vrol_vv_d, OP_UUU_D, H8, H8, H8, rol64)
243
+GEN_VEXT_VV(vrol_vv_b, 1)
244
+GEN_VEXT_VV(vrol_vv_h, 2)
245
+GEN_VEXT_VV(vrol_vv_w, 4)
246
+GEN_VEXT_VV(vrol_vv_d, 8)
247
+
248
+RVVCALL(OPIVX2, vrol_vx_b, OP_UUU_B, H1, H1, rol8)
249
+RVVCALL(OPIVX2, vrol_vx_h, OP_UUU_H, H2, H2, rol16)
250
+RVVCALL(OPIVX2, vrol_vx_w, OP_UUU_W, H4, H4, rol32)
251
+RVVCALL(OPIVX2, vrol_vx_d, OP_UUU_D, H8, H8, rol64)
252
+GEN_VEXT_VX(vrol_vx_b, 1)
253
+GEN_VEXT_VX(vrol_vx_h, 2)
254
+GEN_VEXT_VX(vrol_vx_w, 4)
255
+GEN_VEXT_VX(vrol_vx_d, 8)
256
+
257
+static uint64_t brev8(uint64_t val)
258
+{
259
+ val = ((val & 0x5555555555555555ull) << 1) |
260
+ ((val & 0xAAAAAAAAAAAAAAAAull) >> 1);
261
+ val = ((val & 0x3333333333333333ull) << 2) |
262
+ ((val & 0xCCCCCCCCCCCCCCCCull) >> 2);
263
+ val = ((val & 0x0F0F0F0F0F0F0F0Full) << 4) |
264
+ ((val & 0xF0F0F0F0F0F0F0F0ull) >> 4);
265
+
266
+ return val;
267
+}
268
+
269
+RVVCALL(OPIVV1, vbrev8_v_b, OP_UU_B, H1, H1, brev8)
270
+RVVCALL(OPIVV1, vbrev8_v_h, OP_UU_H, H2, H2, brev8)
271
+RVVCALL(OPIVV1, vbrev8_v_w, OP_UU_W, H4, H4, brev8)
272
+RVVCALL(OPIVV1, vbrev8_v_d, OP_UU_D, H8, H8, brev8)
273
+GEN_VEXT_V(vbrev8_v_b, 1)
274
+GEN_VEXT_V(vbrev8_v_h, 2)
275
+GEN_VEXT_V(vbrev8_v_w, 4)
276
+GEN_VEXT_V(vbrev8_v_d, 8)
277
+
278
+#define DO_IDENTITY(a) (a)
279
+RVVCALL(OPIVV1, vrev8_v_b, OP_UU_B, H1, H1, DO_IDENTITY)
280
+RVVCALL(OPIVV1, vrev8_v_h, OP_UU_H, H2, H2, bswap16)
281
+RVVCALL(OPIVV1, vrev8_v_w, OP_UU_W, H4, H4, bswap32)
282
+RVVCALL(OPIVV1, vrev8_v_d, OP_UU_D, H8, H8, bswap64)
283
+GEN_VEXT_V(vrev8_v_b, 1)
284
+GEN_VEXT_V(vrev8_v_h, 2)
285
+GEN_VEXT_V(vrev8_v_w, 4)
286
+GEN_VEXT_V(vrev8_v_d, 8)
287
+
288
+#define DO_ANDN(a, b) ((a) & ~(b))
289
+RVVCALL(OPIVV2, vandn_vv_b, OP_UUU_B, H1, H1, H1, DO_ANDN)
290
+RVVCALL(OPIVV2, vandn_vv_h, OP_UUU_H, H2, H2, H2, DO_ANDN)
291
+RVVCALL(OPIVV2, vandn_vv_w, OP_UUU_W, H4, H4, H4, DO_ANDN)
292
+RVVCALL(OPIVV2, vandn_vv_d, OP_UUU_D, H8, H8, H8, DO_ANDN)
293
+GEN_VEXT_VV(vandn_vv_b, 1)
294
+GEN_VEXT_VV(vandn_vv_h, 2)
295
+GEN_VEXT_VV(vandn_vv_w, 4)
296
+GEN_VEXT_VV(vandn_vv_d, 8)
297
+
298
+RVVCALL(OPIVX2, vandn_vx_b, OP_UUU_B, H1, H1, DO_ANDN)
299
+RVVCALL(OPIVX2, vandn_vx_h, OP_UUU_H, H2, H2, DO_ANDN)
300
+RVVCALL(OPIVX2, vandn_vx_w, OP_UUU_W, H4, H4, DO_ANDN)
301
+RVVCALL(OPIVX2, vandn_vx_d, OP_UUU_D, H8, H8, DO_ANDN)
302
+GEN_VEXT_VX(vandn_vx_b, 1)
303
+GEN_VEXT_VX(vandn_vx_h, 2)
304
+GEN_VEXT_VX(vandn_vx_w, 4)
305
+GEN_VEXT_VX(vandn_vx_d, 8)
306
+
307
+RVVCALL(OPIVV1, vbrev_v_b, OP_UU_B, H1, H1, revbit8)
308
+RVVCALL(OPIVV1, vbrev_v_h, OP_UU_H, H2, H2, revbit16)
309
+RVVCALL(OPIVV1, vbrev_v_w, OP_UU_W, H4, H4, revbit32)
310
+RVVCALL(OPIVV1, vbrev_v_d, OP_UU_D, H8, H8, revbit64)
311
+GEN_VEXT_V(vbrev_v_b, 1)
312
+GEN_VEXT_V(vbrev_v_h, 2)
313
+GEN_VEXT_V(vbrev_v_w, 4)
314
+GEN_VEXT_V(vbrev_v_d, 8)
315
+
316
+RVVCALL(OPIVV1, vclz_v_b, OP_UU_B, H1, H1, clz8)
317
+RVVCALL(OPIVV1, vclz_v_h, OP_UU_H, H2, H2, clz16)
318
+RVVCALL(OPIVV1, vclz_v_w, OP_UU_W, H4, H4, clz32)
319
+RVVCALL(OPIVV1, vclz_v_d, OP_UU_D, H8, H8, clz64)
320
+GEN_VEXT_V(vclz_v_b, 1)
321
+GEN_VEXT_V(vclz_v_h, 2)
322
+GEN_VEXT_V(vclz_v_w, 4)
323
+GEN_VEXT_V(vclz_v_d, 8)
324
+
325
+RVVCALL(OPIVV1, vctz_v_b, OP_UU_B, H1, H1, ctz8)
326
+RVVCALL(OPIVV1, vctz_v_h, OP_UU_H, H2, H2, ctz16)
327
+RVVCALL(OPIVV1, vctz_v_w, OP_UU_W, H4, H4, ctz32)
328
+RVVCALL(OPIVV1, vctz_v_d, OP_UU_D, H8, H8, ctz64)
329
+GEN_VEXT_V(vctz_v_b, 1)
330
+GEN_VEXT_V(vctz_v_h, 2)
331
+GEN_VEXT_V(vctz_v_w, 4)
332
+GEN_VEXT_V(vctz_v_d, 8)
333
+
334
+RVVCALL(OPIVV1, vcpop_v_b, OP_UU_B, H1, H1, ctpop8)
335
+RVVCALL(OPIVV1, vcpop_v_h, OP_UU_H, H2, H2, ctpop16)
336
+RVVCALL(OPIVV1, vcpop_v_w, OP_UU_W, H4, H4, ctpop32)
337
+RVVCALL(OPIVV1, vcpop_v_d, OP_UU_D, H8, H8, ctpop64)
338
+GEN_VEXT_V(vcpop_v_b, 1)
339
+GEN_VEXT_V(vcpop_v_h, 2)
340
+GEN_VEXT_V(vcpop_v_w, 4)
341
+GEN_VEXT_V(vcpop_v_d, 8)
342
+
343
+#define DO_SLL(N, M) (N << (M & (sizeof(N) * 8 - 1)))
344
+RVVCALL(OPIVV2, vwsll_vv_b, WOP_UUU_B, H2, H1, H1, DO_SLL)
345
+RVVCALL(OPIVV2, vwsll_vv_h, WOP_UUU_H, H4, H2, H2, DO_SLL)
346
+RVVCALL(OPIVV2, vwsll_vv_w, WOP_UUU_W, H8, H4, H4, DO_SLL)
347
+GEN_VEXT_VV(vwsll_vv_b, 2)
348
+GEN_VEXT_VV(vwsll_vv_h, 4)
349
+GEN_VEXT_VV(vwsll_vv_w, 8)
350
+
351
+RVVCALL(OPIVX2, vwsll_vx_b, WOP_UUU_B, H2, H1, DO_SLL)
352
+RVVCALL(OPIVX2, vwsll_vx_h, WOP_UUU_H, H4, H2, DO_SLL)
353
+RVVCALL(OPIVX2, vwsll_vx_w, WOP_UUU_W, H8, H4, DO_SLL)
354
+GEN_VEXT_VX(vwsll_vx_b, 2)
355
+GEN_VEXT_VX(vwsll_vx_h, 4)
356
+GEN_VEXT_VX(vwsll_vx_w, 8)
357
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
358
index XXXXXXX..XXXXXXX 100644
359
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
360
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
361
@@ -XXX,XX +XXX,XX @@ static bool vclmul_vx_check(DisasContext *s, arg_rmrr *a)
362
363
GEN_VX_MASKED_TRANS(vclmul_vx, vclmul_vx_check)
364
GEN_VX_MASKED_TRANS(vclmulh_vx, vclmul_vx_check)
365
+
25
+/*
366
+/*
26
+ * QEMU lowRISC Ibex UART device
367
+ * Zvbb
27
+ *
28
+ * Copyright (c) 2020 Western Digital
29
+ *
30
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
31
+ * of this software and associated documentation files (the "Software"), to deal
32
+ * in the Software without restriction, including without limitation the rights
33
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
34
+ * copies of the Software, and to permit persons to whom the Software is
35
+ * furnished to do so, subject to the following conditions:
36
+ *
37
+ * The above copyright notice and this permission notice shall be included in
38
+ * all copies or substantial portions of the Software.
39
+ *
40
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
43
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
44
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
45
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
46
+ * THE SOFTWARE.
47
+ */
368
+ */
48
+
369
+
49
+#ifndef HW_IBEX_UART_H
370
+#define GEN_OPIVI_GVEC_TRANS_CHECK(NAME, IMM_MODE, OPIVX, SUF, CHECK) \
50
+#define HW_IBEX_UART_H
371
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
51
+
372
+ { \
52
+#include "hw/sysbus.h"
373
+ if (CHECK(s, a)) { \
53
+#include "chardev/char-fe.h"
374
+ static gen_helper_opivx *const fns[4] = { \
54
+#include "qemu/timer.h"
375
+ gen_helper_##OPIVX##_b, \
55
+
376
+ gen_helper_##OPIVX##_h, \
56
+#define IBEX_UART_INTR_STATE 0x00
377
+ gen_helper_##OPIVX##_w, \
57
+ #define INTR_STATE_TX_WATERMARK (1 << 0)
378
+ gen_helper_##OPIVX##_d, \
58
+ #define INTR_STATE_RX_WATERMARK (1 << 1)
379
+ }; \
59
+ #define INTR_STATE_TX_EMPTY (1 << 2)
380
+ return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew], \
60
+ #define INTR_STATE_RX_OVERFLOW (1 << 3)
381
+ IMM_MODE); \
61
+#define IBEX_UART_INTR_ENABLE 0x04
382
+ } \
62
+#define IBEX_UART_INTR_TEST 0x08
383
+ return false; \
63
+
384
+ }
64
+#define IBEX_UART_CTRL 0x0c
385
+
65
+ #define UART_CTRL_TX_ENABLE (1 << 0)
386
+#define GEN_OPIVV_GVEC_TRANS_CHECK(NAME, SUF, CHECK) \
66
+ #define UART_CTRL_RX_ENABLE (1 << 1)
387
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
67
+ #define UART_CTRL_NF (1 << 2)
388
+ { \
68
+ #define UART_CTRL_SLPBK (1 << 4)
389
+ if (CHECK(s, a)) { \
69
+ #define UART_CTRL_LLPBK (1 << 5)
390
+ static gen_helper_gvec_4_ptr *const fns[4] = { \
70
+ #define UART_CTRL_PARITY_EN (1 << 6)
391
+ gen_helper_##NAME##_b, \
71
+ #define UART_CTRL_PARITY_ODD (1 << 7)
392
+ gen_helper_##NAME##_h, \
72
+ #define UART_CTRL_RXBLVL (3 << 8)
393
+ gen_helper_##NAME##_w, \
73
+ #define UART_CTRL_NCO (0xFFFF << 16)
394
+ gen_helper_##NAME##_d, \
74
+
395
+ }; \
75
+#define IBEX_UART_STATUS 0x10
396
+ return do_opivv_gvec(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
76
+ #define UART_STATUS_TXFULL (1 << 0)
397
+ } \
77
+ #define UART_STATUS_RXFULL (1 << 1)
398
+ return false; \
78
+ #define UART_STATUS_TXEMPTY (1 << 2)
399
+ }
79
+ #define UART_STATUS_RXIDLE (1 << 4)
400
+
80
+ #define UART_STATUS_RXEMPTY (1 << 5)
401
+#define GEN_OPIVX_GVEC_SHIFT_TRANS_CHECK(NAME, SUF, CHECK) \
81
+
402
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
82
+#define IBEX_UART_RDATA 0x14
403
+ { \
83
+#define IBEX_UART_WDATA 0x18
404
+ if (CHECK(s, a)) { \
84
+
405
+ static gen_helper_opivx *const fns[4] = { \
85
+#define IBEX_UART_FIFO_CTRL 0x1c
406
+ gen_helper_##NAME##_b, \
86
+ #define FIFO_CTRL_RXRST (1 << 0)
407
+ gen_helper_##NAME##_h, \
87
+ #define FIFO_CTRL_TXRST (1 << 1)
408
+ gen_helper_##NAME##_w, \
88
+ #define FIFO_CTRL_RXILVL (7 << 2)
409
+ gen_helper_##NAME##_d, \
89
+ #define FIFO_CTRL_RXILVL_SHIFT (2)
410
+ }; \
90
+ #define FIFO_CTRL_TXILVL (3 << 5)
411
+ return do_opivx_gvec_shift(s, a, tcg_gen_gvec_##SUF, \
91
+ #define FIFO_CTRL_TXILVL_SHIFT (5)
412
+ fns[s->sew]); \
92
+
413
+ } \
93
+#define IBEX_UART_FIFO_STATUS 0x20
414
+ return false; \
94
+#define IBEX_UART_OVRD 0x24
415
+ }
95
+#define IBEX_UART_VAL 0x28
416
+
96
+#define IBEX_UART_TIMEOUT_CTRL 0x2c
417
+static bool zvbb_vv_check(DisasContext *s, arg_rmrr *a)
97
+
98
+#define IBEX_UART_TX_FIFO_SIZE 16
99
+
100
+#define TYPE_IBEX_UART "ibex-uart"
101
+#define IBEX_UART(obj) \
102
+ OBJECT_CHECK(IbexUartState, (obj), TYPE_IBEX_UART)
103
+
104
+typedef struct {
105
+ /* <private> */
106
+ SysBusDevice parent_obj;
107
+
108
+ /* <public> */
109
+ MemoryRegion mmio;
110
+
111
+ uint8_t tx_fifo[IBEX_UART_TX_FIFO_SIZE];
112
+ uint32_t tx_level;
113
+
114
+ QEMUTimer *fifo_trigger_handle;
115
+ uint64_t char_tx_time;
116
+
117
+ uint32_t uart_intr_state;
118
+ uint32_t uart_intr_enable;
119
+ uint32_t uart_ctrl;
120
+ uint32_t uart_status;
121
+ uint32_t uart_rdata;
122
+ uint32_t uart_fifo_ctrl;
123
+ uint32_t uart_fifo_status;
124
+ uint32_t uart_ovrd;
125
+ uint32_t uart_val;
126
+ uint32_t uart_timeout_ctrl;
127
+
128
+ CharBackend chr;
129
+ qemu_irq tx_watermark;
130
+ qemu_irq rx_watermark;
131
+ qemu_irq tx_empty;
132
+ qemu_irq rx_overflow;
133
+} IbexUartState;
134
+#endif /* HW_IBEX_UART_H */
135
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
136
new file mode 100644
137
index XXXXXXX..XXXXXXX
138
--- /dev/null
139
+++ b/hw/char/ibex_uart.c
140
@@ -XXX,XX +XXX,XX @@
141
+/*
142
+ * QEMU lowRISC Ibex UART device
143
+ *
144
+ * Copyright (c) 2020 Western Digital
145
+ *
146
+ * For details check the documentation here:
147
+ * https://docs.opentitan.org/hw/ip/uart/doc/
148
+ *
149
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
150
+ * of this software and associated documentation files (the "Software"), to deal
151
+ * in the Software without restriction, including without limitation the rights
152
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
153
+ * copies of the Software, and to permit persons to whom the Software is
154
+ * furnished to do so, subject to the following conditions:
155
+ *
156
+ * The above copyright notice and this permission notice shall be included in
157
+ * all copies or substantial portions of the Software.
158
+ *
159
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
160
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
161
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
162
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
163
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
164
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
165
+ * THE SOFTWARE.
166
+ */
167
+
168
+#include "qemu/osdep.h"
169
+#include "hw/char/ibex_uart.h"
170
+#include "hw/irq.h"
171
+#include "hw/qdev-properties.h"
172
+#include "migration/vmstate.h"
173
+#include "qemu/log.h"
174
+#include "qemu/module.h"
175
+
176
+static void ibex_uart_update_irqs(IbexUartState *s)
177
+{
418
+{
178
+ if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_TX_WATERMARK) {
419
+ return opivv_check(s, a) && s->cfg_ptr->ext_zvbb == true;
179
+ qemu_set_irq(s->tx_watermark, 1);
180
+ } else {
181
+ qemu_set_irq(s->tx_watermark, 0);
182
+ }
183
+
184
+ if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_RX_WATERMARK) {
185
+ qemu_set_irq(s->rx_watermark, 1);
186
+ } else {
187
+ qemu_set_irq(s->rx_watermark, 0);
188
+ }
189
+
190
+ if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_TX_EMPTY) {
191
+ qemu_set_irq(s->tx_empty, 1);
192
+ } else {
193
+ qemu_set_irq(s->tx_empty, 0);
194
+ }
195
+
196
+ if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_RX_OVERFLOW) {
197
+ qemu_set_irq(s->rx_overflow, 1);
198
+ } else {
199
+ qemu_set_irq(s->rx_overflow, 0);
200
+ }
201
+}
420
+}
202
+
421
+
203
+static int ibex_uart_can_receive(void *opaque)
422
+static bool zvbb_vx_check(DisasContext *s, arg_rmrr *a)
204
+{
423
+{
205
+ IbexUartState *s = opaque;
424
+ return opivx_check(s, a) && s->cfg_ptr->ext_zvbb == true;
206
+
207
+ if (s->uart_ctrl & UART_CTRL_RX_ENABLE) {
208
+ return 1;
209
+ }
210
+
211
+ return 0;
212
+}
425
+}
213
+
426
+
214
+static void ibex_uart_receive(void *opaque, const uint8_t *buf, int size)
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)
215
+{
486
+{
216
+ IbexUartState *s = opaque;
487
+ return s->cfg_ptr->ext_zvbb == true &&
217
+ uint8_t rx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_RXILVL)
488
+ require_rvv(s) &&
218
+ >> FIFO_CTRL_RXILVL_SHIFT;
489
+ vext_check_isa_ill(s) &&
219
+
490
+ vext_check_ss(s, a->rd, a->rs2, a->vm);
220
+ s->uart_rdata = *buf;
221
+
222
+ s->uart_status &= ~UART_STATUS_RXIDLE;
223
+ s->uart_status &= ~UART_STATUS_RXEMPTY;
224
+
225
+ if (size > rx_fifo_level) {
226
+ s->uart_intr_state |= INTR_STATE_RX_WATERMARK;
227
+ }
228
+
229
+ ibex_uart_update_irqs(s);
230
+}
491
+}
231
+
492
+
232
+static gboolean ibex_uart_xmit(GIOChannel *chan, GIOCondition cond,
493
+GEN_OPIV_TRANS(vbrev8_v, zvbb_opiv_check)
233
+ void *opaque)
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)
234
+{
501
+{
235
+ IbexUartState *s = opaque;
502
+ return s->cfg_ptr->ext_zvbb && opivv_widen_check(s, a);
236
+ uint8_t tx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_TXILVL)
237
+ >> FIFO_CTRL_TXILVL_SHIFT;
238
+ int ret;
239
+
240
+ /* instant drain the fifo when there's no back-end */
241
+ if (!qemu_chr_fe_backend_connected(&s->chr)) {
242
+ s->tx_level = 0;
243
+ return FALSE;
244
+ }
245
+
246
+ if (!s->tx_level) {
247
+ s->uart_status &= ~UART_STATUS_TXFULL;
248
+ s->uart_status |= UART_STATUS_TXEMPTY;
249
+ s->uart_intr_state |= INTR_STATE_TX_EMPTY;
250
+ s->uart_intr_state &= ~INTR_STATE_TX_WATERMARK;
251
+ ibex_uart_update_irqs(s);
252
+ return FALSE;
253
+ }
254
+
255
+ ret = qemu_chr_fe_write(&s->chr, s->tx_fifo, s->tx_level);
256
+
257
+ if (ret >= 0) {
258
+ s->tx_level -= ret;
259
+ memmove(s->tx_fifo, s->tx_fifo + ret, s->tx_level);
260
+ }
261
+
262
+ if (s->tx_level) {
263
+ guint r = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
264
+ ibex_uart_xmit, s);
265
+ if (!r) {
266
+ s->tx_level = 0;
267
+ return FALSE;
268
+ }
269
+ }
270
+
271
+ /* Clear the TX Full bit */
272
+ if (s->tx_level != IBEX_UART_TX_FIFO_SIZE) {
273
+ s->uart_status &= ~UART_STATUS_TXFULL;
274
+ }
275
+
276
+ /* Disable the TX_WATERMARK IRQ */
277
+ if (s->tx_level < tx_fifo_level) {
278
+ s->uart_intr_state &= ~INTR_STATE_TX_WATERMARK;
279
+ }
280
+
281
+ /* Set TX empty */
282
+ if (s->tx_level == 0) {
283
+ s->uart_status |= UART_STATUS_TXEMPTY;
284
+ s->uart_intr_state |= INTR_STATE_TX_EMPTY;
285
+ }
286
+
287
+ ibex_uart_update_irqs(s);
288
+ return FALSE;
289
+}
503
+}
290
+
504
+
291
+static void uart_write_tx_fifo(IbexUartState *s, const uint8_t *buf,
505
+static bool vwsll_vx_check(DisasContext *s, arg_rmrr *a)
292
+ int size)
293
+{
506
+{
294
+ uint64_t current_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
507
+ return s->cfg_ptr->ext_zvbb && opivx_widen_check(s, a);
295
+ uint8_t tx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_TXILVL)
296
+ >> FIFO_CTRL_TXILVL_SHIFT;
297
+
298
+ if (size > IBEX_UART_TX_FIFO_SIZE - s->tx_level) {
299
+ size = IBEX_UART_TX_FIFO_SIZE - s->tx_level;
300
+ qemu_log_mask(LOG_GUEST_ERROR, "ibex_uart: TX FIFO overflow");
301
+ }
302
+
303
+ memcpy(s->tx_fifo + s->tx_level, buf, size);
304
+ s->tx_level += size;
305
+
306
+ if (s->tx_level > 0) {
307
+ s->uart_status &= ~UART_STATUS_TXEMPTY;
308
+ }
309
+
310
+ if (s->tx_level >= tx_fifo_level) {
311
+ s->uart_intr_state |= INTR_STATE_TX_WATERMARK;
312
+ ibex_uart_update_irqs(s);
313
+ }
314
+
315
+ if (s->tx_level == IBEX_UART_TX_FIFO_SIZE) {
316
+ s->uart_status |= UART_STATUS_TXFULL;
317
+ }
318
+
319
+ timer_mod(s->fifo_trigger_handle, current_time +
320
+ (s->char_tx_time * 4));
321
+}
508
+}
322
+
509
+
323
+static void ibex_uart_reset(DeviceState *dev)
510
+/* OPIVI without GVEC IR */
324
+{
511
+#define GEN_OPIVI_WIDEN_TRANS(NAME, IMM_MODE, OPIVX, CHECK) \
325
+ IbexUartState *s = IBEX_UART(dev);
512
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
326
+
513
+ { \
327
+ s->uart_intr_state = 0x00000000;
514
+ if (CHECK(s, a)) { \
328
+ s->uart_intr_state = 0x00000000;
515
+ static gen_helper_opivx *const fns[3] = { \
329
+ s->uart_intr_enable = 0x00000000;
516
+ gen_helper_##OPIVX##_b, \
330
+ s->uart_ctrl = 0x00000000;
517
+ gen_helper_##OPIVX##_h, \
331
+ s->uart_status = 0x0000003c;
518
+ gen_helper_##OPIVX##_w, \
332
+ s->uart_rdata = 0x00000000;
519
+ }; \
333
+ s->uart_fifo_ctrl = 0x00000000;
520
+ return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s, \
334
+ s->uart_fifo_status = 0x00000000;
521
+ IMM_MODE); \
335
+ s->uart_ovrd = 0x00000000;
522
+ } \
336
+ s->uart_val = 0x00000000;
523
+ return false; \
337
+ s->uart_timeout_ctrl = 0x00000000;
524
+ }
338
+
525
+
339
+ s->tx_level = 0;
526
+GEN_OPIVV_WIDEN_TRANS(vwsll_vv, vwsll_vv_check)
340
+
527
+GEN_OPIVX_WIDEN_TRANS(vwsll_vx, vwsll_vx_check)
341
+ s->char_tx_time = (NANOSECONDS_PER_SECOND / 230400) * 10;
528
+GEN_OPIVI_WIDEN_TRANS(vwsll_vi, IMM_ZX, vwsll_vx, vwsll_vx_check)
342
+
343
+ ibex_uart_update_irqs(s);
344
+}
345
+
346
+static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
347
+ unsigned int size)
348
+{
349
+ IbexUartState *s = opaque;
350
+ uint64_t retvalue = 0;
351
+
352
+ switch (addr) {
353
+ case IBEX_UART_INTR_STATE:
354
+ retvalue = s->uart_intr_state;
355
+ break;
356
+ case IBEX_UART_INTR_ENABLE:
357
+ retvalue = s->uart_intr_enable;
358
+ break;
359
+ case IBEX_UART_INTR_TEST:
360
+ qemu_log_mask(LOG_GUEST_ERROR,
361
+ "%s: wdata is write only\n", __func__);
362
+ break;
363
+
364
+ case IBEX_UART_CTRL:
365
+ retvalue = s->uart_ctrl;
366
+ break;
367
+ case IBEX_UART_STATUS:
368
+ retvalue = s->uart_status;
369
+ break;
370
+
371
+ case IBEX_UART_RDATA:
372
+ retvalue = s->uart_rdata;
373
+ if (s->uart_ctrl & UART_CTRL_RX_ENABLE) {
374
+ qemu_chr_fe_accept_input(&s->chr);
375
+
376
+ s->uart_status |= UART_STATUS_RXIDLE;
377
+ s->uart_status |= UART_STATUS_RXEMPTY;
378
+ }
379
+ break;
380
+ case IBEX_UART_WDATA:
381
+ qemu_log_mask(LOG_GUEST_ERROR,
382
+ "%s: wdata is write only\n", __func__);
383
+ break;
384
+
385
+ case IBEX_UART_FIFO_CTRL:
386
+ retvalue = s->uart_fifo_ctrl;
387
+ break;
388
+ case IBEX_UART_FIFO_STATUS:
389
+ retvalue = s->uart_fifo_status;
390
+
391
+ retvalue |= s->tx_level & 0x1F;
392
+
393
+ qemu_log_mask(LOG_UNIMP,
394
+ "%s: RX fifos are not supported\n", __func__);
395
+ break;
396
+
397
+ case IBEX_UART_OVRD:
398
+ retvalue = s->uart_ovrd;
399
+ qemu_log_mask(LOG_UNIMP,
400
+ "%s: ovrd is not supported\n", __func__);
401
+ break;
402
+ case IBEX_UART_VAL:
403
+ retvalue = s->uart_val;
404
+ qemu_log_mask(LOG_UNIMP,
405
+ "%s: val is not supported\n", __func__);
406
+ break;
407
+ case IBEX_UART_TIMEOUT_CTRL:
408
+ retvalue = s->uart_timeout_ctrl;
409
+ qemu_log_mask(LOG_UNIMP,
410
+ "%s: timeout_ctrl is not supported\n", __func__);
411
+ break;
412
+ default:
413
+ qemu_log_mask(LOG_GUEST_ERROR,
414
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
415
+ return 0;
416
+ }
417
+
418
+ return retvalue;
419
+}
420
+
421
+static void ibex_uart_write(void *opaque, hwaddr addr,
422
+ uint64_t val64, unsigned int size)
423
+{
424
+ IbexUartState *s = opaque;
425
+ uint32_t value = val64;
426
+
427
+ switch (addr) {
428
+ case IBEX_UART_INTR_STATE:
429
+ /* Write 1 clear */
430
+ s->uart_intr_state &= ~value;
431
+ ibex_uart_update_irqs(s);
432
+ break;
433
+ case IBEX_UART_INTR_ENABLE:
434
+ s->uart_intr_enable = value;
435
+ ibex_uart_update_irqs(s);
436
+ break;
437
+ case IBEX_UART_INTR_TEST:
438
+ s->uart_intr_state |= value;
439
+ ibex_uart_update_irqs(s);
440
+ break;
441
+
442
+ case IBEX_UART_CTRL:
443
+ s->uart_ctrl = value;
444
+
445
+ if (value & UART_CTRL_NF) {
446
+ qemu_log_mask(LOG_UNIMP,
447
+ "%s: UART_CTRL_NF is not supported\n", __func__);
448
+ }
449
+ if (value & UART_CTRL_SLPBK) {
450
+ qemu_log_mask(LOG_UNIMP,
451
+ "%s: UART_CTRL_SLPBK is not supported\n", __func__);
452
+ }
453
+ if (value & UART_CTRL_LLPBK) {
454
+ qemu_log_mask(LOG_UNIMP,
455
+ "%s: UART_CTRL_LLPBK is not supported\n", __func__);
456
+ }
457
+ if (value & UART_CTRL_PARITY_EN) {
458
+ qemu_log_mask(LOG_UNIMP,
459
+ "%s: UART_CTRL_PARITY_EN is not supported\n",
460
+ __func__);
461
+ }
462
+ if (value & UART_CTRL_PARITY_ODD) {
463
+ qemu_log_mask(LOG_UNIMP,
464
+ "%s: UART_CTRL_PARITY_ODD is not supported\n",
465
+ __func__);
466
+ }
467
+ if (value & UART_CTRL_RXBLVL) {
468
+ qemu_log_mask(LOG_UNIMP,
469
+ "%s: UART_CTRL_RXBLVL is not supported\n", __func__);
470
+ }
471
+ if (value & UART_CTRL_NCO) {
472
+ uint64_t baud = ((value & UART_CTRL_NCO) >> 16);
473
+ baud *= 1000;
474
+ baud /= 2 ^ 20;
475
+
476
+ s->char_tx_time = (NANOSECONDS_PER_SECOND / baud) * 10;
477
+ }
478
+ break;
479
+ case IBEX_UART_STATUS:
480
+ qemu_log_mask(LOG_GUEST_ERROR,
481
+ "%s: status is read only\n", __func__);
482
+ break;
483
+
484
+ case IBEX_UART_RDATA:
485
+ qemu_log_mask(LOG_GUEST_ERROR,
486
+ "%s: rdata is read only\n", __func__);
487
+ break;
488
+ case IBEX_UART_WDATA:
489
+ uart_write_tx_fifo(s, (uint8_t *) &value, 1);
490
+ break;
491
+
492
+ case IBEX_UART_FIFO_CTRL:
493
+ s->uart_fifo_ctrl = value;
494
+
495
+ if (value & FIFO_CTRL_RXRST) {
496
+ qemu_log_mask(LOG_UNIMP,
497
+ "%s: RX fifos are not supported\n", __func__);
498
+ }
499
+ if (value & FIFO_CTRL_TXRST) {
500
+ s->tx_level = 0;
501
+ }
502
+ break;
503
+ case IBEX_UART_FIFO_STATUS:
504
+ qemu_log_mask(LOG_GUEST_ERROR,
505
+ "%s: fifo_status is read only\n", __func__);
506
+ break;
507
+
508
+ case IBEX_UART_OVRD:
509
+ s->uart_ovrd = value;
510
+ qemu_log_mask(LOG_UNIMP,
511
+ "%s: ovrd is not supported\n", __func__);
512
+ break;
513
+ case IBEX_UART_VAL:
514
+ qemu_log_mask(LOG_GUEST_ERROR,
515
+ "%s: val is read only\n", __func__);
516
+ break;
517
+ case IBEX_UART_TIMEOUT_CTRL:
518
+ s->uart_timeout_ctrl = value;
519
+ qemu_log_mask(LOG_UNIMP,
520
+ "%s: timeout_ctrl is not supported\n", __func__);
521
+ break;
522
+ default:
523
+ qemu_log_mask(LOG_GUEST_ERROR,
524
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
525
+ }
526
+}
527
+
528
+static void fifo_trigger_update(void *opaque)
529
+{
530
+ IbexUartState *s = opaque;
531
+
532
+ if (s->uart_ctrl & UART_CTRL_TX_ENABLE) {
533
+ ibex_uart_xmit(NULL, G_IO_OUT, s);
534
+ }
535
+}
536
+
537
+static const MemoryRegionOps ibex_uart_ops = {
538
+ .read = ibex_uart_read,
539
+ .write = ibex_uart_write,
540
+ .endianness = DEVICE_NATIVE_ENDIAN,
541
+ .impl.min_access_size = 4,
542
+ .impl.max_access_size = 4,
543
+};
544
+
545
+static int ibex_uart_post_load(void *opaque, int version_id)
546
+{
547
+ IbexUartState *s = opaque;
548
+
549
+ ibex_uart_update_irqs(s);
550
+ return 0;
551
+}
552
+
553
+static const VMStateDescription vmstate_ibex_uart = {
554
+ .name = TYPE_IBEX_UART,
555
+ .version_id = 1,
556
+ .minimum_version_id = 1,
557
+ .post_load = ibex_uart_post_load,
558
+ .fields = (VMStateField[]) {
559
+ VMSTATE_UINT8_ARRAY(tx_fifo, IbexUartState,
560
+ IBEX_UART_TX_FIFO_SIZE),
561
+ VMSTATE_UINT32(tx_level, IbexUartState),
562
+ VMSTATE_UINT64(char_tx_time, IbexUartState),
563
+ VMSTATE_TIMER_PTR(fifo_trigger_handle, IbexUartState),
564
+ VMSTATE_UINT32(uart_intr_state, IbexUartState),
565
+ VMSTATE_UINT32(uart_intr_enable, IbexUartState),
566
+ VMSTATE_UINT32(uart_ctrl, IbexUartState),
567
+ VMSTATE_UINT32(uart_status, IbexUartState),
568
+ VMSTATE_UINT32(uart_rdata, IbexUartState),
569
+ VMSTATE_UINT32(uart_fifo_ctrl, IbexUartState),
570
+ VMSTATE_UINT32(uart_fifo_status, IbexUartState),
571
+ VMSTATE_UINT32(uart_ovrd, IbexUartState),
572
+ VMSTATE_UINT32(uart_val, IbexUartState),
573
+ VMSTATE_UINT32(uart_timeout_ctrl, IbexUartState),
574
+ VMSTATE_END_OF_LIST()
575
+ }
576
+};
577
+
578
+static Property ibex_uart_properties[] = {
579
+ DEFINE_PROP_CHR("chardev", IbexUartState, chr),
580
+ DEFINE_PROP_END_OF_LIST(),
581
+};
582
+
583
+static void ibex_uart_init(Object *obj)
584
+{
585
+ IbexUartState *s = IBEX_UART(obj);
586
+
587
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_watermark);
588
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->rx_watermark);
589
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_empty);
590
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->rx_overflow);
591
+
592
+ memory_region_init_io(&s->mmio, obj, &ibex_uart_ops, s,
593
+ TYPE_IBEX_UART, 0x400);
594
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
595
+}
596
+
597
+static void ibex_uart_realize(DeviceState *dev, Error **errp)
598
+{
599
+ IbexUartState *s = IBEX_UART(dev);
600
+
601
+ s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
602
+ fifo_trigger_update, s);
603
+
604
+ qemu_chr_fe_set_handlers(&s->chr, ibex_uart_can_receive,
605
+ ibex_uart_receive, NULL, NULL,
606
+ s, NULL, true);
607
+}
608
+
609
+static void ibex_uart_class_init(ObjectClass *klass, void *data)
610
+{
611
+ DeviceClass *dc = DEVICE_CLASS(klass);
612
+
613
+ dc->reset = ibex_uart_reset;
614
+ dc->realize = ibex_uart_realize;
615
+ dc->vmsd = &vmstate_ibex_uart;
616
+ device_class_set_props(dc, ibex_uart_properties);
617
+}
618
+
619
+static const TypeInfo ibex_uart_info = {
620
+ .name = TYPE_IBEX_UART,
621
+ .parent = TYPE_SYS_BUS_DEVICE,
622
+ .instance_size = sizeof(IbexUartState),
623
+ .instance_init = ibex_uart_init,
624
+ .class_init = ibex_uart_class_init,
625
+};
626
+
627
+static void ibex_uart_register_types(void)
628
+{
629
+ type_register_static(&ibex_uart_info);
630
+}
631
+
632
+type_init(ibex_uart_register_types)
633
diff --git a/MAINTAINERS b/MAINTAINERS
634
index XXXXXXX..XXXXXXX 100644
635
--- a/MAINTAINERS
636
+++ b/MAINTAINERS
637
@@ -XXX,XX +XXX,XX @@ M: Alistair Francis <Alistair.Francis@wdc.com>
638
L: qemu-riscv@nongnu.org
639
S: Supported
640
F: hw/riscv/opentitan.c
641
+F: hw/char/ibex_uart.c
642
F: include/hw/riscv/opentitan.h
643
+F: include/hw/char/ibex_uart.h
644
645
SH4 Machines
646
------------
647
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
648
index XXXXXXX..XXXXXXX 100644
649
--- a/hw/char/Makefile.objs
650
+++ b/hw/char/Makefile.objs
651
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_VIRTIO_SERIAL) += virtio-console.o
652
common-obj-$(CONFIG_XILINX) += xilinx_uartlite.o
653
common-obj-$(CONFIG_XEN) += xen_console.o
654
common-obj-$(CONFIG_CADENCE) += cadence_uart.o
655
+common-obj-$(CONFIG_IBEX) += ibex_uart.o
656
657
common-obj-$(CONFIG_EXYNOS4) += exynos4210_uart.o
658
common-obj-$(CONFIG_COLDFIRE) += mcf_uart.o
659
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
660
index XXXXXXX..XXXXXXX 100644
661
--- a/hw/riscv/Kconfig
662
+++ b/hw/riscv/Kconfig
663
@@ -XXX,XX +XXX,XX @@ config HTIF
664
config HART
665
bool
666
667
+config IBEX
668
+ bool
669
+
670
config SIFIVE
671
bool
672
select MSI_NONBROKEN
673
@@ -XXX,XX +XXX,XX @@ config SPIKE
674
675
config OPENTITAN
676
bool
677
+ select IBEX
678
select HART
679
select UNIMP
680
681
--
529
--
682
2.27.0
530
2.41.0
683
684
diff view generated by jsdifflib
New patch
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
1
2
3
This commit adds support for the Zvkned vector-crypto extension, which
4
consists of the following instructions:
5
6
* vaesef.[vv,vs]
7
* vaesdf.[vv,vs]
8
* vaesdm.[vv,vs]
9
* vaesz.vs
10
* vaesem.[vv,vs]
11
* vaeskf1.vi
12
* vaeskf2.vi
13
14
Translation functions are defined in
15
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
16
`target/riscv/vcrypto_helper.c`.
17
18
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
19
Co-authored-by: William Salmon <will.salmon@codethink.co.uk>
20
[max.chou@sifive.com: Replaced vstart checking by TCG op]
21
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
22
Signed-off-by: William Salmon <will.salmon@codethink.co.uk>
23
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
24
Signed-off-by: Max Chou <max.chou@sifive.com>
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>
32
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
---
34
target/riscv/cpu_cfg.h | 1 +
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(-)
41
42
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/riscv/cpu_cfg.h
45
+++ b/target/riscv/cpu_cfg.h
46
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
47
bool ext_zve64d;
48
bool ext_zvbb;
49
bool ext_zvbc;
50
+ bool ext_zvkned;
51
bool ext_zmmul;
52
bool ext_zvfbfmin;
53
bool ext_zvfbfwma;
54
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/riscv/helper.h
57
+++ b/target/riscv/helper.h
58
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vandn_vx_b, void, ptr, ptr, tl, ptr, env, i32)
59
DEF_HELPER_6(vandn_vx_h, void, ptr, ptr, tl, ptr, env, i32)
60
DEF_HELPER_6(vandn_vx_w, void, ptr, ptr, tl, ptr, env, i32)
61
DEF_HELPER_6(vandn_vx_d, void, ptr, ptr, tl, ptr, env, i32)
62
+
63
+DEF_HELPER_2(egs_check, void, i32, env)
64
+
65
+DEF_HELPER_4(vaesef_vv, void, ptr, ptr, env, i32)
66
+DEF_HELPER_4(vaesef_vs, void, ptr, ptr, env, i32)
67
+DEF_HELPER_4(vaesdf_vv, void, ptr, ptr, env, i32)
68
+DEF_HELPER_4(vaesdf_vs, void, ptr, ptr, env, i32)
69
+DEF_HELPER_4(vaesem_vv, void, ptr, ptr, env, i32)
70
+DEF_HELPER_4(vaesem_vs, void, ptr, ptr, env, i32)
71
+DEF_HELPER_4(vaesdm_vv, void, ptr, ptr, env, i32)
72
+DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
73
+DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
74
+DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
75
+DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
76
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/riscv/insn32.decode
79
+++ b/target/riscv/insn32.decode
80
@@ -XXX,XX +XXX,XX @@
81
@r_rm ....... ..... ..... ... ..... ....... %rs2 %rs1 %rm %rd
82
@r2_rm ....... ..... ..... ... ..... ....... %rs1 %rm %rd
83
@r2 ....... ..... ..... ... ..... ....... &r2 %rs1 %rd
84
+@r2_vm_1 ...... . ..... ..... ... ..... ....... &rmr vm=1 %rs2 %rd
85
@r2_nfvm ... ... vm:1 ..... ..... ... ..... ....... &r2nfvm %nf %rs1 %rd
86
@r2_vm ...... vm:1 ..... ..... ... ..... ....... &rmr %rs2 %rd
87
@r1_vm ...... vm:1 ..... ..... ... ..... ....... %rd
88
@@ -XXX,XX +XXX,XX @@ vcpop_v 010010 . ..... 01110 010 ..... 1010111 @r2_vm
89
vwsll_vv 110101 . ..... ..... 000 ..... 1010111 @r_vm
90
vwsll_vx 110101 . ..... ..... 100 ..... 1010111 @r_vm
91
vwsll_vi 110101 . ..... ..... 011 ..... 1010111 @r_vm
92
+
93
+# *** Zvkned vector crypto extension ***
94
+vaesef_vv 101000 1 ..... 00011 010 ..... 1110111 @r2_vm_1
95
+vaesef_vs 101001 1 ..... 00011 010 ..... 1110111 @r2_vm_1
96
+vaesdf_vv 101000 1 ..... 00001 010 ..... 1110111 @r2_vm_1
97
+vaesdf_vs 101001 1 ..... 00001 010 ..... 1110111 @r2_vm_1
98
+vaesem_vv 101000 1 ..... 00010 010 ..... 1110111 @r2_vm_1
99
+vaesem_vs 101001 1 ..... 00010 010 ..... 1110111 @r2_vm_1
100
+vaesdm_vv 101000 1 ..... 00000 010 ..... 1110111 @r2_vm_1
101
+vaesdm_vs 101001 1 ..... 00000 010 ..... 1110111 @r2_vm_1
102
+vaesz_vs 101001 1 ..... 00111 010 ..... 1110111 @r2_vm_1
103
+vaeskf1_vi 100010 1 ..... ..... 010 ..... 1110111 @r_vm_1
104
+vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1
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)
506
--
507
2.41.0
diff view generated by jsdifflib
New patch
1
From: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
1
2
3
This commit adds support for the Zvknh vector-crypto extension, which
4
consists of the following instructions:
5
6
* vsha2ms.vv
7
* vsha2c[hl].vv
8
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Co-authored-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
14
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
15
[max.chou@sifive.com: Replaced vstart checking by TCG op]
16
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
17
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
18
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
19
Signed-off-by: Max Chou <max.chou@sifive.com>
20
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
21
[max.chou@sifive.com: Exposed x-zvknha & x-zvknhb properties]
22
[max.chou@sifive.com: Replaced SEW selection to happened during
23
translation]
24
Message-ID: <20230711165917.2629866-11-max.chou@sifive.com>
25
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
26
---
27
target/riscv/cpu_cfg.h | 2 +
28
target/riscv/helper.h | 6 +
29
target/riscv/insn32.decode | 5 +
30
target/riscv/cpu.c | 13 +-
31
target/riscv/vcrypto_helper.c | 238 +++++++++++++++++++++++
32
target/riscv/insn_trans/trans_rvvk.c.inc | 129 ++++++++++++
33
6 files changed, 390 insertions(+), 3 deletions(-)
34
35
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/cpu_cfg.h
38
+++ b/target/riscv/cpu_cfg.h
39
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
40
bool ext_zvbb;
41
bool ext_zvbc;
42
bool ext_zvkned;
43
+ bool ext_zvknha;
44
+ bool ext_zvknhb;
45
bool ext_zmmul;
46
bool ext_zvfbfmin;
47
bool ext_zvfbfwma;
48
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/helper.h
51
+++ b/target/riscv/helper.h
52
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_4(vaesdm_vs, void, ptr, ptr, env, i32)
53
DEF_HELPER_4(vaesz_vs, void, ptr, ptr, env, i32)
54
DEF_HELPER_5(vaeskf1_vi, void, ptr, ptr, i32, env, i32)
55
DEF_HELPER_5(vaeskf2_vi, void, ptr, ptr, i32, env, i32)
56
+
57
+DEF_HELPER_5(vsha2ms_vv, void, ptr, ptr, ptr, env, i32)
58
+DEF_HELPER_5(vsha2ch32_vv, void, ptr, ptr, ptr, env, i32)
59
+DEF_HELPER_5(vsha2ch64_vv, void, ptr, ptr, ptr, env, i32)
60
+DEF_HELPER_5(vsha2cl32_vv, void, ptr, ptr, ptr, env, i32)
61
+DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
62
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
63
index XXXXXXX..XXXXXXX 100644
64
--- a/target/riscv/insn32.decode
65
+++ b/target/riscv/insn32.decode
66
@@ -XXX,XX +XXX,XX @@ vaesdm_vs 101001 1 ..... 00000 010 ..... 1110111 @r2_vm_1
67
vaesz_vs 101001 1 ..... 00111 010 ..... 1110111 @r2_vm_1
68
vaeskf1_vi 100010 1 ..... ..... 010 ..... 1110111 @r_vm_1
69
vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1
70
+
71
+# *** Zvknh vector crypto extension ***
72
+vsha2ms_vv 101101 1 ..... ..... 010 ..... 1110111 @r_vm_1
73
+vsha2ch_vv 101110 1 ..... ..... 010 ..... 1110111 @r_vm_1
74
+vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
75
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/riscv/cpu.c
78
+++ b/target/riscv/cpu.c
79
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
80
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
81
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
82
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
83
+ ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
84
+ ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
85
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
86
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
87
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
88
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
89
* In principle Zve*x would also suffice here, were they supported
90
* in qemu
91
*/
92
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned) && !cpu->cfg.ext_zve32f) {
93
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha) &&
94
+ !cpu->cfg.ext_zve32f) {
95
error_setg(errp,
96
"Vector crypto extensions require V or Zve* extensions");
97
return;
98
}
99
100
- if (cpu->cfg.ext_zvbc && !cpu->cfg.ext_zve64f) {
101
- error_setg(errp, "Zvbc extension requires V or Zve64{f,d} extensions");
102
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
103
+ error_setg(
104
+ errp,
105
+ "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
106
return;
107
}
108
109
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
110
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
111
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
112
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
113
+ DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
114
+ DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
115
116
DEFINE_PROP_END_OF_LIST(),
117
};
118
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
119
index XXXXXXX..XXXXXXX 100644
120
--- a/target/riscv/vcrypto_helper.c
121
+++ b/target/riscv/vcrypto_helper.c
122
@@ -XXX,XX +XXX,XX @@ void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
123
/* set tail elements to 1s */
124
vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
125
}
126
+
127
+static inline uint32_t sig0_sha256(uint32_t x)
128
+{
129
+ return ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3);
130
+}
131
+
132
+static inline uint32_t sig1_sha256(uint32_t x)
133
+{
134
+ return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
135
+}
136
+
137
+static inline uint64_t sig0_sha512(uint64_t x)
138
+{
139
+ return ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7);
140
+}
141
+
142
+static inline uint64_t sig1_sha512(uint64_t x)
143
+{
144
+ return ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6);
145
+}
146
+
147
+static inline void vsha2ms_e32(uint32_t *vd, uint32_t *vs1, uint32_t *vs2)
148
+{
149
+ uint32_t res[4];
150
+ res[0] = sig1_sha256(vs1[H4(2)]) + vs2[H4(1)] + sig0_sha256(vd[H4(1)]) +
151
+ vd[H4(0)];
152
+ res[1] = sig1_sha256(vs1[H4(3)]) + vs2[H4(2)] + sig0_sha256(vd[H4(2)]) +
153
+ vd[H4(1)];
154
+ res[2] =
155
+ sig1_sha256(res[0]) + vs2[H4(3)] + sig0_sha256(vd[H4(3)]) + vd[H4(2)];
156
+ res[3] =
157
+ sig1_sha256(res[1]) + vs1[H4(0)] + sig0_sha256(vs2[H4(0)]) + vd[H4(3)];
158
+ vd[H4(3)] = res[3];
159
+ vd[H4(2)] = res[2];
160
+ vd[H4(1)] = res[1];
161
+ vd[H4(0)] = res[0];
162
+}
163
+
164
+static inline void vsha2ms_e64(uint64_t *vd, uint64_t *vs1, uint64_t *vs2)
165
+{
166
+ uint64_t res[4];
167
+ res[0] = sig1_sha512(vs1[2]) + vs2[1] + sig0_sha512(vd[1]) + vd[0];
168
+ res[1] = sig1_sha512(vs1[3]) + vs2[2] + sig0_sha512(vd[2]) + vd[1];
169
+ res[2] = sig1_sha512(res[0]) + vs2[3] + sig0_sha512(vd[3]) + vd[2];
170
+ res[3] = sig1_sha512(res[1]) + vs1[0] + sig0_sha512(vs2[0]) + vd[3];
171
+ vd[3] = res[3];
172
+ vd[2] = res[2];
173
+ vd[1] = res[1];
174
+ vd[0] = res[0];
175
+}
176
+
177
+void HELPER(vsha2ms_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
178
+ uint32_t desc)
179
+{
180
+ uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
181
+ uint32_t esz = sew == MO_32 ? 4 : 8;
182
+ uint32_t total_elems;
183
+ uint32_t vta = vext_vta(desc);
184
+
185
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
186
+ if (sew == MO_32) {
187
+ vsha2ms_e32(((uint32_t *)vd) + i * 4, ((uint32_t *)vs1) + i * 4,
188
+ ((uint32_t *)vs2) + i * 4);
189
+ } else {
190
+ /* If not 32 then SEW should be 64 */
191
+ vsha2ms_e64(((uint64_t *)vd) + i * 4, ((uint64_t *)vs1) + i * 4,
192
+ ((uint64_t *)vs2) + i * 4);
193
+ }
194
+ }
195
+ /* set tail elements to 1s */
196
+ total_elems = vext_get_total_elems(env, desc, esz);
197
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
198
+ env->vstart = 0;
199
+}
200
+
201
+static inline uint64_t sum0_64(uint64_t x)
202
+{
203
+ return ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39);
204
+}
205
+
206
+static inline uint32_t sum0_32(uint32_t x)
207
+{
208
+ return ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22);
209
+}
210
+
211
+static inline uint64_t sum1_64(uint64_t x)
212
+{
213
+ return ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41);
214
+}
215
+
216
+static inline uint32_t sum1_32(uint32_t x)
217
+{
218
+ return ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25);
219
+}
220
+
221
+#define ch(x, y, z) ((x & y) ^ ((~x) & z))
222
+
223
+#define maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
224
+
225
+static void vsha2c_64(uint64_t *vs2, uint64_t *vd, uint64_t *vs1)
226
+{
227
+ uint64_t a = vs2[3], b = vs2[2], e = vs2[1], f = vs2[0];
228
+ uint64_t c = vd[3], d = vd[2], g = vd[1], h = vd[0];
229
+ uint64_t W0 = vs1[0], W1 = vs1[1];
230
+ uint64_t T1 = h + sum1_64(e) + ch(e, f, g) + W0;
231
+ uint64_t T2 = sum0_64(a) + maj(a, b, c);
232
+
233
+ h = g;
234
+ g = f;
235
+ f = e;
236
+ e = d + T1;
237
+ d = c;
238
+ c = b;
239
+ b = a;
240
+ a = T1 + T2;
241
+
242
+ T1 = h + sum1_64(e) + ch(e, f, g) + W1;
243
+ T2 = sum0_64(a) + maj(a, b, c);
244
+ h = g;
245
+ g = f;
246
+ f = e;
247
+ e = d + T1;
248
+ d = c;
249
+ c = b;
250
+ b = a;
251
+ a = T1 + T2;
252
+
253
+ vd[0] = f;
254
+ vd[1] = e;
255
+ vd[2] = b;
256
+ vd[3] = a;
257
+}
258
+
259
+static void vsha2c_32(uint32_t *vs2, uint32_t *vd, uint32_t *vs1)
260
+{
261
+ uint32_t a = vs2[H4(3)], b = vs2[H4(2)], e = vs2[H4(1)], f = vs2[H4(0)];
262
+ uint32_t c = vd[H4(3)], d = vd[H4(2)], g = vd[H4(1)], h = vd[H4(0)];
263
+ uint32_t W0 = vs1[H4(0)], W1 = vs1[H4(1)];
264
+ uint32_t T1 = h + sum1_32(e) + ch(e, f, g) + W0;
265
+ uint32_t T2 = sum0_32(a) + maj(a, b, c);
266
+
267
+ h = g;
268
+ g = f;
269
+ f = e;
270
+ e = d + T1;
271
+ d = c;
272
+ c = b;
273
+ b = a;
274
+ a = T1 + T2;
275
+
276
+ T1 = h + sum1_32(e) + ch(e, f, g) + W1;
277
+ T2 = sum0_32(a) + maj(a, b, c);
278
+ h = g;
279
+ g = f;
280
+ f = e;
281
+ e = d + T1;
282
+ d = c;
283
+ c = b;
284
+ b = a;
285
+ a = T1 + T2;
286
+
287
+ vd[H4(0)] = f;
288
+ vd[H4(1)] = e;
289
+ vd[H4(2)] = b;
290
+ vd[H4(3)] = a;
291
+}
292
+
293
+void HELPER(vsha2ch32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
294
+ uint32_t desc)
295
+{
296
+ const uint32_t esz = 4;
297
+ uint32_t total_elems;
298
+ uint32_t vta = vext_vta(desc);
299
+
300
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
301
+ vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i,
302
+ ((uint32_t *)vs1) + 4 * i + 2);
303
+ }
304
+
305
+ /* set tail elements to 1s */
306
+ total_elems = vext_get_total_elems(env, desc, esz);
307
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
308
+ env->vstart = 0;
309
+}
310
+
311
+void HELPER(vsha2ch64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
312
+ uint32_t desc)
313
+{
314
+ const uint32_t esz = 8;
315
+ uint32_t total_elems;
316
+ uint32_t vta = vext_vta(desc);
317
+
318
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
319
+ vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i,
320
+ ((uint64_t *)vs1) + 4 * i + 2);
321
+ }
322
+
323
+ /* set tail elements to 1s */
324
+ total_elems = vext_get_total_elems(env, desc, esz);
325
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
326
+ env->vstart = 0;
327
+}
328
+
329
+void HELPER(vsha2cl32_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
330
+ uint32_t desc)
331
+{
332
+ const uint32_t esz = 4;
333
+ uint32_t total_elems;
334
+ uint32_t vta = vext_vta(desc);
335
+
336
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
337
+ vsha2c_32(((uint32_t *)vs2) + 4 * i, ((uint32_t *)vd) + 4 * i,
338
+ (((uint32_t *)vs1) + 4 * i));
339
+ }
340
+
341
+ /* set tail elements to 1s */
342
+ total_elems = vext_get_total_elems(env, desc, esz);
343
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
344
+ env->vstart = 0;
345
+}
346
+
347
+void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, CPURISCVState *env,
348
+ uint32_t desc)
349
+{
350
+ uint32_t esz = 8;
351
+ uint32_t total_elems;
352
+ uint32_t vta = vext_vta(desc);
353
+
354
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
355
+ vsha2c_64(((uint64_t *)vs2) + 4 * i, ((uint64_t *)vd) + 4 * i,
356
+ (((uint64_t *)vs1) + 4 * i));
357
+ }
358
+
359
+ /* set tail elements to 1s */
360
+ total_elems = vext_get_total_elems(env, desc, esz);
361
+ vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
362
+ env->vstart = 0;
363
+}
364
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
365
index XXXXXXX..XXXXXXX 100644
366
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
367
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
368
@@ -XXX,XX +XXX,XX @@ static bool vaeskf2_check(DisasContext *s, arg_vaeskf2_vi *a)
369
370
GEN_VI_UNMASKED_TRANS(vaeskf1_vi, vaeskf1_check, ZVKNED_EGS)
371
GEN_VI_UNMASKED_TRANS(vaeskf2_vi, vaeskf2_check, ZVKNED_EGS)
372
+
373
+/*
374
+ * Zvknh
375
+ */
376
+
377
+#define ZVKNH_EGS 4
378
+
379
+#define GEN_VV_UNMASKED_TRANS(NAME, CHECK, EGS) \
380
+ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
381
+ { \
382
+ if (CHECK(s, a)) { \
383
+ uint32_t data = 0; \
384
+ TCGLabel *over = gen_new_label(); \
385
+ TCGv_i32 egs; \
386
+ \
387
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) { \
388
+ /* save opcode for unwinding in case we throw an exception */ \
389
+ decode_save_opc(s); \
390
+ egs = tcg_constant_i32(EGS); \
391
+ gen_helper_egs_check(egs, cpu_env); \
392
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
393
+ } \
394
+ \
395
+ data = FIELD_DP32(data, VDATA, VM, a->vm); \
396
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
397
+ data = FIELD_DP32(data, VDATA, VTA, s->vta); \
398
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s); \
399
+ data = FIELD_DP32(data, VDATA, VMA, s->vma); \
400
+ \
401
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1), \
402
+ vreg_ofs(s, a->rs2), cpu_env, \
403
+ s->cfg_ptr->vlen / 8, s->cfg_ptr->vlen / 8, \
404
+ data, gen_helper_##NAME); \
405
+ \
406
+ mark_vs_dirty(s); \
407
+ gen_set_label(over); \
408
+ return true; \
409
+ } \
410
+ return false; \
411
+ }
412
+
413
+static bool vsha_check_sew(DisasContext *s)
414
+{
415
+ return (s->cfg_ptr->ext_zvknha == true && s->sew == MO_32) ||
416
+ (s->cfg_ptr->ext_zvknhb == true &&
417
+ (s->sew == MO_32 || s->sew == MO_64));
418
+}
419
+
420
+static bool vsha_check(DisasContext *s, arg_rmrr *a)
421
+{
422
+ int egw_bytes = ZVKNH_EGS << s->sew;
423
+ int mult = 1 << MAX(s->lmul, 0);
424
+ return opivv_check(s, a) &&
425
+ vsha_check_sew(s) &&
426
+ MAXSZ(s) >= egw_bytes &&
427
+ !is_overlapped(a->rd, mult, a->rs1, mult) &&
428
+ !is_overlapped(a->rd, mult, a->rs2, mult) &&
429
+ s->lmul >= 0;
430
+}
431
+
432
+GEN_VV_UNMASKED_TRANS(vsha2ms_vv, vsha_check, ZVKNH_EGS)
433
+
434
+static bool trans_vsha2cl_vv(DisasContext *s, arg_rmrr *a)
435
+{
436
+ if (vsha_check(s, a)) {
437
+ uint32_t data = 0;
438
+ TCGLabel *over = gen_new_label();
439
+ TCGv_i32 egs;
440
+
441
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
442
+ /* save opcode for unwinding in case we throw an exception */
443
+ decode_save_opc(s);
444
+ egs = tcg_constant_i32(ZVKNH_EGS);
445
+ gen_helper_egs_check(egs, cpu_env);
446
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
447
+ }
448
+
449
+ data = FIELD_DP32(data, VDATA, VM, a->vm);
450
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
451
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
452
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
453
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
454
+
455
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
456
+ vreg_ofs(s, a->rs2), cpu_env, s->cfg_ptr->vlen / 8,
457
+ s->cfg_ptr->vlen / 8, data,
458
+ s->sew == MO_32 ?
459
+ gen_helper_vsha2cl32_vv : gen_helper_vsha2cl64_vv);
460
+
461
+ mark_vs_dirty(s);
462
+ gen_set_label(over);
463
+ return true;
464
+ }
465
+ return false;
466
+}
467
+
468
+static bool trans_vsha2ch_vv(DisasContext *s, arg_rmrr *a)
469
+{
470
+ if (vsha_check(s, a)) {
471
+ uint32_t data = 0;
472
+ TCGLabel *over = gen_new_label();
473
+ TCGv_i32 egs;
474
+
475
+ if (!s->vstart_eq_zero || !s->vl_eq_vlmax) {
476
+ /* save opcode for unwinding in case we throw an exception */
477
+ decode_save_opc(s);
478
+ egs = tcg_constant_i32(ZVKNH_EGS);
479
+ gen_helper_egs_check(egs, cpu_env);
480
+ tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
481
+ }
482
+
483
+ data = FIELD_DP32(data, VDATA, VM, a->vm);
484
+ data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
485
+ data = FIELD_DP32(data, VDATA, VTA, s->vta);
486
+ data = FIELD_DP32(data, VDATA, VTA_ALL_1S, s->cfg_vta_all_1s);
487
+ data = FIELD_DP32(data, VDATA, VMA, s->vma);
488
+
489
+ tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
490
+ vreg_ofs(s, a->rs2), cpu_env, s->cfg_ptr->vlen / 8,
491
+ s->cfg_ptr->vlen / 8, data,
492
+ s->sew == MO_32 ?
493
+ gen_helper_vsha2ch32_vv : gen_helper_vsha2ch64_vv);
494
+
495
+ mark_vs_dirty(s);
496
+ gen_set_label(over);
497
+ return true;
498
+ }
499
+ return false;
500
+}
501
--
502
2.41.0
diff view generated by jsdifflib
1
Call the helper_hyp_tlb_flush() function on hfence instructions which
1
From: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
2
will generate an illegal insruction execption if we don't have
2
3
permission to flush the Hypervisor level TLBs.
3
This commit adds support for the Zvksh vector-crypto extension, which
4
4
consists of the following instructions:
5
6
* vsm3me.vv
7
* vsm3c.vi
8
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Co-authored-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
14
[max.chou@sifive.com: Replaced vstart checking by TCG op]
15
Signed-off-by: Kiran Ostrolenk <kiran.ostrolenk@codethink.co.uk>
16
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
17
Signed-off-by: Max Chou <max.chou@sifive.com>
18
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
19
[max.chou@sifive.com: Exposed x-zvksh property]
20
Message-ID: <20230711165917.2629866-12-max.chou@sifive.com>
5
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
---
22
---
8
target/riscv/helper.h | 5 ++++
23
target/riscv/cpu_cfg.h | 1 +
9
target/riscv/insn_trans/trans_rvh.inc.c | 32 +++++--------------------
24
target/riscv/helper.h | 3 +
10
target/riscv/op_helper.c | 13 ++++++++++
25
target/riscv/insn32.decode | 4 +
11
3 files changed, 24 insertions(+), 26 deletions(-)
26
target/riscv/cpu.c | 6 +-
12
27
target/riscv/vcrypto_helper.c | 134 +++++++++++++++++++++++
28
target/riscv/insn_trans/trans_rvvk.c.inc | 31 ++++++
29
6 files changed, 177 insertions(+), 2 deletions(-)
30
31
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/cpu_cfg.h
34
+++ b/target/riscv/cpu_cfg.h
35
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
36
bool ext_zvkned;
37
bool ext_zvknha;
38
bool ext_zvknhb;
39
+ bool ext_zvksh;
40
bool ext_zmmul;
41
bool ext_zvfbfmin;
42
bool ext_zvfbfwma;
13
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
43
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
14
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/helper.h
45
--- a/target/riscv/helper.h
16
+++ b/target/riscv/helper.h
46
+++ b/target/riscv/helper.h
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(mret, tl, env, tl)
47
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsha2ch32_vv, void, ptr, ptr, ptr, env, i32)
18
DEF_HELPER_1(wfi, void, env)
48
DEF_HELPER_5(vsha2ch64_vv, void, ptr, ptr, ptr, env, i32)
19
DEF_HELPER_1(tlb_flush, void, env)
49
DEF_HELPER_5(vsha2cl32_vv, void, ptr, ptr, ptr, env, i32)
20
#endif
50
DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
21
+
51
+
22
+/* Hypervisor functions */
52
+DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
23
+#ifndef CONFIG_USER_ONLY
53
+DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
24
+DEF_HELPER_1(hyp_tlb_flush, void, env)
54
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
25
+#endif
55
index XXXXXXX..XXXXXXX 100644
26
diff --git a/target/riscv/insn_trans/trans_rvh.inc.c b/target/riscv/insn_trans/trans_rvh.inc.c
56
--- a/target/riscv/insn32.decode
27
index XXXXXXX..XXXXXXX 100644
57
+++ b/target/riscv/insn32.decode
28
--- a/target/riscv/insn_trans/trans_rvh.inc.c
58
@@ -XXX,XX +XXX,XX @@ vaeskf2_vi 101010 1 ..... ..... 010 ..... 1110111 @r_vm_1
29
+++ b/target/riscv/insn_trans/trans_rvh.inc.c
59
vsha2ms_vv 101101 1 ..... ..... 010 ..... 1110111 @r_vm_1
30
@@ -XXX,XX +XXX,XX @@
60
vsha2ch_vv 101110 1 ..... ..... 010 ..... 1110111 @r_vm_1
31
61
vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
32
static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
62
+
33
{
63
+# *** Zvksh vector crypto extension ***
34
+ REQUIRE_EXT(ctx, RVH);
64
+vsm3me_vv 100000 1 ..... ..... 010 ..... 1110111 @r_vm_1
35
#ifndef CONFIG_USER_ONLY
65
+vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
36
- if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
66
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
37
- has_ext(ctx, RVH)) {
67
index XXXXXXX..XXXXXXX 100644
38
- /* Hpervisor extensions exist */
68
--- a/target/riscv/cpu.c
39
- /*
69
+++ b/target/riscv/cpu.c
40
- * if (env->priv == PRV_M ||
70
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
41
- * (env->priv == PRV_S &&
71
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
42
- * !riscv_cpu_virt_enabled(env) &&
72
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
43
- * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
73
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
44
- */
74
+ ISA_EXT_DATA_ENTRY(zvksh, PRIV_VERSION_1_12_0, ext_zvksh),
45
- gen_helper_tlb_flush(cpu_env);
75
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
46
- return true;
76
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
47
- /* } */
77
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
48
- }
78
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
49
+ gen_helper_hyp_tlb_flush(cpu_env);
79
* In principle Zve*x would also suffice here, were they supported
50
+ return true;
80
* in qemu
51
#endif
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
}
52
return false;
245
return false;
53
}
246
}
54
247
+
55
static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a)
248
+/*
56
{
249
+ * Zvksh
57
+ REQUIRE_EXT(ctx, RVH);
250
+ */
58
#ifndef CONFIG_USER_ONLY
251
+
59
- if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
252
+#define ZVKSH_EGS 8
60
- has_ext(ctx, RVH)) {
253
+
61
- /* Hpervisor extensions exist */
254
+static inline bool vsm3_check(DisasContext *s, arg_rmrr *a)
62
- /*
255
+{
63
- * if (env->priv == PRV_M ||
256
+ int egw_bytes = ZVKSH_EGS << s->sew;
64
- * (env->priv == PRV_S &&
257
+ int mult = 1 << MAX(s->lmul, 0);
65
- * !riscv_cpu_virt_enabled(env) &&
258
+ return s->cfg_ptr->ext_zvksh == true &&
66
- * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
259
+ require_rvv(s) &&
67
- */
260
+ vext_check_isa_ill(s) &&
68
- gen_helper_tlb_flush(cpu_env);
261
+ !is_overlapped(a->rd, mult, a->rs2, mult) &&
69
- return true;
262
+ MAXSZ(s) >= egw_bytes &&
70
- /* } */
263
+ s->sew == MO_32;
71
- }
264
+}
72
+ gen_helper_hyp_tlb_flush(cpu_env);
265
+
73
+ return true;
266
+static inline bool vsm3me_check(DisasContext *s, arg_rmrr *a)
74
#endif
267
+{
75
return false;
268
+ return vsm3_check(s, a) && vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm);
76
}
269
+}
77
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
270
+
78
index XXXXXXX..XXXXXXX 100644
271
+static inline bool vsm3c_check(DisasContext *s, arg_rmrr *a)
79
--- a/target/riscv/op_helper.c
272
+{
80
+++ b/target/riscv/op_helper.c
273
+ return vsm3_check(s, a) && vext_check_ss(s, a->rd, a->rs2, a->vm);
81
@@ -XXX,XX +XXX,XX @@ void helper_tlb_flush(CPURISCVState *env)
274
+}
82
}
275
+
83
}
276
+GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS)
84
277
+GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS)
85
+void helper_hyp_tlb_flush(CPURISCVState *env)
86
+{
87
+ CPUState *cs = env_cpu(env);
88
+
89
+ if (env->priv == PRV_M ||
90
+ (env->priv == PRV_S && !riscv_cpu_virt_enabled(env))) {
91
+ tlb_flush(cs);
92
+ return;
93
+ }
94
+
95
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
96
+}
97
+
98
#endif /* !CONFIG_USER_ONLY */
99
--
278
--
100
2.27.0
279
2.41.0
101
102
diff view generated by jsdifflib
New patch
1
1
From: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
2
3
This commit adds support for the Zvkg vector-crypto extension, which
4
consists of the following instructions:
5
6
* vgmul.vv
7
* vghsh.vv
8
9
Translation functions are defined in
10
`target/riscv/insn_trans/trans_rvvk.c.inc` and helpers are defined in
11
`target/riscv/vcrypto_helper.c`.
12
13
Co-authored-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
14
[max.chou@sifive.com: Replaced vstart checking by TCG op]
15
Signed-off-by: Lawrence Hunter <lawrence.hunter@codethink.co.uk>
16
Signed-off-by: Nazar Kazakov <nazar.kazakov@codethink.co.uk>
17
Signed-off-by: Max Chou <max.chou@sifive.com>
18
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
19
[max.chou@sifive.com: Exposed x-zvkg property]
20
[max.chou@sifive.com: Replaced uint by int for cross win32 build]
21
Message-ID: <20230711165917.2629866-13-max.chou@sifive.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
24
target/riscv/cpu_cfg.h | 1 +
25
target/riscv/helper.h | 3 +
26
target/riscv/insn32.decode | 4 ++
27
target/riscv/cpu.c | 6 +-
28
target/riscv/vcrypto_helper.c | 72 ++++++++++++++++++++++++
29
target/riscv/insn_trans/trans_rvvk.c.inc | 30 ++++++++++
30
6 files changed, 114 insertions(+), 2 deletions(-)
31
32
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/cpu_cfg.h
35
+++ b/target/riscv/cpu_cfg.h
36
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
37
bool ext_zve64d;
38
bool ext_zvbb;
39
bool ext_zvbc;
40
+ bool ext_zvkg;
41
bool ext_zvkned;
42
bool ext_zvknha;
43
bool ext_zvknhb;
44
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/riscv/helper.h
47
+++ b/target/riscv/helper.h
48
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsha2cl64_vv, void, ptr, ptr, ptr, env, i32)
49
50
DEF_HELPER_5(vsm3me_vv, void, ptr, ptr, ptr, env, i32)
51
DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
52
+
53
+DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
54
+DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
55
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/riscv/insn32.decode
58
+++ b/target/riscv/insn32.decode
59
@@ -XXX,XX +XXX,XX @@ vsha2cl_vv 101111 1 ..... ..... 010 ..... 1110111 @r_vm_1
60
# *** Zvksh vector crypto extension ***
61
vsm3me_vv 100000 1 ..... ..... 010 ..... 1110111 @r_vm_1
62
vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
63
+
64
+# *** Zvkg vector crypto extension ***
65
+vghsh_vv 101100 1 ..... ..... 010 ..... 1110111 @r_vm_1
66
+vgmul_vv 101000 1 ..... 10001 010 ..... 1110111 @r2_vm_1
67
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/riscv/cpu.c
70
+++ b/target/riscv/cpu.c
71
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
72
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
73
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
74
ISA_EXT_DATA_ENTRY(zvfhmin, PRIV_VERSION_1_12_0, ext_zvfhmin),
75
+ ISA_EXT_DATA_ENTRY(zvkg, PRIV_VERSION_1_12_0, ext_zvkg),
76
ISA_EXT_DATA_ENTRY(zvkned, PRIV_VERSION_1_12_0, ext_zvkned),
77
ISA_EXT_DATA_ENTRY(zvknha, PRIV_VERSION_1_12_0, ext_zvknha),
78
ISA_EXT_DATA_ENTRY(zvknhb, PRIV_VERSION_1_12_0, ext_zvknhb),
79
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
80
* In principle Zve*x would also suffice here, were they supported
81
* in qemu
82
*/
83
- if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha ||
84
- cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
85
+ if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkg || cpu->cfg.ext_zvkned ||
86
+ cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
87
error_setg(errp,
88
"Vector crypto extensions require V or Zve* extensions");
89
return;
90
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
91
/* Vector cryptography extensions */
92
DEFINE_PROP_BOOL("x-zvbb", RISCVCPU, cfg.ext_zvbb, false),
93
DEFINE_PROP_BOOL("x-zvbc", RISCVCPU, cfg.ext_zvbc, false),
94
+ DEFINE_PROP_BOOL("x-zvkg", RISCVCPU, cfg.ext_zvkg, false),
95
DEFINE_PROP_BOOL("x-zvkned", RISCVCPU, cfg.ext_zvkned, false),
96
DEFINE_PROP_BOOL("x-zvknha", RISCVCPU, cfg.ext_zvknha, false),
97
DEFINE_PROP_BOOL("x-zvknhb", RISCVCPU, cfg.ext_zvknhb, false),
98
diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/riscv/vcrypto_helper.c
101
+++ b/target/riscv/vcrypto_helper.c
102
@@ -XXX,XX +XXX,XX @@ void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
103
vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
104
env->vstart = 0;
105
}
106
+
107
+void HELPER(vghsh_vv)(void *vd_vptr, void *vs1_vptr, void *vs2_vptr,
108
+ CPURISCVState *env, uint32_t desc)
109
+{
110
+ uint64_t *vd = vd_vptr;
111
+ uint64_t *vs1 = vs1_vptr;
112
+ uint64_t *vs2 = vs2_vptr;
113
+ uint32_t vta = vext_vta(desc);
114
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
115
+
116
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
117
+ uint64_t Y[2] = {vd[i * 2 + 0], vd[i * 2 + 1]};
118
+ uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
119
+ uint64_t X[2] = {vs1[i * 2 + 0], vs1[i * 2 + 1]};
120
+ uint64_t Z[2] = {0, 0};
121
+
122
+ uint64_t S[2] = {brev8(Y[0] ^ X[0]), brev8(Y[1] ^ X[1])};
123
+
124
+ for (int j = 0; j < 128; j++) {
125
+ if ((S[j / 64] >> (j % 64)) & 1) {
126
+ Z[0] ^= H[0];
127
+ Z[1] ^= H[1];
128
+ }
129
+ bool reduce = ((H[1] >> 63) & 1);
130
+ H[1] = H[1] << 1 | H[0] >> 63;
131
+ H[0] = H[0] << 1;
132
+ if (reduce) {
133
+ H[0] ^= 0x87;
134
+ }
135
+ }
136
+
137
+ vd[i * 2 + 0] = brev8(Z[0]);
138
+ vd[i * 2 + 1] = brev8(Z[1]);
139
+ }
140
+ /* set tail elements to 1s */
141
+ vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
142
+ env->vstart = 0;
143
+}
144
+
145
+void HELPER(vgmul_vv)(void *vd_vptr, void *vs2_vptr, CPURISCVState *env,
146
+ uint32_t desc)
147
+{
148
+ uint64_t *vd = vd_vptr;
149
+ uint64_t *vs2 = vs2_vptr;
150
+ uint32_t vta = vext_vta(desc);
151
+ uint32_t total_elems = vext_get_total_elems(env, desc, 4);
152
+
153
+ for (uint32_t i = env->vstart / 4; i < env->vl / 4; i++) {
154
+ uint64_t Y[2] = {brev8(vd[i * 2 + 0]), brev8(vd[i * 2 + 1])};
155
+ uint64_t H[2] = {brev8(vs2[i * 2 + 0]), brev8(vs2[i * 2 + 1])};
156
+ uint64_t Z[2] = {0, 0};
157
+
158
+ for (int j = 0; j < 128; j++) {
159
+ if ((Y[j / 64] >> (j % 64)) & 1) {
160
+ Z[0] ^= H[0];
161
+ Z[1] ^= H[1];
162
+ }
163
+ bool reduce = ((H[1] >> 63) & 1);
164
+ H[1] = H[1] << 1 | H[0] >> 63;
165
+ H[0] = H[0] << 1;
166
+ if (reduce) {
167
+ H[0] ^= 0x87;
168
+ }
169
+ }
170
+
171
+ vd[i * 2 + 0] = brev8(Z[0]);
172
+ vd[i * 2 + 1] = brev8(Z[1]);
173
+ }
174
+ /* set tail elements to 1s */
175
+ vext_set_elems_1s(vd, vta, env->vl * 4, total_elems * 4);
176
+ env->vstart = 0;
177
+}
178
diff --git a/target/riscv/insn_trans/trans_rvvk.c.inc b/target/riscv/insn_trans/trans_rvvk.c.inc
179
index XXXXXXX..XXXXXXX 100644
180
--- a/target/riscv/insn_trans/trans_rvvk.c.inc
181
+++ b/target/riscv/insn_trans/trans_rvvk.c.inc
182
@@ -XXX,XX +XXX,XX @@ static inline bool vsm3c_check(DisasContext *s, arg_rmrr *a)
183
184
GEN_VV_UNMASKED_TRANS(vsm3me_vv, vsm3me_check, ZVKSH_EGS)
185
GEN_VI_UNMASKED_TRANS(vsm3c_vi, vsm3c_check, ZVKSH_EGS)
186
+
187
+/*
188
+ * Zvkg
189
+ */
190
+
191
+#define ZVKG_EGS 4
192
+
193
+static bool vgmul_check(DisasContext *s, arg_rmr *a)
194
+{
195
+ int egw_bytes = ZVKG_EGS << s->sew;
196
+ return s->cfg_ptr->ext_zvkg == true &&
197
+ vext_check_isa_ill(s) &&
198
+ require_rvv(s) &&
199
+ MAXSZ(s) >= egw_bytes &&
200
+ vext_check_ss(s, a->rd, a->rs2, a->vm) &&
201
+ s->sew == MO_32;
202
+}
203
+
204
+GEN_V_UNMASKED_TRANS(vgmul_vv, vgmul_check, ZVKG_EGS)
205
+
206
+static bool vghsh_check(DisasContext *s, arg_rmrr *a)
207
+{
208
+ int egw_bytes = ZVKG_EGS << s->sew;
209
+ return s->cfg_ptr->ext_zvkg == true &&
210
+ opivv_check(s, a) &&
211
+ MAXSZ(s) >= egw_bytes &&
212
+ s->sew == MO_32;
213
+}
214
+
215
+GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
216
--
217
2.41.0
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
2
3
Allows sharing of sm4_subword between different targets.
4
5
Signed-off-by: Max Chou <max.chou@sifive.com>
6
Reviewed-by: Frank Chang <frank.chang@sifive.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Max Chou <max.chou@sifive.com>
9
Message-ID: <20230711165917.2629866-14-max.chou@sifive.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Bin Meng <bin.meng@windriver.com>
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
---
11
---
5
include/hw/riscv/opentitan.h | 13 +++++++++++++
12
include/crypto/sm4.h | 8 ++++++++
6
hw/riscv/opentitan.c | 25 +++++++++++++++++++++++--
13
target/arm/tcg/crypto_helper.c | 10 ++--------
7
2 files changed, 36 insertions(+), 2 deletions(-)
14
2 files changed, 10 insertions(+), 8 deletions(-)
8
15
9
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
16
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
10
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
11
--- a/include/hw/riscv/opentitan.h
18
--- a/include/crypto/sm4.h
12
+++ b/include/hw/riscv/opentitan.h
19
+++ b/include/crypto/sm4.h
13
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
14
21
15
#include "hw/riscv/riscv_hart.h"
22
extern const uint8_t sm4_sbox[256];
16
#include "hw/intc/ibex_plic.h"
23
17
+#include "hw/char/ibex_uart.h"
24
+static inline uint32_t sm4_subword(uint32_t word)
18
25
+{
19
#define TYPE_RISCV_IBEX_SOC "riscv.lowrisc.ibex.soc"
26
+ return sm4_sbox[word & 0xff] |
20
#define RISCV_IBEX_SOC(obj) \
27
+ sm4_sbox[(word >> 8) & 0xff] << 8 |
21
@@ -XXX,XX +XXX,XX @@ typedef struct LowRISCIbexSoCState {
28
+ sm4_sbox[(word >> 16) & 0xff] << 16 |
22
/*< public >*/
29
+ sm4_sbox[(word >> 24) & 0xff] << 24;
23
RISCVHartArrayState cpus;
30
+}
24
IbexPlicState plic;
25
+ IbexUartState uart;
26
27
MemoryRegion flash_mem;
28
MemoryRegion rom;
29
@@ -XXX,XX +XXX,XX @@ enum {
30
IBEX_PADCTRL,
31
};
32
33
+enum {
34
+ IBEX_UART_RX_PARITY_ERR_IRQ = 0x28,
35
+ IBEX_UART_RX_TIMEOUT_IRQ = 0x27,
36
+ IBEX_UART_RX_BREAK_ERR_IRQ = 0x26,
37
+ IBEX_UART_RX_FRAME_ERR_IRQ = 0x25,
38
+ IBEX_UART_RX_OVERFLOW_IRQ = 0x24,
39
+ IBEX_UART_TX_EMPTY_IRQ = 0x23,
40
+ IBEX_UART_RX_WATERMARK_IRQ = 0x22,
41
+ IBEX_UART_TX_WATERMARK_IRQ = 0x21,
42
+};
43
+
31
+
44
#endif
32
#endif
45
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
33
diff --git a/target/arm/tcg/crypto_helper.c b/target/arm/tcg/crypto_helper.c
46
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/riscv/opentitan.c
35
--- a/target/arm/tcg/crypto_helper.c
48
+++ b/hw/riscv/opentitan.c
36
+++ b/target/arm/tcg/crypto_helper.c
49
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_init(Object *obj)
37
@@ -XXX,XX +XXX,XX @@ static void do_crypto_sm4e(uint64_t *rd, uint64_t *rn, uint64_t *rm)
50
object_initialize_child(obj, "cpus", &s->cpus, TYPE_RISCV_HART_ARRAY);
38
CR_ST_WORD(d, (i + 3) % 4) ^
51
39
CR_ST_WORD(n, i);
52
object_initialize_child(obj, "plic", &s->plic, TYPE_IBEX_PLIC);
40
53
+
41
- t = sm4_sbox[t & 0xff] |
54
+ object_initialize_child(obj, "uart", &s->uart, TYPE_IBEX_UART);
42
- sm4_sbox[(t >> 8) & 0xff] << 8 |
55
}
43
- sm4_sbox[(t >> 16) & 0xff] << 16 |
56
44
- sm4_sbox[(t >> 24) & 0xff] << 24;
57
static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
45
+ t = sm4_subword(t);
58
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
46
47
CR_ST_WORD(d, i) ^= t ^ rol32(t, 2) ^ rol32(t, 10) ^ rol32(t, 18) ^
48
rol32(t, 24);
49
@@ -XXX,XX +XXX,XX @@ static void do_crypto_sm4ekey(uint64_t *rd, uint64_t *rn, uint64_t *rm)
50
CR_ST_WORD(d, (i + 3) % 4) ^
51
CR_ST_WORD(m, i);
52
53
- t = sm4_sbox[t & 0xff] |
54
- sm4_sbox[(t >> 8) & 0xff] << 8 |
55
- sm4_sbox[(t >> 16) & 0xff] << 16 |
56
- sm4_sbox[(t >> 24) & 0xff] << 24;
57
+ t = sm4_subword(t);
58
59
CR_ST_WORD(d, i) ^= t ^ rol32(t, 13) ^ rol32(t, 23);
59
}
60
}
60
sysbus_mmio_map(SYS_BUS_DEVICE(&s->plic), 0, memmap[IBEX_PLIC].base);
61
62
- create_unimplemented_device("riscv.lowrisc.ibex.uart",
63
- memmap[IBEX_UART].base, memmap[IBEX_UART].size);
64
+ /* UART */
65
+ qdev_prop_set_chr(DEVICE(&(s->uart)), "chardev", serial_hd(0));
66
+ sysbus_realize(SYS_BUS_DEVICE(&s->uart), &err);
67
+ if (err != NULL) {
68
+ error_propagate(errp, err);
69
+ return;
70
+ }
71
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart), 0, memmap[IBEX_UART].base);
72
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart),
73
+ 0, qdev_get_gpio_in(DEVICE(&s->plic),
74
+ IBEX_UART_TX_WATERMARK_IRQ));
75
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart),
76
+ 1, qdev_get_gpio_in(DEVICE(&s->plic),
77
+ IBEX_UART_RX_WATERMARK_IRQ));
78
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart),
79
+ 2, qdev_get_gpio_in(DEVICE(&s->plic),
80
+ IBEX_UART_TX_EMPTY_IRQ));
81
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart),
82
+ 3, qdev_get_gpio_in(DEVICE(&s->plic),
83
+ IBEX_UART_RX_OVERFLOW_IRQ));
84
+
85
create_unimplemented_device("riscv.lowrisc.ibex.gpio",
86
memmap[IBEX_GPIO].base, memmap[IBEX_GPIO].size);
87
create_unimplemented_device("riscv.lowrisc.ibex.spi",
88
--
61
--
89
2.27.0
62
2.41.0
90
91
diff view generated by jsdifflib
New patch
1
From: Max Chou <max.chou@sifive.com>
1
2
3
Adds sm4_ck constant for use in sm4 cryptography across different targets.
4
5
Signed-off-by: Max Chou <max.chou@sifive.com>
6
Reviewed-by: Frank Chang <frank.chang@sifive.com>
7
Signed-off-by: Max Chou <max.chou@sifive.com>
8
Message-ID: <20230711165917.2629866-15-max.chou@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
include/crypto/sm4.h | 1 +
12
crypto/sm4.c | 10 ++++++++++
13
2 files changed, 11 insertions(+)
14
15
diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/crypto/sm4.h
18
+++ b/include/crypto/sm4.h
19
@@ -XXX,XX +XXX,XX @@
20
#define QEMU_SM4_H
21
22
extern const uint8_t sm4_sbox[256];
23
+extern const uint32_t sm4_ck[32];
24
25
static inline uint32_t sm4_subword(uint32_t word)
26
{
27
diff --git a/crypto/sm4.c b/crypto/sm4.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/crypto/sm4.c
30
+++ b/crypto/sm4.c
31
@@ -XXX,XX +XXX,XX @@ uint8_t const sm4_sbox[] = {
32
0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48,
33
};
34
35
+uint32_t const sm4_ck[] = {
36
+ 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
37
+ 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
38
+ 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
39
+ 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
40
+ 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
41
+ 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
42
+ 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
43
+ 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
44
+};
45
--
46
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
Per the SiFive manual, all E/U series CPU cores' reset vector is
3
This commit adds support for the Zvksed vector-crypto extension, which
4
at 0x1004. Update our codes to match the hardware.
4
consists of the following instructions:
5
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
* vsm4k.vi
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
* vsm4r.[vv,vs]
8
Message-id: 1592268641-7478-3-git-send-email-bmeng.cn@gmail.com
8
9
Message-Id: <1592268641-7478-3-git-send-email-bmeng.cn@gmail.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
hw/riscv/sifive_e.c | 10 ++++++----
23
target/riscv/cpu_cfg.h | 1 +
13
hw/riscv/sifive_u.c | 6 +++---
24
target/riscv/helper.h | 4 +
14
target/riscv/cpu.c | 16 ++++++++--------
25
target/riscv/insn32.decode | 5 +
15
3 files changed, 17 insertions(+), 15 deletions(-)
26
target/riscv/cpu.c | 5 +-
16
27
target/riscv/vcrypto_helper.c | 127 +++++++++++++++++++++++
17
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
28
target/riscv/insn_trans/trans_rvvk.c.inc | 43 ++++++++
18
index XXXXXXX..XXXXXXX 100644
29
6 files changed, 184 insertions(+), 1 deletion(-)
19
--- a/hw/riscv/sifive_e.c
30
20
+++ b/hw/riscv/sifive_e.c
31
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
21
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_init(MachineState *machine)
32
index XXXXXXX..XXXXXXX 100644
22
memmap[SIFIVE_E_DTIM].base, main_mem);
33
--- a/target/riscv/cpu_cfg.h
23
34
+++ b/target/riscv/cpu_cfg.h
24
/* Mask ROM reset vector */
35
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
25
- uint32_t reset_vec[2];
36
bool ext_zvkned;
26
+ uint32_t reset_vec[4];
37
bool ext_zvknha;
27
38
bool ext_zvknhb;
28
if (s->revb) {
39
+ bool ext_zvksed;
29
- reset_vec[0] = 0x200102b7; /* 0x1000: lui t0,0x20010 */
40
bool ext_zvksh;
30
+ reset_vec[1] = 0x200102b7; /* 0x1004: lui t0,0x20010 */
41
bool ext_zmmul;
31
} else {
42
bool ext_zvfbfmin;
32
- reset_vec[0] = 0x204002b7; /* 0x1000: lui t0,0x20400 */
43
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
33
+ reset_vec[1] = 0x204002b7; /* 0x1004: lui t0,0x20400 */
44
index XXXXXXX..XXXXXXX 100644
34
}
45
--- a/target/riscv/helper.h
35
- reset_vec[1] = 0x00028067; /* 0x1004: jr t0 */
46
+++ b/target/riscv/helper.h
36
+ reset_vec[2] = 0x00028067; /* 0x1008: jr t0 */
47
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(vsm3c_vi, void, ptr, ptr, i32, env, i32)
37
+
48
38
+ reset_vec[0] = reset_vec[3] = 0;
49
DEF_HELPER_5(vghsh_vv, void, ptr, ptr, ptr, env, i32)
39
50
DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
40
/* copy in the reset vector in little_endian byte order */
51
+
41
for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
52
+DEF_HELPER_5(vsm4k_vi, void, ptr, ptr, i32, env, i32)
42
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
53
+DEF_HELPER_4(vsm4r_vv, void, ptr, ptr, env, i32)
43
index XXXXXXX..XXXXXXX 100644
54
+DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32)
44
--- a/hw/riscv/sifive_u.c
55
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
45
+++ b/hw/riscv/sifive_u.c
56
index XXXXXXX..XXXXXXX 100644
46
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
57
--- a/target/riscv/insn32.decode
47
58
+++ b/target/riscv/insn32.decode
48
/* reset vector */
59
@@ -XXX,XX +XXX,XX @@ vsm3c_vi 101011 1 ..... ..... 010 ..... 1110111 @r_vm_1
49
uint32_t reset_vec[8] = {
60
# *** Zvkg vector crypto extension ***
50
+ 0x00000000,
61
vghsh_vv 101100 1 ..... ..... 010 ..... 1110111 @r_vm_1
51
0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
62
vgmul_vv 101000 1 ..... 10001 010 ..... 1110111 @r2_vm_1
52
- 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */
63
+
53
+ 0x01c28593, /* addi a1, t0, %pcrel_lo(1b) */
64
+# *** Zvksed vector crypto extension ***
54
0xf1402573, /* csrr a0, mhartid */
65
+vsm4k_vi 100001 1 ..... ..... 010 ..... 1110111 @r_vm_1
55
#if defined(TARGET_RISCV32)
66
+vsm4r_vv 101000 1 ..... 10000 010 ..... 1110111 @r2_vm_1
56
0x0182a283, /* lw t0, 24(t0) */
67
+vsm4r_vs 101001 1 ..... 10000 010 ..... 1110111 @r2_vm_1
57
#elif defined(TARGET_RISCV64)
58
- 0x0182b283, /* ld t0, 24(t0) */
59
+ 0x0182e283, /* lwu t0, 24(t0) */
60
#endif
61
0x00028067, /* jr t0 */
62
0x00000000,
63
start_addr, /* start: .dword */
64
- 0x00000000,
65
/* dtb: */
66
};
67
68
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
68
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
69
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/riscv/cpu.c
70
--- a/target/riscv/cpu.c
71
+++ b/target/riscv/cpu.c
71
+++ b/target/riscv/cpu.c
72
@@ -XXX,XX +XXX,XX @@ static void riscv_base_cpu_init(Object *obj)
72
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
73
set_resetvec(env, DEFAULT_RSTVEC);
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;
74
}
113
}
75
114
+
76
-static void rvxx_gcsu_priv1_10_0_cpu_init(Object *obj)
115
+void HELPER(vsm4k_vi)(void *vd, void *vs2, uint32_t uimm5, CPURISCVState *env,
77
+static void rvxx_sifive_u_cpu_init(Object *obj)
116
+ uint32_t desc)
78
{
117
+{
79
CPURISCVState *env = &RISCV_CPU(obj)->env;
118
+ const uint32_t egs = 4;
80
set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
119
+ uint32_t rnd = uimm5 & 0x7;
81
set_priv_version(env, PRIV_VERSION_1_10_0);
120
+ uint32_t group_start = env->vstart / egs;
82
- set_resetvec(env, DEFAULT_RSTVEC);
121
+ uint32_t group_end = env->vl / egs;
83
+ set_resetvec(env, 0x1004);
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)
84
}
245
}
85
246
86
-static void rvxx_imacu_nommu_cpu_init(Object *obj)
247
GEN_VV_UNMASKED_TRANS(vghsh_vv, vghsh_check, ZVKG_EGS)
87
+static void rvxx_sifive_e_cpu_init(Object *obj)
248
+
88
{
249
+/*
89
CPURISCVState *env = &RISCV_CPU(obj)->env;
250
+ * Zvksed
90
set_misa(env, RVXLEN | RVI | RVM | RVA | RVC | RVU);
251
+ */
91
set_priv_version(env, PRIV_VERSION_1_10_0);
252
+
92
- set_resetvec(env, DEFAULT_RSTVEC);
253
+#define ZVKSED_EGS 4
93
+ set_resetvec(env, 0x1004);
254
+
94
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
255
+static bool zvksed_check(DisasContext *s)
95
}
256
+{
96
257
+ int egw_bytes = ZVKSED_EGS << s->sew;
97
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
258
+ return s->cfg_ptr->ext_zvksed == true &&
98
#if defined(TARGET_RISCV32)
259
+ require_rvv(s) &&
99
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
260
+ vext_check_isa_ill(s) &&
100
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
261
+ MAXSZ(s) >= egw_bytes &&
101
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_imacu_nommu_cpu_init),
262
+ s->sew == MO_32;
102
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_sifive_e_cpu_init),
263
+}
103
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
264
+
104
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
265
+static bool vsm4k_vi_check(DisasContext *s, arg_rmrr *a)
105
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_sifive_u_cpu_init),
266
+{
106
#elif defined(TARGET_RISCV64)
267
+ return zvksed_check(s) &&
107
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
268
+ require_align(a->rd, s->lmul) &&
108
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rvxx_imacu_nommu_cpu_init),
269
+ require_align(a->rs2, s->lmul);
109
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_gcsu_priv1_10_0_cpu_init),
270
+}
110
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rvxx_sifive_e_cpu_init),
271
+
111
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_sifive_u_cpu_init),
272
+GEN_VI_UNMASKED_TRANS(vsm4k_vi, vsm4k_vi_check, ZVKSED_EGS)
112
#endif
273
+
113
};
274
+static bool vsm4r_vv_check(DisasContext *s, arg_rmr *a)
114
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)
115
--
291
--
116
2.27.0
292
2.41.0
117
118
diff view generated by jsdifflib
New patch
1
From: Rob Bradford <rbradford@rivosinc.com>
1
2
3
These are WARL fields - zero out the bits for unavailable counters and
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.
7
8
Tested by modifying OpenSBI to write max value to these CSRs and upon
9
subsequent read the appropriate number of bits for number of PMUs is
10
enabled and the TM bit is zero in mcountinhibit.
11
12
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Atish Patra <atishp@rivosinc.com>
15
Message-ID: <20230802124906.24197-1-rbradford@rivosinc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
target/riscv/csr.c | 11 +++++++++--
19
1 file changed, 9 insertions(+), 2 deletions(-)
20
21
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/csr.c
24
+++ b/target/riscv/csr.c
25
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
26
{
27
int cidx;
28
PMUCTRState *counter;
29
+ RISCVCPU *cpu = env_archcpu(env);
30
31
- env->mcountinhibit = val;
32
+ /* WARL register - disable unavailable counters; TM bit is always 0 */
33
+ env->mcountinhibit =
34
+ val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_IR);
35
36
/* Check if any other counter is also monitoring cycles/instructions */
37
for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
38
@@ -XXX,XX +XXX,XX @@ static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
39
static RISCVException write_mcounteren(CPURISCVState *env, int csrno,
40
target_ulong val)
41
{
42
- env->mcounteren = val;
43
+ RISCVCPU *cpu = env_archcpu(env);
44
+
45
+ /* WARL register - disable unavailable counters */
46
+ env->mcounteren = val & (cpu->pmu_avail_ctrs | COUNTEREN_CY | COUNTEREN_TM |
47
+ COUNTEREN_IR);
48
return RISCV_EXCP_NONE;
49
}
50
51
--
52
2.41.0
diff view generated by jsdifflib
New patch
1
From: Jason Chien <jason.chien@sifive.com>
1
2
3
RVA23 Profiles states:
4
The RVA23 profiles are intended to be used for 64-bit application
5
processors that will run rich OS stacks from standard binary OS
6
distributions and with a substantial number of third-party binary user
7
applications that will be supported over a considerable length of time
8
in the field.
9
10
The chapter 4 of the unprivileged spec introduces the Zihintntl extension
11
and Zihintntl is a mandatory extension presented in RVA23 Profiles, whose
12
purpose is to enable application and operating system portability across
13
different implementations. Thus the DTS should contain the Zihintntl ISA
14
string in order to pass to software.
15
16
The unprivileged spec states:
17
Like any HINTs, these instructions may be freely ignored. Hence, although
18
they are described in terms of cache-based memory hierarchies, they do not
19
mandate the provision of caches.
20
21
These instructions are encoded with non-used opcode, e.g. ADD x0, x0, x2,
22
which QEMU already supports, and QEMU does not emulate cache. Therefore
23
these instructions can be considered as a no-op, and we only need to add
24
a new property for the Zihintntl extension.
25
26
Reviewed-by: Frank Chang <frank.chang@sifive.com>
27
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
28
Signed-off-by: Jason Chien <jason.chien@sifive.com>
29
Message-ID: <20230726074049.19505-2-jason.chien@sifive.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
31
---
32
target/riscv/cpu_cfg.h | 1 +
33
target/riscv/cpu.c | 2 ++
34
2 files changed, 3 insertions(+)
35
36
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/cpu_cfg.h
39
+++ b/target/riscv/cpu_cfg.h
40
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
41
bool ext_icbom;
42
bool ext_icboz;
43
bool ext_zicond;
44
+ bool ext_zihintntl;
45
bool ext_zihintpause;
46
bool ext_smstateen;
47
bool ext_sstc;
48
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/cpu.c
51
+++ b/target/riscv/cpu.c
52
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
53
ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond),
54
ISA_EXT_DATA_ENTRY(zicsr, PRIV_VERSION_1_10_0, ext_icsr),
55
ISA_EXT_DATA_ENTRY(zifencei, PRIV_VERSION_1_10_0, ext_ifencei),
56
+ ISA_EXT_DATA_ENTRY(zihintntl, PRIV_VERSION_1_10_0, ext_zihintntl),
57
ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause),
58
ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul),
59
ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs),
60
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
61
DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
62
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
63
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
64
+ DEFINE_PROP_BOOL("Zihintntl", RISCVCPU, cfg.ext_zihintntl, true),
65
DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
66
DEFINE_PROP_BOOL("Zawrs", RISCVCPU, cfg.ext_zawrs, true),
67
DEFINE_PROP_BOOL("Zfa", RISCVCPU, cfg.ext_zfa, true),
68
--
69
2.41.0
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
2
3
Commit a47842d ("riscv: Add support for the Zfa extension") implemented the zfa extension.
4
However, it has some typos for fleq.d and fltq.d. Both of them misused the fltq.s
5
helper function.
6
7
Fixes: a47842d ("riscv: Add support for the Zfa extension")
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
11
Message-ID: <20230728003906.768-1-zhiwei_liu@linux.alibaba.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/insn_trans/trans_rvzfa.c.inc | 4 ++--
15
1 file changed, 2 insertions(+), 2 deletions(-)
16
17
diff --git a/target/riscv/insn_trans/trans_rvzfa.c.inc b/target/riscv/insn_trans/trans_rvzfa.c.inc
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/insn_trans/trans_rvzfa.c.inc
20
+++ b/target/riscv/insn_trans/trans_rvzfa.c.inc
21
@@ -XXX,XX +XXX,XX @@ bool trans_fleq_d(DisasContext *ctx, arg_fleq_d *a)
22
TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
23
TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
24
25
- gen_helper_fltq_s(dest, cpu_env, src1, src2);
26
+ gen_helper_fleq_d(dest, cpu_env, src1, src2);
27
gen_set_gpr(ctx, a->rd, dest);
28
return true;
29
}
30
@@ -XXX,XX +XXX,XX @@ bool trans_fltq_d(DisasContext *ctx, arg_fltq_d *a)
31
TCGv_i64 src1 = get_fpr_hs(ctx, a->rs1);
32
TCGv_i64 src2 = get_fpr_hs(ctx, a->rs2);
33
34
- gen_helper_fltq_s(dest, cpu_env, src1, src2);
35
+ gen_helper_fltq_d(dest, cpu_env, src1, src2);
36
gen_set_gpr(ctx, a->rd, dest);
37
return true;
38
}
39
--
40
2.41.0
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
On SiFive FU540 SoC, the value stored at physical address 0x1000
3
When writing the upper mtime, we should keep the original lower mtime
4
stores the MSEL pin state that is used to control the next boot
4
whose value is given by cpu_riscv_read_rtc() instead of
5
location that ROM codes jump to.
5
cpu_riscv_read_rtc_raw(). The same logic applies to writes to lower mtime.
6
6
7
Add a new property msel to sifive_u machine for this.
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
8
9
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 1591625864-31494-12-git-send-email-bmeng.cn@gmail.com
9
Message-ID: <20230728082502.26439-1-jason.chien@sifive.com>
12
Message-Id: <1591625864-31494-12-git-send-email-bmeng.cn@gmail.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
11
---
15
include/hw/riscv/sifive_u.h | 1 +
12
hw/intc/riscv_aclint.c | 5 +++--
16
hw/riscv/sifive_u.c | 7 +++++++
13
1 file changed, 3 insertions(+), 2 deletions(-)
17
2 files changed, 8 insertions(+)
18
14
19
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
15
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/riscv/sifive_u.h
17
--- a/hw/intc/riscv_aclint.c
22
+++ b/include/hw/riscv/sifive_u.h
18
+++ b/hw/intc/riscv_aclint.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveUState {
19
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
24
int fdt_size;
20
return;
25
21
} else if (addr == mtimer->time_base || addr == mtimer->time_base + 4) {
26
bool start_in_flash;
22
uint64_t rtc_r = cpu_riscv_read_rtc_raw(mtimer->timebase_freq);
27
+ uint32_t msel;
23
+ uint64_t rtc = cpu_riscv_read_rtc(mtimer);
28
uint32_t serial;
24
29
} SiFiveUState;
25
if (addr == mtimer->time_base) {
30
26
if (size == 4) {
31
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
27
/* time_lo for RV32/RV64 */
32
index XXXXXXX..XXXXXXX 100644
28
- mtimer->time_delta = ((rtc_r & ~0xFFFFFFFFULL) | value) - rtc_r;
33
--- a/hw/riscv/sifive_u.c
29
+ mtimer->time_delta = ((rtc & ~0xFFFFFFFFULL) | value) - rtc_r;
34
+++ b/hw/riscv/sifive_u.c
30
} else {
35
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_instance_init(Object *obj)
31
/* time for RV64 */
36
"Set on to tell QEMU's ROM to jump to "
32
mtimer->time_delta = value - rtc_r;
37
"flash. Otherwise QEMU will jump to DRAM");
33
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr,
38
34
} else {
39
+ s->msel = 0;
35
if (size == 4) {
40
+ object_property_add(obj, "msel", "uint32",
36
/* time_hi for RV32/RV64 */
41
+ sifive_u_machine_get_uint32_prop,
37
- mtimer->time_delta = (value << 32 | (rtc_r & 0xFFFFFFFF)) - rtc_r;
42
+ sifive_u_machine_set_uint32_prop, NULL, &s->msel);
38
+ mtimer->time_delta = (value << 32 | (rtc & 0xFFFFFFFF)) - rtc_r;
43
+ object_property_set_description(obj, "msel",
39
} else {
44
+ "Mode Select (MSEL[3:0]) pin state");
40
qemu_log_mask(LOG_GUEST_ERROR,
45
+
41
"aclint-mtimer: invalid time_hi write: %08x",
46
s->serial = OTP_SERIAL;
47
object_property_add(obj, "serial", "uint32",
48
sifive_u_machine_get_uint32_prop,
49
--
42
--
50
2.27.0
43
2.41.0
51
52
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
At present the GPIO output IRQs are triggered each time any GPIO
3
The variables whose values are given by cpu_riscv_read_rtc() should be named
4
register is written. However this is not correct. We should only
4
"rtc". The variables whose value are given by cpu_riscv_read_rtc_raw()
5
trigger the output IRQ when the pin is configured as output enable.
5
should be named "rtc_r".
6
6
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 1591625864-31494-9-git-send-email-bmeng.cn@gmail.com
9
Message-ID: <20230728082502.26439-2-jason.chien@sifive.com>
10
Message-Id: <1591625864-31494-9-git-send-email-bmeng.cn@gmail.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
11
---
13
hw/riscv/sifive_gpio.c | 4 +++-
12
hw/intc/riscv_aclint.c | 6 +++---
14
1 file changed, 3 insertions(+), 1 deletion(-)
13
1 file changed, 3 insertions(+), 3 deletions(-)
15
14
16
diff --git a/hw/riscv/sifive_gpio.c b/hw/riscv/sifive_gpio.c
15
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/sifive_gpio.c
17
--- a/hw/intc/riscv_aclint.c
19
+++ b/hw/riscv/sifive_gpio.c
18
+++ b/hw/intc/riscv_aclint.c
20
@@ -XXX,XX +XXX,XX @@ static void update_state(SIFIVEGPIOState *s)
19
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
21
actual_value = pull;
20
uint64_t next;
22
}
21
uint64_t diff;
23
22
24
- qemu_set_irq(s->output[i], actual_value);
23
- uint64_t rtc_r = cpu_riscv_read_rtc(mtimer);
25
+ if (output_en) {
24
+ uint64_t rtc = cpu_riscv_read_rtc(mtimer);
26
+ qemu_set_irq(s->output[i], actual_value);
25
27
+ }
26
/* Compute the relative hartid w.r.t the socket */
28
27
hartid = hartid - mtimer->hartid_base;
29
/* Input value */
28
30
ival = input_en && actual_value;
29
mtimer->timecmp[hartid] = value;
30
- if (mtimer->timecmp[hartid] <= rtc_r) {
31
+ if (mtimer->timecmp[hartid] <= rtc) {
32
/*
33
* If we're setting an MTIMECMP value in the "past",
34
* immediately raise the timer interrupt
35
@@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
36
37
/* otherwise, set up the future timer interrupt */
38
qemu_irq_lower(mtimer->timer_irqs[hartid]);
39
- diff = mtimer->timecmp[hartid] - rtc_r;
40
+ diff = mtimer->timecmp[hartid] - rtc;
41
/* back to ns (note args switched in muldiv64) */
42
uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
43
31
--
44
--
32
2.27.0
45
2.41.0
33
34
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
2
3
Move the flash and DRAM to the end of the SoC memmap table.
3
We should not use types dependend on host arch for target_ucontext.
4
This bug is found when run rv32 applications.
4
5
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 1592268641-7478-5-git-send-email-bmeng.cn@gmail.com
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Message-Id: <1592268641-7478-5-git-send-email-bmeng.cn@gmail.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-ID: <20230811055438.1945-1-zhiwei_liu@linux.alibaba.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
12
---
11
hw/riscv/sifive_u.c | 4 ++--
13
linux-user/riscv/signal.c | 4 ++--
12
1 file changed, 2 insertions(+), 2 deletions(-)
14
1 file changed, 2 insertions(+), 2 deletions(-)
13
15
14
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
16
diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/sifive_u.c
18
--- a/linux-user/riscv/signal.c
17
+++ b/hw/riscv/sifive_u.c
19
+++ b/linux-user/riscv/signal.c
18
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
20
@@ -XXX,XX +XXX,XX @@ struct target_sigcontext {
19
[SIFIVE_U_UART1] = { 0x10011000, 0x1000 },
21
}; /* cf. riscv-linux:arch/riscv/include/uapi/asm/ptrace.h */
20
[SIFIVE_U_GPIO] = { 0x10060000, 0x1000 },
22
21
[SIFIVE_U_OTP] = { 0x10070000, 0x1000 },
23
struct target_ucontext {
22
- [SIFIVE_U_FLASH0] = { 0x20000000, 0x10000000 },
24
- unsigned long uc_flags;
23
- [SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
25
- struct target_ucontext *uc_link;
24
[SIFIVE_U_GEM] = { 0x10090000, 0x2000 },
26
+ abi_ulong uc_flags;
25
[SIFIVE_U_GEM_MGMT] = { 0x100a0000, 0x1000 },
27
+ abi_ptr uc_link;
26
+ [SIFIVE_U_FLASH0] = { 0x20000000, 0x10000000 },
28
target_stack_t uc_stack;
27
+ [SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
29
target_sigset_t uc_sigmask;
28
};
30
uint8_t __unused[1024 / 8 - sizeof(target_sigset_t)];
29
30
#define OTP_SERIAL 1
31
--
31
--
32
2.27.0
32
2.41.0
33
33
34
34
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
This was done in the virt & sifive_u codes, but opentitan codes were
3
In this patch, we create the APLIC and IMSIC FDT helper functions and
4
missed. Remove the riscv_ prefix of the machine* and soc* functions.
4
remove M mode AIA devices when using KVM acceleration.
5
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Jim Shu <jim.shu@sifive.com>
8
Message-id: 1591625864-31494-3-git-send-email-bmeng.cn@gmail.com
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Message-Id: <1591625864-31494-3-git-send-email-bmeng.cn@gmail.com>
9
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
10
Message-ID: <20230727102439.22554-2-yongxuan.wang@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
---
12
hw/riscv/opentitan.c | 29 ++++++++++++++---------------
13
hw/riscv/virt.c | 290 +++++++++++++++++++++++-------------------------
13
1 file changed, 14 insertions(+), 15 deletions(-)
14
1 file changed, 137 insertions(+), 153 deletions(-)
14
15
15
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
16
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/opentitan.c
18
--- a/hw/riscv/virt.c
18
+++ b/hw/riscv/opentitan.c
19
+++ b/hw/riscv/virt.c
19
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
20
@@ -XXX,XX +XXX,XX @@ static uint32_t imsic_num_bits(uint32_t count)
20
[IBEX_PADCTRL] = { 0x40160000, 0x10000 }
21
return ret;
21
};
22
}
22
23
23
-static void riscv_opentitan_init(MachineState *machine)
24
-static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
24
+static void opentitan_board_init(MachineState *machine)
25
- uint32_t *phandle, uint32_t *intc_phandles,
26
- uint32_t *msi_m_phandle, uint32_t *msi_s_phandle)
27
+static void create_fdt_one_imsic(RISCVVirtState *s, hwaddr base_addr,
28
+ uint32_t *intc_phandles, uint32_t msi_phandle,
29
+ bool m_mode, uint32_t imsic_guest_bits)
25
{
30
{
26
const struct MemmapEntry *memmap = ibex_memmap;
31
int cpu, socket;
27
OpenTitanState *s = g_new0(OpenTitanState, 1);
32
char *imsic_name;
28
@@ -XXX,XX +XXX,XX @@ static void riscv_opentitan_init(MachineState *machine)
33
MachineState *ms = MACHINE(s);
29
memory_region_add_subregion(sys_mem,
34
int socket_count = riscv_socket_count(ms);
30
memmap[IBEX_RAM].base, main_mem);
35
- uint32_t imsic_max_hart_per_socket, imsic_guest_bits;
31
36
+ uint32_t imsic_max_hart_per_socket;
37
uint32_t *imsic_cells, *imsic_regs, imsic_addr, imsic_size;
38
39
- *msi_m_phandle = (*phandle)++;
40
- *msi_s_phandle = (*phandle)++;
41
imsic_cells = g_new0(uint32_t, ms->smp.cpus * 2);
42
imsic_regs = g_new0(uint32_t, socket_count * 4);
43
44
- /* M-level IMSIC node */
45
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
46
imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
47
- imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
48
+ imsic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
49
}
50
- imsic_max_hart_per_socket = 0;
51
- for (socket = 0; socket < socket_count; socket++) {
52
- imsic_addr = memmap[VIRT_IMSIC_M].base +
53
- socket * VIRT_IMSIC_GROUP_MAX_SIZE;
54
- imsic_size = IMSIC_HART_SIZE(0) * s->soc[socket].num_harts;
55
- imsic_regs[socket * 4 + 0] = 0;
56
- imsic_regs[socket * 4 + 1] = cpu_to_be32(imsic_addr);
57
- imsic_regs[socket * 4 + 2] = 0;
58
- imsic_regs[socket * 4 + 3] = cpu_to_be32(imsic_size);
59
- if (imsic_max_hart_per_socket < s->soc[socket].num_harts) {
60
- imsic_max_hart_per_socket = s->soc[socket].num_harts;
61
- }
62
- }
63
- imsic_name = g_strdup_printf("/soc/imsics@%lx",
64
- (unsigned long)memmap[VIRT_IMSIC_M].base);
65
- qemu_fdt_add_subnode(ms->fdt, imsic_name);
66
- qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
67
- "riscv,imsics");
68
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
69
- FDT_IMSIC_INT_CELLS);
70
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
71
- NULL, 0);
72
- qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
73
- NULL, 0);
74
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
75
- imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
76
- qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
77
- socket_count * sizeof(uint32_t) * 4);
78
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
79
- VIRT_IRQCHIP_NUM_MSIS);
80
- if (socket_count > 1) {
81
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
82
- imsic_num_bits(imsic_max_hart_per_socket));
83
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
84
- imsic_num_bits(socket_count));
85
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
86
- IMSIC_MMIO_GROUP_MIN_SHIFT);
87
- }
88
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_m_phandle);
32
-
89
-
33
if (machine->firmware) {
90
- g_free(imsic_name);
34
riscv_load_firmware(machine->firmware, memmap[IBEX_RAM].base, NULL);
91
35
}
92
- /* S-level IMSIC node */
36
@@ -XXX,XX +XXX,XX @@ static void riscv_opentitan_init(MachineState *machine)
93
- for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
37
}
94
- imsic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
95
- imsic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
96
- }
97
- imsic_guest_bits = imsic_num_bits(s->aia_guests + 1);
98
imsic_max_hart_per_socket = 0;
99
for (socket = 0; socket < socket_count; socket++) {
100
- imsic_addr = memmap[VIRT_IMSIC_S].base +
101
- socket * VIRT_IMSIC_GROUP_MAX_SIZE;
102
+ imsic_addr = base_addr + socket * VIRT_IMSIC_GROUP_MAX_SIZE;
103
imsic_size = IMSIC_HART_SIZE(imsic_guest_bits) *
104
s->soc[socket].num_harts;
105
imsic_regs[socket * 4 + 0] = 0;
106
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
107
imsic_max_hart_per_socket = s->soc[socket].num_harts;
108
}
109
}
110
- imsic_name = g_strdup_printf("/soc/imsics@%lx",
111
- (unsigned long)memmap[VIRT_IMSIC_S].base);
112
+
113
+ imsic_name = g_strdup_printf("/soc/imsics@%lx", (unsigned long)base_addr);
114
qemu_fdt_add_subnode(ms->fdt, imsic_name);
115
- qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible",
116
- "riscv,imsics");
117
+ qemu_fdt_setprop_string(ms->fdt, imsic_name, "compatible", "riscv,imsics");
118
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "#interrupt-cells",
119
- FDT_IMSIC_INT_CELLS);
120
- qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller",
121
- NULL, 0);
122
- qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller",
123
- NULL, 0);
124
+ FDT_IMSIC_INT_CELLS);
125
+ qemu_fdt_setprop(ms->fdt, imsic_name, "interrupt-controller", NULL, 0);
126
+ qemu_fdt_setprop(ms->fdt, imsic_name, "msi-controller", NULL, 0);
127
qemu_fdt_setprop(ms->fdt, imsic_name, "interrupts-extended",
128
- imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
129
+ imsic_cells, ms->smp.cpus * sizeof(uint32_t) * 2);
130
qemu_fdt_setprop(ms->fdt, imsic_name, "reg", imsic_regs,
131
- socket_count * sizeof(uint32_t) * 4);
132
+ socket_count * sizeof(uint32_t) * 4);
133
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,num-ids",
134
- VIRT_IRQCHIP_NUM_MSIS);
135
+ VIRT_IRQCHIP_NUM_MSIS);
136
+
137
if (imsic_guest_bits) {
138
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,guest-index-bits",
139
- imsic_guest_bits);
140
+ imsic_guest_bits);
141
}
142
+
143
if (socket_count > 1) {
144
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,hart-index-bits",
145
- imsic_num_bits(imsic_max_hart_per_socket));
146
+ imsic_num_bits(imsic_max_hart_per_socket));
147
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-bits",
148
- imsic_num_bits(socket_count));
149
+ imsic_num_bits(socket_count));
150
qemu_fdt_setprop_cell(ms->fdt, imsic_name, "riscv,group-index-shift",
151
- IMSIC_MMIO_GROUP_MIN_SHIFT);
152
+ IMSIC_MMIO_GROUP_MIN_SHIFT);
153
}
154
- qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", *msi_s_phandle);
155
- g_free(imsic_name);
156
+ qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", msi_phandle);
157
158
+ g_free(imsic_name);
159
g_free(imsic_regs);
160
g_free(imsic_cells);
38
}
161
}
39
162
40
-static void riscv_opentitan_machine_init(MachineClass *mc)
163
-static void create_fdt_socket_aplic(RISCVVirtState *s,
41
+static void opentitan_machine_init(MachineClass *mc)
164
- const MemMapEntry *memmap, int socket,
165
- uint32_t msi_m_phandle,
166
- uint32_t msi_s_phandle,
167
- uint32_t *phandle,
168
- uint32_t *intc_phandles,
169
- uint32_t *aplic_phandles)
170
+static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
171
+ uint32_t *phandle, uint32_t *intc_phandles,
172
+ uint32_t *msi_m_phandle, uint32_t *msi_s_phandle)
173
+{
174
+ *msi_m_phandle = (*phandle)++;
175
+ *msi_s_phandle = (*phandle)++;
176
+
177
+ if (!kvm_enabled()) {
178
+ /* M-level IMSIC node */
179
+ create_fdt_one_imsic(s, memmap[VIRT_IMSIC_M].base, intc_phandles,
180
+ *msi_m_phandle, true, 0);
181
+ }
182
+
183
+ /* S-level IMSIC node */
184
+ create_fdt_one_imsic(s, memmap[VIRT_IMSIC_S].base, intc_phandles,
185
+ *msi_s_phandle, false,
186
+ imsic_num_bits(s->aia_guests + 1));
187
+
188
+}
189
+
190
+static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
191
+ unsigned long aplic_addr, uint32_t aplic_size,
192
+ uint32_t msi_phandle,
193
+ uint32_t *intc_phandles,
194
+ uint32_t aplic_phandle,
195
+ uint32_t aplic_child_phandle,
196
+ bool m_mode)
42
{
197
{
43
mc->desc = "RISC-V Board compatible with OpenTitan";
198
int cpu;
44
- mc->init = riscv_opentitan_init;
199
char *aplic_name;
45
+ mc->init = opentitan_board_init;
200
uint32_t *aplic_cells;
46
mc->max_cpus = 1;
201
- unsigned long aplic_addr;
47
mc->default_cpu_type = TYPE_RISCV_CPU_IBEX;
202
MachineState *ms = MACHINE(s);
203
- uint32_t aplic_m_phandle, aplic_s_phandle;
204
205
- aplic_m_phandle = (*phandle)++;
206
- aplic_s_phandle = (*phandle)++;
207
aplic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
208
209
- /* M-level APLIC node */
210
for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
211
aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
212
- aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_M_EXT);
213
+ aplic_cells[cpu * 2 + 1] = cpu_to_be32(m_mode ? IRQ_M_EXT : IRQ_S_EXT);
214
}
215
- aplic_addr = memmap[VIRT_APLIC_M].base +
216
- (memmap[VIRT_APLIC_M].size * socket);
217
+
218
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
219
qemu_fdt_add_subnode(ms->fdt, aplic_name);
220
qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
221
qemu_fdt_setprop_cell(ms->fdt, aplic_name,
222
- "#interrupt-cells", FDT_APLIC_INT_CELLS);
223
+ "#interrupt-cells", FDT_APLIC_INT_CELLS);
224
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
225
+
226
if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
227
qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
228
- aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2);
229
+ aplic_cells,
230
+ s->soc[socket].num_harts * sizeof(uint32_t) * 2);
231
} else {
232
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent",
233
- msi_m_phandle);
234
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent", msi_phandle);
235
}
236
+
237
qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
238
- 0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_M].size);
239
+ 0x0, aplic_addr, 0x0, aplic_size);
240
qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
241
- VIRT_IRQCHIP_NUM_SOURCES);
242
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,children",
243
- aplic_s_phandle);
244
- qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate",
245
- aplic_s_phandle, 0x1, VIRT_IRQCHIP_NUM_SOURCES);
246
+ VIRT_IRQCHIP_NUM_SOURCES);
247
+
248
+ if (aplic_child_phandle) {
249
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,children",
250
+ aplic_child_phandle);
251
+ qemu_fdt_setprop_cells(ms->fdt, aplic_name, "riscv,delegate",
252
+ aplic_child_phandle, 0x1,
253
+ VIRT_IRQCHIP_NUM_SOURCES);
254
+ }
255
+
256
riscv_socket_fdt_write_id(ms, aplic_name, socket);
257
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_m_phandle);
258
+ qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_phandle);
259
+
260
g_free(aplic_name);
261
+ g_free(aplic_cells);
262
+}
263
264
- /* S-level APLIC node */
265
- for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
266
- aplic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
267
- aplic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
268
+static void create_fdt_socket_aplic(RISCVVirtState *s,
269
+ const MemMapEntry *memmap, int socket,
270
+ uint32_t msi_m_phandle,
271
+ uint32_t msi_s_phandle,
272
+ uint32_t *phandle,
273
+ uint32_t *intc_phandles,
274
+ uint32_t *aplic_phandles)
275
+{
276
+ char *aplic_name;
277
+ unsigned long aplic_addr;
278
+ MachineState *ms = MACHINE(s);
279
+ uint32_t aplic_m_phandle, aplic_s_phandle;
280
+
281
+ aplic_m_phandle = (*phandle)++;
282
+ aplic_s_phandle = (*phandle)++;
283
+
284
+ if (!kvm_enabled()) {
285
+ /* M-level APLIC node */
286
+ aplic_addr = memmap[VIRT_APLIC_M].base +
287
+ (memmap[VIRT_APLIC_M].size * socket);
288
+ create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_M].size,
289
+ msi_m_phandle, intc_phandles,
290
+ aplic_m_phandle, aplic_s_phandle,
291
+ true);
292
}
293
+
294
+ /* S-level APLIC node */
295
aplic_addr = memmap[VIRT_APLIC_S].base +
296
(memmap[VIRT_APLIC_S].size * socket);
297
+ create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_S].size,
298
+ msi_s_phandle, intc_phandles,
299
+ aplic_s_phandle, 0,
300
+ false);
301
+
302
aplic_name = g_strdup_printf("/soc/aplic@%lx", aplic_addr);
303
- qemu_fdt_add_subnode(ms->fdt, aplic_name);
304
- qemu_fdt_setprop_string(ms->fdt, aplic_name, "compatible", "riscv,aplic");
305
- qemu_fdt_setprop_cell(ms->fdt, aplic_name,
306
- "#interrupt-cells", FDT_APLIC_INT_CELLS);
307
- qemu_fdt_setprop(ms->fdt, aplic_name, "interrupt-controller", NULL, 0);
308
- if (s->aia_type == VIRT_AIA_TYPE_APLIC) {
309
- qemu_fdt_setprop(ms->fdt, aplic_name, "interrupts-extended",
310
- aplic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 2);
311
- } else {
312
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "msi-parent",
313
- msi_s_phandle);
314
- }
315
- qemu_fdt_setprop_cells(ms->fdt, aplic_name, "reg",
316
- 0x0, aplic_addr, 0x0, memmap[VIRT_APLIC_S].size);
317
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "riscv,num-sources",
318
- VIRT_IRQCHIP_NUM_SOURCES);
319
- riscv_socket_fdt_write_id(ms, aplic_name, socket);
320
- qemu_fdt_setprop_cell(ms->fdt, aplic_name, "phandle", aplic_s_phandle);
321
322
if (!socket) {
323
platform_bus_add_all_fdt_nodes(ms->fdt, aplic_name,
324
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
325
326
g_free(aplic_name);
327
328
- g_free(aplic_cells);
329
aplic_phandles[socket] = aplic_s_phandle;
48
}
330
}
49
331
50
-DEFINE_MACHINE("opentitan", riscv_opentitan_machine_init)
332
@@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
51
+DEFINE_MACHINE("opentitan", opentitan_machine_init)
333
int i;
52
334
hwaddr addr;
53
-static void riscv_lowrisc_ibex_soc_init(Object *obj)
335
uint32_t guest_bits;
54
+static void lowrisc_ibex_soc_init(Object *obj)
336
- DeviceState *aplic_m;
55
{
337
- bool msimode = (aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) ? true : false;
56
LowRISCIbexSoCState *s = RISCV_IBEX_SOC(obj);
338
+ DeviceState *aplic_s = NULL;
57
339
+ DeviceState *aplic_m = NULL;
58
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_init(Object *obj)
340
+ bool msimode = aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
59
object_initialize_child(obj, "uart", &s->uart, TYPE_IBEX_UART);
341
342
if (msimode) {
343
- /* Per-socket M-level IMSICs */
344
- addr = memmap[VIRT_IMSIC_M].base + socket * VIRT_IMSIC_GROUP_MAX_SIZE;
345
- for (i = 0; i < hart_count; i++) {
346
- riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0),
347
- base_hartid + i, true, 1,
348
- VIRT_IRQCHIP_NUM_MSIS);
349
+ if (!kvm_enabled()) {
350
+ /* Per-socket M-level IMSICs */
351
+ addr = memmap[VIRT_IMSIC_M].base +
352
+ socket * VIRT_IMSIC_GROUP_MAX_SIZE;
353
+ for (i = 0; i < hart_count; i++) {
354
+ riscv_imsic_create(addr + i * IMSIC_HART_SIZE(0),
355
+ base_hartid + i, true, 1,
356
+ VIRT_IRQCHIP_NUM_MSIS);
357
+ }
358
}
359
360
/* Per-socket S-level IMSICs */
361
@@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
362
}
363
}
364
365
- /* Per-socket M-level APLIC */
366
- aplic_m = riscv_aplic_create(
367
- memmap[VIRT_APLIC_M].base + socket * memmap[VIRT_APLIC_M].size,
368
- memmap[VIRT_APLIC_M].size,
369
- (msimode) ? 0 : base_hartid,
370
- (msimode) ? 0 : hart_count,
371
- VIRT_IRQCHIP_NUM_SOURCES,
372
- VIRT_IRQCHIP_NUM_PRIO_BITS,
373
- msimode, true, NULL);
374
-
375
- if (aplic_m) {
376
- /* Per-socket S-level APLIC */
377
- riscv_aplic_create(
378
- memmap[VIRT_APLIC_S].base + socket * memmap[VIRT_APLIC_S].size,
379
- memmap[VIRT_APLIC_S].size,
380
- (msimode) ? 0 : base_hartid,
381
- (msimode) ? 0 : hart_count,
382
- VIRT_IRQCHIP_NUM_SOURCES,
383
- VIRT_IRQCHIP_NUM_PRIO_BITS,
384
- msimode, false, aplic_m);
385
+ if (!kvm_enabled()) {
386
+ /* Per-socket M-level APLIC */
387
+ aplic_m = riscv_aplic_create(memmap[VIRT_APLIC_M].base +
388
+ socket * memmap[VIRT_APLIC_M].size,
389
+ memmap[VIRT_APLIC_M].size,
390
+ (msimode) ? 0 : base_hartid,
391
+ (msimode) ? 0 : hart_count,
392
+ VIRT_IRQCHIP_NUM_SOURCES,
393
+ VIRT_IRQCHIP_NUM_PRIO_BITS,
394
+ msimode, true, NULL);
395
}
396
397
- return aplic_m;
398
+ /* Per-socket S-level APLIC */
399
+ aplic_s = riscv_aplic_create(memmap[VIRT_APLIC_S].base +
400
+ socket * memmap[VIRT_APLIC_S].size,
401
+ memmap[VIRT_APLIC_S].size,
402
+ (msimode) ? 0 : base_hartid,
403
+ (msimode) ? 0 : hart_count,
404
+ VIRT_IRQCHIP_NUM_SOURCES,
405
+ VIRT_IRQCHIP_NUM_PRIO_BITS,
406
+ msimode, false, aplic_m);
407
+
408
+ return kvm_enabled() ? aplic_s : aplic_m;
60
}
409
}
61
410
62
-static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
411
static void create_platform_bus(RISCVVirtState *s, DeviceState *irqchip)
63
+static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
64
{
65
const struct MemmapEntry *memmap = ibex_memmap;
66
MachineState *ms = MACHINE(qdev_get_machine());
67
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
68
memmap[IBEX_PADCTRL].base, memmap[IBEX_PADCTRL].size);
69
}
70
71
-static void riscv_lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data)
72
+static void lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data)
73
{
74
DeviceClass *dc = DEVICE_CLASS(oc);
75
76
- dc->realize = riscv_lowrisc_ibex_soc_realize;
77
+ dc->realize = lowrisc_ibex_soc_realize;
78
/* Reason: Uses serial_hds in realize function, thus can't be used twice */
79
dc->user_creatable = false;
80
}
81
82
-static const TypeInfo riscv_lowrisc_ibex_soc_type_info = {
83
+static const TypeInfo lowrisc_ibex_soc_type_info = {
84
.name = TYPE_RISCV_IBEX_SOC,
85
.parent = TYPE_DEVICE,
86
.instance_size = sizeof(LowRISCIbexSoCState),
87
- .instance_init = riscv_lowrisc_ibex_soc_init,
88
- .class_init = riscv_lowrisc_ibex_soc_class_init,
89
+ .instance_init = lowrisc_ibex_soc_init,
90
+ .class_init = lowrisc_ibex_soc_class_init,
91
};
92
93
-static void riscv_lowrisc_ibex_soc_register_types(void)
94
+static void lowrisc_ibex_soc_register_types(void)
95
{
96
- type_register_static(&riscv_lowrisc_ibex_soc_type_info);
97
+ type_register_static(&lowrisc_ibex_soc_type_info);
98
}
99
100
-type_init(riscv_lowrisc_ibex_soc_register_types)
101
+type_init(lowrisc_ibex_soc_register_types)
102
--
412
--
103
2.27.0
413
2.41.0
104
105
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
It is enough to simply map the SiFive FU540 DDR memory controller
3
We check the in-kernel irqchip support when using KVM acceleration.
4
into the MMIO space using create_unimplemented_device(), to make
5
the upstream U-Boot v2020.07 DDR memory initialization codes happy.
6
4
7
Note we do not generate device tree fragment for the DDR memory
5
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
8
controller. Since the controller data in device tree consumes a
6
Reviewed-by: Jim Shu <jim.shu@sifive.com>
9
very large space (see fu540-hifive-unleashed-a00-ddr.dtsi in the
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
U-Boot source), and it is only needed by U-Boot SPL but not any
8
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
11
operating system, we choose not to generate the fragment here.
9
Message-ID: <20230727102439.22554-3-yongxuan.wang@sifive.com>
12
This also means when testing with U-Boot SPL, the device tree has
13
to come from U-Boot SPL itself, but not the one generated by QEMU
14
on the fly. The memory has to be set to 8GiB to match the real
15
HiFive Unleashed board when invoking QEMU (-m 8G).
16
17
With this commit, QEMU can boot U-Boot SPL built for SiFive FU540
18
all the way up to loading U-Boot proper from MMC:
19
20
$ qemu-system-riscv64 -nographic -M sifive_u,msel=6 -m 8G -bios u-boot-spl.bin
21
22
U-Boot SPL 2020.07-rc3-00208-g88bd5b1 (Jun 08 2020 - 20:16:10 +0800)
23
Trying to boot from MMC1
24
Unhandled exception: Load access fault
25
EPC: 0000000008009be6 TVAL: 0000000010050014
26
27
The above exception is expected because QSPI is unsupported yet.
28
29
Signed-off-by: Bin Meng <bin.meng@windriver.com>
30
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
31
Message-id: 1592268641-7478-6-git-send-email-bmeng.cn@gmail.com
32
Message-Id: <1592268641-7478-6-git-send-email-bmeng.cn@gmail.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
34
---
11
---
35
include/hw/riscv/sifive_u.h | 1 +
12
target/riscv/kvm.c | 10 +++++++++-
36
hw/riscv/sifive_u.c | 4 ++++
13
1 file changed, 9 insertions(+), 1 deletion(-)
37
2 files changed, 5 insertions(+)
38
14
39
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
15
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
40
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
41
--- a/include/hw/riscv/sifive_u.h
17
--- a/target/riscv/kvm.c
42
+++ b/include/hw/riscv/sifive_u.h
18
+++ b/target/riscv/kvm.c
43
@@ -XXX,XX +XXX,XX @@ enum {
19
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
44
SIFIVE_U_UART1,
20
45
SIFIVE_U_GPIO,
21
int kvm_arch_irqchip_create(KVMState *s)
46
SIFIVE_U_OTP,
22
{
47
+ SIFIVE_U_DMC,
23
- return 0;
48
SIFIVE_U_FLASH0,
24
+ if (kvm_kernel_irqchip_split()) {
49
SIFIVE_U_DRAM,
25
+ error_report("-machine kernel_irqchip=split is not supported on RISC-V.");
50
SIFIVE_U_GEM,
26
+ exit(1);
51
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
27
+ }
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/riscv/sifive_u.c
54
+++ b/hw/riscv/sifive_u.c
55
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
56
[SIFIVE_U_OTP] = { 0x10070000, 0x1000 },
57
[SIFIVE_U_GEM] = { 0x10090000, 0x2000 },
58
[SIFIVE_U_GEM_MGMT] = { 0x100a0000, 0x1000 },
59
+ [SIFIVE_U_DMC] = { 0x100b0000, 0x10000 },
60
[SIFIVE_U_FLASH0] = { 0x20000000, 0x10000000 },
61
[SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
62
};
63
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
64
65
create_unimplemented_device("riscv.sifive.u.gem-mgmt",
66
memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
67
+
28
+
68
+ create_unimplemented_device("riscv.sifive.u.dmc",
29
+ /*
69
+ memmap[SIFIVE_U_DMC].base, memmap[SIFIVE_U_DMC].size);
30
+ * We can create the VAIA using the newer device control API.
31
+ */
32
+ return kvm_check_extension(s, KVM_CAP_DEVICE_CTRL);
70
}
33
}
71
34
72
static Property sifive_u_soc_props[] = {
35
int kvm_arch_process_async_events(CPUState *cs)
73
--
36
--
74
2.27.0
37
2.41.0
75
76
diff view generated by jsdifflib
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
3
We create a vAIA chip by using the KVM_DEV_TYPE_RISCV_AIA and then set up
4
the chip with the KVM_DEV_RISCV_AIA_GRP_* APIs.
5
We also extend KVM accelerator to specify the KVM AIA mode. The "riscv-aia"
6
parameter is passed along with --accel in QEMU command-line.
7
1) "riscv-aia=emul": IMSIC is emulated by hypervisor
8
2) "riscv-aia=hwaccel": use hardware guest IMSIC
9
3) "riscv-aia=auto": use the hardware guest IMSICs whenever available
10
otherwise we fallback to software emulation.
11
12
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
13
Reviewed-by: Jim Shu <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>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Bin Meng <bin.meng@windriver.com>
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
---
18
---
5
include/hw/riscv/opentitan.h | 3 +++
19
target/riscv/kvm_riscv.h | 4 +
6
hw/riscv/opentitan.c | 14 ++++++++++++--
20
target/riscv/kvm.c | 186 +++++++++++++++++++++++++++++++++++++++
7
2 files changed, 15 insertions(+), 2 deletions(-)
21
2 files changed, 190 insertions(+)
8
22
9
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
23
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
10
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
11
--- a/include/hw/riscv/opentitan.h
25
--- a/target/riscv/kvm_riscv.h
12
+++ b/include/hw/riscv/opentitan.h
26
+++ b/target/riscv/kvm_riscv.h
13
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@
14
#define HW_OPENTITAN_H
28
void kvm_riscv_init_user_properties(Object *cpu_obj);
15
29
void kvm_riscv_reset_vcpu(RISCVCPU *cpu);
16
#include "hw/riscv/riscv_hart.h"
30
void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level);
17
+#include "hw/intc/ibex_plic.h"
31
+void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
18
32
+ uint64_t aia_irq_num, uint64_t aia_msi_num,
19
#define TYPE_RISCV_IBEX_SOC "riscv.lowrisc.ibex.soc"
33
+ uint64_t aplic_base, uint64_t imsic_base,
20
#define RISCV_IBEX_SOC(obj) \
34
+ uint64_t guest_num);
21
@@ -XXX,XX +XXX,XX @@ typedef struct LowRISCIbexSoCState {
35
22
36
#endif
23
/*< public >*/
37
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
24
RISCVHartArrayState cpus;
25
+ IbexPlicState plic;
26
+
27
MemoryRegion flash_mem;
28
MemoryRegion rom;
29
} LowRISCIbexSoCState;
30
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
31
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/riscv/opentitan.c
39
--- a/target/riscv/kvm.c
33
+++ b/hw/riscv/opentitan.c
40
+++ b/target/riscv/kvm.c
34
@@ -XXX,XX +XXX,XX @@
41
@@ -XXX,XX +XXX,XX @@
35
#include "hw/riscv/boot.h"
36
#include "exec/address-spaces.h"
42
#include "exec/address-spaces.h"
37
#include "qemu/units.h"
43
#include "hw/boards.h"
38
+#include "sysemu/sysemu.h"
44
#include "hw/irq.h"
39
45
+#include "hw/intc/riscv_imsic.h"
40
static const struct MemmapEntry {
46
#include "qemu/log.h"
41
hwaddr base;
47
#include "hw/loader.h"
42
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_init(Object *obj)
48
#include "kvm_riscv.h"
43
LowRISCIbexSoCState *s = RISCV_IBEX_SOC(obj);
49
@@ -XXX,XX +XXX,XX @@
44
50
#include "chardev/char-fe.h"
45
object_initialize_child(obj, "cpus", &s->cpus, TYPE_RISCV_HART_ARRAY);
51
#include "migration/migration.h"
46
+
52
#include "sysemu/runstate.h"
47
+ object_initialize_child(obj, "plic", &s->plic, TYPE_IBEX_PLIC);
53
+#include "hw/riscv/numa.h"
54
55
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
56
uint64_t idx)
57
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_cpu_check_are_resettable(void)
58
return true;
48
}
59
}
49
60
50
static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
61
+static int aia_mode;
51
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
62
+
52
MachineState *ms = MACHINE(qdev_get_machine());
63
+static const char *kvm_aia_mode_str(uint64_t mode)
53
LowRISCIbexSoCState *s = RISCV_IBEX_SOC(dev_soc);
64
+{
54
MemoryRegion *sys_mem = get_system_memory();
65
+ switch (mode) {
55
+ Error *err = NULL;
66
+ case KVM_DEV_RISCV_AIA_MODE_EMUL:
56
67
+ return "emul";
57
object_property_set_str(OBJECT(&s->cpus), ms->cpu_type, "cpu-type",
68
+ case KVM_DEV_RISCV_AIA_MODE_HWACCEL:
58
&error_abort);
69
+ return "hwaccel";
59
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
70
+ case KVM_DEV_RISCV_AIA_MODE_AUTO:
60
memory_region_add_subregion(sys_mem, memmap[IBEX_FLASH].base,
71
+ default:
61
&s->flash_mem);
72
+ return "auto";
62
73
+ };
63
+ /* PLIC */
74
+}
64
+ sysbus_realize(SYS_BUS_DEVICE(&s->plic), &err);
75
+
65
+ if (err != NULL) {
76
+static char *riscv_get_kvm_aia(Object *obj, Error **errp)
66
+ error_propagate(errp, err);
77
+{
67
+ return;
78
+ return g_strdup(kvm_aia_mode_str(aia_mode));
68
+ }
79
+}
69
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->plic), 0, memmap[IBEX_PLIC].base);
80
+
70
+
81
+static void riscv_set_kvm_aia(Object *obj, const char *val, Error **errp)
71
create_unimplemented_device("riscv.lowrisc.ibex.uart",
82
+{
72
memmap[IBEX_UART].base, memmap[IBEX_UART].size);
83
+ if (!strcmp(val, "emul")) {
73
create_unimplemented_device("riscv.lowrisc.ibex.gpio",
84
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_EMUL;
74
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
85
+ } else if (!strcmp(val, "hwaccel")) {
75
memmap[IBEX_AES].base, memmap[IBEX_AES].size);
86
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_HWACCEL;
76
create_unimplemented_device("riscv.lowrisc.ibex.hmac",
87
+ } else if (!strcmp(val, "auto")) {
77
memmap[IBEX_HMAC].base, memmap[IBEX_HMAC].size);
88
+ aia_mode = KVM_DEV_RISCV_AIA_MODE_AUTO;
78
- create_unimplemented_device("riscv.lowrisc.ibex.plic",
89
+ } else {
79
- memmap[IBEX_PLIC].base, memmap[IBEX_PLIC].size);
90
+ error_setg(errp, "Invalid KVM AIA mode");
80
create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
91
+ error_append_hint(errp, "Valid values are emul, hwaccel, and auto.\n");
81
memmap[IBEX_PINMUX].base, memmap[IBEX_PINMUX].size);
92
+ }
82
create_unimplemented_device("riscv.lowrisc.ibex.alert_handler",
93
+}
94
+
95
void kvm_arch_accel_class_init(ObjectClass *oc)
96
{
97
+ object_class_property_add_str(oc, "riscv-aia", riscv_get_kvm_aia,
98
+ riscv_set_kvm_aia);
99
+ object_class_property_set_description(oc, "riscv-aia",
100
+ "Set KVM AIA mode. Valid values are "
101
+ "emul, hwaccel, and auto. Default "
102
+ "is auto.");
103
+ object_property_set_default_str(object_class_property_find(oc, "riscv-aia"),
104
+ "auto");
105
+}
106
+
107
+void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
108
+ uint64_t aia_irq_num, uint64_t aia_msi_num,
109
+ uint64_t aplic_base, uint64_t imsic_base,
110
+ uint64_t guest_num)
111
+{
112
+ int ret, i;
113
+ int aia_fd = -1;
114
+ uint64_t default_aia_mode;
115
+ uint64_t socket_count = riscv_socket_count(machine);
116
+ uint64_t max_hart_per_socket = 0;
117
+ uint64_t socket, base_hart, hart_count, socket_imsic_base, imsic_addr;
118
+ uint64_t socket_bits, hart_bits, guest_bits;
119
+
120
+ aia_fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_RISCV_AIA, false);
121
+
122
+ if (aia_fd < 0) {
123
+ error_report("Unable to create in-kernel irqchip");
124
+ exit(1);
125
+ }
126
+
127
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
128
+ KVM_DEV_RISCV_AIA_CONFIG_MODE,
129
+ &default_aia_mode, false, NULL);
130
+ if (ret < 0) {
131
+ error_report("KVM AIA: failed to get current KVM AIA mode");
132
+ exit(1);
133
+ }
134
+ qemu_log("KVM AIA: default mode is %s\n",
135
+ kvm_aia_mode_str(default_aia_mode));
136
+
137
+ if (default_aia_mode != aia_mode) {
138
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
139
+ KVM_DEV_RISCV_AIA_CONFIG_MODE,
140
+ &aia_mode, true, NULL);
141
+ if (ret < 0)
142
+ warn_report("KVM AIA: failed to set KVM AIA mode");
143
+ else
144
+ qemu_log("KVM AIA: set current mode to %s\n",
145
+ kvm_aia_mode_str(aia_mode));
146
+ }
147
+
148
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
149
+ KVM_DEV_RISCV_AIA_CONFIG_SRCS,
150
+ &aia_irq_num, true, NULL);
151
+ if (ret < 0) {
152
+ error_report("KVM AIA: failed to set number of input irq lines");
153
+ exit(1);
154
+ }
155
+
156
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
157
+ KVM_DEV_RISCV_AIA_CONFIG_IDS,
158
+ &aia_msi_num, true, NULL);
159
+ if (ret < 0) {
160
+ error_report("KVM AIA: failed to set number of msi");
161
+ exit(1);
162
+ }
163
+
164
+ socket_bits = find_last_bit(&socket_count, BITS_PER_LONG) + 1;
165
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
166
+ KVM_DEV_RISCV_AIA_CONFIG_GROUP_BITS,
167
+ &socket_bits, true, NULL);
168
+ if (ret < 0) {
169
+ error_report("KVM AIA: failed to set group_bits");
170
+ exit(1);
171
+ }
172
+
173
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
174
+ KVM_DEV_RISCV_AIA_CONFIG_GROUP_SHIFT,
175
+ &group_shift, true, NULL);
176
+ if (ret < 0) {
177
+ error_report("KVM AIA: failed to set group_shift");
178
+ exit(1);
179
+ }
180
+
181
+ guest_bits = guest_num == 0 ? 0 :
182
+ find_last_bit(&guest_num, BITS_PER_LONG) + 1;
183
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
184
+ KVM_DEV_RISCV_AIA_CONFIG_GUEST_BITS,
185
+ &guest_bits, true, NULL);
186
+ if (ret < 0) {
187
+ error_report("KVM AIA: failed to set guest_bits");
188
+ exit(1);
189
+ }
190
+
191
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_ADDR,
192
+ KVM_DEV_RISCV_AIA_ADDR_APLIC,
193
+ &aplic_base, true, NULL);
194
+ if (ret < 0) {
195
+ error_report("KVM AIA: failed to set the base address of APLIC");
196
+ exit(1);
197
+ }
198
+
199
+ for (socket = 0; socket < socket_count; socket++) {
200
+ socket_imsic_base = imsic_base + socket * (1U << group_shift);
201
+ hart_count = riscv_socket_hart_count(machine, socket);
202
+ base_hart = riscv_socket_first_hartid(machine, socket);
203
+
204
+ if (max_hart_per_socket < hart_count) {
205
+ max_hart_per_socket = hart_count;
206
+ }
207
+
208
+ for (i = 0; i < hart_count; i++) {
209
+ imsic_addr = socket_imsic_base + i * IMSIC_HART_SIZE(guest_bits);
210
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_ADDR,
211
+ KVM_DEV_RISCV_AIA_ADDR_IMSIC(i + base_hart),
212
+ &imsic_addr, true, NULL);
213
+ if (ret < 0) {
214
+ error_report("KVM AIA: failed to set the IMSIC address for hart %d", i);
215
+ exit(1);
216
+ }
217
+ }
218
+ }
219
+
220
+ hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
221
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
222
+ KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
223
+ &hart_bits, true, NULL);
224
+ if (ret < 0) {
225
+ error_report("KVM AIA: failed to set hart_bits");
226
+ exit(1);
227
+ }
228
+
229
+ if (kvm_has_gsi_routing()) {
230
+ for (uint64_t idx = 0; idx < aia_irq_num + 1; ++idx) {
231
+ /* KVM AIA only has one APLIC instance */
232
+ kvm_irqchip_add_irq_route(kvm_state, idx, 0, idx);
233
+ }
234
+ kvm_gsi_routing_allowed = true;
235
+ kvm_irqchip_commit_routes(kvm_state);
236
+ }
237
+
238
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CTRL,
239
+ KVM_DEV_RISCV_AIA_CTRL_INIT,
240
+ NULL, true, NULL);
241
+ if (ret < 0) {
242
+ error_report("KVM AIA: initialized fail");
243
+ exit(1);
244
+ }
245
+
246
+ kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();
247
}
83
--
248
--
84
2.27.0
249
2.41.0
85
86
diff view generated by jsdifflib
1
From: Ian Jiang <ianjiang.ict@gmail.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
The function that makes NaN-boxing when a 32-bit value is assigned
3
KVM AIA can't emulate APLIC only. When "aia=aplic" parameter is passed,
4
to a 64-bit FP register is split out to a helper gen_nanbox_fpr().
4
APLIC devices is emulated by QEMU. For "aia=aplic-imsic", remove the
5
Then it is applied in translating of the FLW instruction.
5
mmio operations of APLIC when using KVM AIA and send wired interrupt
6
signal via KVM_IRQ_LINE API.
7
After KVM AIA enabled, MSI messages are delivered by KVM_SIGNAL_MSI API
8
when the IMSICs receive mmio write requests.
6
9
7
Signed-off-by: Ian Jiang <ianjiang.ict@gmail.com>
10
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
8
Message-Id: <20200128003707.17028-1-ianjiang.ict@gmail.com>
11
Reviewed-by: Jim Shu <jim.shu@sifive.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
14
Message-ID: <20230727102439.22554-5-yongxuan.wang@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
16
---
13
target/riscv/insn_trans/trans_rvf.inc.c | 17 +++++++++++++++--
17
hw/intc/riscv_aplic.c | 56 ++++++++++++++++++++++++++++++-------------
14
1 file changed, 15 insertions(+), 2 deletions(-)
18
hw/intc/riscv_imsic.c | 25 +++++++++++++++----
19
2 files changed, 61 insertions(+), 20 deletions(-)
15
20
16
diff --git a/target/riscv/insn_trans/trans_rvf.inc.c b/target/riscv/insn_trans/trans_rvf.inc.c
21
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
17
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/insn_trans/trans_rvf.inc.c
23
--- a/hw/intc/riscv_aplic.c
19
+++ b/target/riscv/insn_trans/trans_rvf.inc.c
24
+++ b/hw/intc/riscv_aplic.c
20
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@
21
return false; \
26
#include "hw/irq.h"
22
} while (0)
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
23
36
24
+/*
37
+/*
25
+ * RISC-V requires NaN-boxing of narrower width floating
38
+ * KVM AIA only supports APLIC MSI, fallback to QEMU emulation if we want to use
26
+ * point values. This applies when a 32-bit value is
39
+ * APLIC Wired.
27
+ * assigned to a 64-bit FP register. Thus this does not
28
+ * apply when the RVD extension is not present.
29
+ */
40
+ */
30
+static void gen_nanbox_fpr(DisasContext *ctx, int regno)
41
+static bool is_kvm_aia(bool msimode)
31
+{
42
+{
32
+ if (has_ext(ctx, RVD)) {
43
+ return kvm_irqchip_in_kernel() && msimode;
33
+ tcg_gen_ori_i64(cpu_fpr[regno], cpu_fpr[regno],
34
+ MAKE_64BIT_MASK(32, 32));
35
+ }
36
+}
44
+}
37
+
45
+
38
static bool trans_flw(DisasContext *ctx, arg_flw *a)
46
static uint32_t riscv_aplic_read_input_word(RISCVAPLICState *aplic,
47
uint32_t word)
39
{
48
{
40
TCGv t0 = tcg_temp_new();
49
@@ -XXX,XX +XXX,XX @@ static uint32_t riscv_aplic_idc_claimi(RISCVAPLICState *aplic, uint32_t idc)
41
@@ -XXX,XX +XXX,XX @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
50
return topi;
42
tcg_gen_addi_tl(t0, t0, a->imm);
51
}
43
52
44
tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEUL);
53
+static void riscv_kvm_aplic_request(void *opaque, int irq, int level)
45
- /* RISC-V requires NaN-boxing of narrower width floating point values */
54
+{
46
- tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], 0xffffffff00000000ULL);
55
+ kvm_set_irq(kvm_state, irq, !!level);
47
+ gen_nanbox_fpr(ctx, a->rd);
56
+}
48
57
+
49
tcg_temp_free(t0);
58
static void riscv_aplic_request(void *opaque, int irq, int level)
50
mark_fs_dirty(ctx);
59
{
60
bool update = false;
61
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
62
uint32_t i;
63
RISCVAPLICState *aplic = RISCV_APLIC(dev);
64
65
- aplic->bitfield_words = (aplic->num_irqs + 31) >> 5;
66
- aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs);
67
- aplic->state = g_new0(uint32_t, aplic->num_irqs);
68
- aplic->target = g_new0(uint32_t, aplic->num_irqs);
69
- if (!aplic->msimode) {
70
- for (i = 0; i < aplic->num_irqs; i++) {
71
- aplic->target[i] = 1;
72
+ if (!is_kvm_aia(aplic->msimode)) {
73
+ aplic->bitfield_words = (aplic->num_irqs + 31) >> 5;
74
+ aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs);
75
+ aplic->state = g_new0(uint32_t, aplic->num_irqs);
76
+ aplic->target = g_new0(uint32_t, aplic->num_irqs);
77
+ if (!aplic->msimode) {
78
+ for (i = 0; i < aplic->num_irqs; i++) {
79
+ aplic->target[i] = 1;
80
+ }
81
}
82
- }
83
- aplic->idelivery = g_new0(uint32_t, aplic->num_harts);
84
- aplic->iforce = g_new0(uint32_t, aplic->num_harts);
85
- aplic->ithreshold = g_new0(uint32_t, aplic->num_harts);
86
+ aplic->idelivery = g_new0(uint32_t, aplic->num_harts);
87
+ aplic->iforce = g_new0(uint32_t, aplic->num_harts);
88
+ aplic->ithreshold = g_new0(uint32_t, aplic->num_harts);
89
90
- memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops, aplic,
91
- TYPE_RISCV_APLIC, aplic->aperture_size);
92
- sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio);
93
+ memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops,
94
+ aplic, TYPE_RISCV_APLIC, aplic->aperture_size);
95
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio);
96
+ }
97
98
/*
99
* Only root APLICs have hardware IRQ lines. All non-root APLICs
100
* have IRQ lines delegated by their parent APLIC.
101
*/
102
if (!aplic->parent) {
103
- qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
104
+ if (is_kvm_aia(aplic->msimode)) {
105
+ qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs);
106
+ } else {
107
+ qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
108
+ }
109
}
110
111
/* Create output IRQ lines for non-MSI mode */
112
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
113
qdev_prop_set_bit(dev, "mmode", mmode);
114
115
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
116
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
117
+
118
+ if (!is_kvm_aia(msimode)) {
119
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
120
+ }
121
122
if (parent) {
123
riscv_aplic_add_child(parent, dev);
124
diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c
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;
143
+
144
+ msi.address_lo = extract64(imsic->mmio.addr + addr, 0, 32);
145
+ msi.address_hi = extract64(imsic->mmio.addr + addr, 32, 32);
146
+ msi.data = le32_to_cpu(value);
147
+
148
+ kvm_vm_ioctl(kvm_state, KVM_SIGNAL_MSI, &msi);
149
+
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,
51
--
174
--
52
2.27.0
175
2.41.0
53
54
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
SiFive FU540 SoC integrates a GPIO controller with 16 GPIO lines.
3
Select KVM AIA when the host kernel has in-kernel AIA chip support.
4
This hooks the exsiting SiFive GPIO model to the SoC, and adds its
4
Since KVM AIA only has one APLIC instance, we map the QEMU APLIC
5
device tree data as well.
5
devices to KVM APLIC.
6
6
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Jim Shu <jim.shu@sifive.com>
9
Message-id: 1591625864-31494-8-git-send-email-bmeng.cn@gmail.com
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Message-Id: <1591625864-31494-8-git-send-email-bmeng.cn@gmail.com>
10
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
11
Message-ID: <20230727102439.22554-6-yongxuan.wang@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
---
13
include/hw/riscv/sifive_u.h | 19 ++++++++++++++++
14
hw/riscv/virt.c | 94 +++++++++++++++++++++++++++++++++----------------
14
hw/riscv/sifive_u.c | 43 +++++++++++++++++++++++++++++++++++--
15
1 file changed, 63 insertions(+), 31 deletions(-)
15
2 files changed, 60 insertions(+), 2 deletions(-)
16
16
17
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
17
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/riscv/sifive_u.h
19
--- a/hw/riscv/virt.c
20
+++ b/include/hw/riscv/sifive_u.h
20
+++ b/hw/riscv/virt.c
21
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/net/cadence_gem.h"
22
#include "hw/riscv/virt.h"
23
#include "hw/riscv/riscv_hart.h"
23
#include "hw/riscv/boot.h"
24
#include "hw/riscv/sifive_cpu.h"
24
#include "hw/riscv/numa.h"
25
+#include "hw/riscv/sifive_gpio.h"
25
+#include "kvm_riscv.h"
26
#include "hw/riscv/sifive_u_prci.h"
26
#include "hw/intc/riscv_aclint.h"
27
#include "hw/riscv/sifive_u_otp.h"
27
#include "hw/intc/riscv_aplic.h"
28
28
#include "hw/intc/riscv_imsic.h"
29
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveUSoCState {
30
RISCVHartArrayState u_cpus;
31
DeviceState *plic;
32
SiFiveUPRCIState prci;
33
+ SIFIVEGPIOState gpio;
34
SiFiveUOTPState otp;
35
CadenceGEMState gem;
36
37
@@ -XXX,XX +XXX,XX @@ enum {
38
SIFIVE_U_PRCI,
39
SIFIVE_U_UART0,
40
SIFIVE_U_UART1,
41
+ SIFIVE_U_GPIO,
42
SIFIVE_U_OTP,
43
SIFIVE_U_FLASH0,
44
SIFIVE_U_DRAM,
45
@@ -XXX,XX +XXX,XX @@ enum {
46
enum {
47
SIFIVE_U_UART0_IRQ = 4,
48
SIFIVE_U_UART1_IRQ = 5,
49
+ SIFIVE_U_GPIO_IRQ0 = 7,
50
+ SIFIVE_U_GPIO_IRQ1 = 8,
51
+ SIFIVE_U_GPIO_IRQ2 = 9,
52
+ SIFIVE_U_GPIO_IRQ3 = 10,
53
+ SIFIVE_U_GPIO_IRQ4 = 11,
54
+ SIFIVE_U_GPIO_IRQ5 = 12,
55
+ SIFIVE_U_GPIO_IRQ6 = 13,
56
+ SIFIVE_U_GPIO_IRQ7 = 14,
57
+ SIFIVE_U_GPIO_IRQ8 = 15,
58
+ SIFIVE_U_GPIO_IRQ9 = 16,
59
+ SIFIVE_U_GPIO_IRQ10 = 17,
60
+ SIFIVE_U_GPIO_IRQ11 = 18,
61
+ SIFIVE_U_GPIO_IRQ12 = 19,
62
+ SIFIVE_U_GPIO_IRQ13 = 20,
63
+ SIFIVE_U_GPIO_IRQ14 = 21,
64
+ SIFIVE_U_GPIO_IRQ15 = 22,
65
SIFIVE_U_GEM_IRQ = 0x35
66
};
67
68
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/riscv/sifive_u.c
71
+++ b/hw/riscv/sifive_u.c
72
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@
73
* 1) CLINT (Core Level Interruptor)
30
#error "Can't accommodate all IMSIC groups in address space"
74
* 2) PLIC (Platform Level Interrupt Controller)
31
#endif
75
* 3) PRCI (Power, Reset, Clock, Interrupt)
32
76
- * 4) OTP (One-Time Programmable) memory with stored serial number
33
+/* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU. */
77
- * 5) GEM (Gigabit Ethernet Controller) and management block
34
+static bool virt_use_kvm_aia(RISCVVirtState *s)
78
+ * 4) GPIO (General Purpose Input/Output Controller)
35
+{
79
+ * 5) OTP (One-Time Programmable) memory with stored serial number
36
+ return kvm_irqchip_in_kernel() && s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
80
+ * 6) GEM (Gigabit Ethernet Controller) and management block
37
+}
81
*
82
* This board currently generates devicetree dynamically that indicates at least
83
* two harts and up to five harts.
84
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
85
[SIFIVE_U_PRCI] = { 0x10000000, 0x1000 },
86
[SIFIVE_U_UART0] = { 0x10010000, 0x1000 },
87
[SIFIVE_U_UART1] = { 0x10011000, 0x1000 },
88
+ [SIFIVE_U_GPIO] = { 0x10060000, 0x1000 },
89
[SIFIVE_U_OTP] = { 0x10070000, 0x1000 },
90
[SIFIVE_U_FLASH0] = { 0x20000000, 0x10000000 },
91
[SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
92
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
93
g_free(cells);
94
g_free(nodename);
95
96
+ nodename = g_strdup_printf("/soc/gpio@%lx",
97
+ (long)memmap[SIFIVE_U_GPIO].base);
98
+ qemu_fdt_add_subnode(fdt, nodename);
99
+ qemu_fdt_setprop_cells(fdt, nodename, "clocks",
100
+ prci_phandle, PRCI_CLK_TLCLK);
101
+ qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 2);
102
+ qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
103
+ qemu_fdt_setprop_cell(fdt, nodename, "#gpio-cells", 2);
104
+ qemu_fdt_setprop(fdt, nodename, "gpio-controller", NULL, 0);
105
+ qemu_fdt_setprop_cells(fdt, nodename, "reg",
106
+ 0x0, memmap[SIFIVE_U_GPIO].base,
107
+ 0x0, memmap[SIFIVE_U_GPIO].size);
108
+ qemu_fdt_setprop_cells(fdt, nodename, "interrupts", SIFIVE_U_GPIO_IRQ0,
109
+ SIFIVE_U_GPIO_IRQ1, SIFIVE_U_GPIO_IRQ2, SIFIVE_U_GPIO_IRQ3,
110
+ SIFIVE_U_GPIO_IRQ4, SIFIVE_U_GPIO_IRQ5, SIFIVE_U_GPIO_IRQ6,
111
+ SIFIVE_U_GPIO_IRQ7, SIFIVE_U_GPIO_IRQ8, SIFIVE_U_GPIO_IRQ9,
112
+ SIFIVE_U_GPIO_IRQ10, SIFIVE_U_GPIO_IRQ11, SIFIVE_U_GPIO_IRQ12,
113
+ SIFIVE_U_GPIO_IRQ13, SIFIVE_U_GPIO_IRQ14, SIFIVE_U_GPIO_IRQ15);
114
+ qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
115
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,gpio0");
116
+ g_free(nodename);
117
+
38
+
118
phy_phandle = phandle++;
39
static const MemMapEntry virt_memmap[] = {
119
nodename = g_strdup_printf("/soc/ethernet@%lx",
40
[VIRT_DEBUG] = { 0x0, 0x100 },
120
(long)memmap[SIFIVE_U_GEM].base);
41
[VIRT_MROM] = { 0x1000, 0xf000 },
121
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_instance_init(Object *obj)
42
@@ -XXX,XX +XXX,XX @@ static void create_fdt_one_aplic(RISCVVirtState *s, int socket,
122
object_initialize_child(obj, "prci", &s->prci, TYPE_SIFIVE_U_PRCI);
43
uint32_t *intc_phandles,
123
object_initialize_child(obj, "otp", &s->otp, TYPE_SIFIVE_U_OTP);
44
uint32_t aplic_phandle,
124
object_initialize_child(obj, "gem", &s->gem, TYPE_CADENCE_GEM);
45
uint32_t aplic_child_phandle,
125
+ object_initialize_child(obj, "gpio", &s->gpio, TYPE_SIFIVE_GPIO);
46
- bool m_mode)
126
}
47
+ bool m_mode, int num_harts)
127
48
{
128
static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
49
int cpu;
129
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
50
char *aplic_name;
130
sysbus_realize(SYS_BUS_DEVICE(&s->prci), &err);
51
uint32_t *aplic_cells;
131
sysbus_mmio_map(SYS_BUS_DEVICE(&s->prci), 0, memmap[SIFIVE_U_PRCI].base);
52
MachineState *ms = MACHINE(s);
132
53
133
+ qdev_prop_set_uint32(DEVICE(&s->gpio), "ngpio", 16);
54
- aplic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
134
+ sysbus_realize(SYS_BUS_DEVICE(&s->gpio), &err);
55
+ aplic_cells = g_new0(uint32_t, num_harts * 2);
135
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, memmap[SIFIVE_U_GPIO].base);
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;
136
+
125
+
137
+ /* Pass all GPIOs to the SOC layer so they are available to the board */
126
+ if (s->aia_type == VIRT_AIA_TYPE_NONE) {
138
+ qdev_pass_gpios(DEVICE(&s->gpio), dev, NULL);
127
+ create_fdt_socket_plic(s, memmap, socket, phandle,
139
+
128
+ &intc_phandles[phandle_pos],
140
+ /* Connect GPIO interrupts to the PLIC */
129
+ xplic_phandles);
141
+ for (i = 0; i < 16; i++) {
130
+ } else {
142
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), i,
131
+ create_fdt_socket_aplic(s, memmap, socket,
143
+ qdev_get_gpio_in(DEVICE(s->plic),
132
+ msi_m_phandle, msi_s_phandle, phandle,
144
+ SIFIVE_U_GPIO_IRQ0 + i));
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);
145
+ }
185
+ }
146
+
186
+
147
qdev_prop_set_uint32(DEVICE(&s->otp), "serial", s->serial);
187
if (riscv_is_32bit(&s->soc[0])) {
148
sysbus_realize(SYS_BUS_DEVICE(&s->otp), &err);
188
#if HOST_LONG_BITS == 64
149
sysbus_mmio_map(SYS_BUS_DEVICE(&s->otp), 0, memmap[SIFIVE_U_OTP].base);
189
/* limit RAM size in a 32-bit system */
150
--
190
--
151
2.27.0
191
2.41.0
152
153
diff view generated by jsdifflib
1
From: Conor Dooley <conor.dooley@microchip.com>
2
3
On a dtb dumped from the virt machine, dt-validate complains:
4
soc: pmu: {'riscv,event-to-mhpmcounters': [[1, 1, 524281], [2, 2, 524284], [65561, 65561, 524280], [65563, 65563, 524280], [65569, 65569, 524280]], 'compatible': ['riscv,pmu']} should not be valid under {'type': 'object'}
5
from schema $id: http://devicetree.org/schemas/simple-bus.yaml#
6
That's pretty cryptic, but running the dtb back through dtc produces
7
something a lot more reasonable:
8
Warning (simple_bus_reg): /soc/pmu: missing or empty reg/ranges property
9
10
Moving the riscv,pmu node out of the soc bus solves the problem.
11
12
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Message-ID: <20230727-groom-decline-2c57ce42841c@spud>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
3
---
17
---
4
target/riscv/cpu_helper.c | 2 +-
18
hw/riscv/virt.c | 2 +-
5
1 file changed, 1 insertion(+), 1 deletion(-)
19
1 file changed, 1 insertion(+), 1 deletion(-)
6
20
7
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
21
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
8
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
9
--- a/target/riscv/cpu_helper.c
23
--- a/hw/riscv/virt.c
10
+++ b/target/riscv/cpu_helper.c
24
+++ b/hw/riscv/virt.c
11
@@ -XXX,XX +XXX,XX @@ restart:
25
@@ -XXX,XX +XXX,XX @@ static void create_fdt_pmu(RISCVVirtState *s)
12
hwaddr vbase;
26
MachineState *ms = MACHINE(s);
13
27
RISCVCPU hart = s->soc[0].harts[0];
14
/* Do the second stage translation on the base PTE address. */
28
15
- get_physical_address(env, &vbase, &vbase_prot, base, access_type,
29
- pmu_name = g_strdup_printf("/soc/pmu");
16
+ get_physical_address(env, &vbase, &vbase_prot, base, MMU_DATA_LOAD,
30
+ pmu_name = g_strdup_printf("/pmu");
17
mmu_idx, false, true);
31
qemu_fdt_add_subnode(ms->fdt, pmu_name);
18
32
qemu_fdt_setprop_string(ms->fdt, pmu_name, "compatible", "riscv,pmu");
19
pte_addr = vbase + idx * ptesize;
33
riscv_pmu_generate_fdt_node(ms->fdt, hart.cfg.pmu_num, pmu_name);
20
--
34
--
21
2.27.0
35
2.41.0
22
23
diff view generated by jsdifflib
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
2
3
The Svadu specification updated the name of the *envcfg bit from
4
HADE to ADUE.
5
6
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
7
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Message-ID: <20230816141916.66898-1-liweiwei@iscas.ac.cn>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
3
---
11
---
4
target/riscv/cpu_helper.c | 9 +++++++--
12
target/riscv/cpu_bits.h | 8 ++++----
5
1 file changed, 7 insertions(+), 2 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(-)
6
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++) {
7
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
68
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
8
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
9
--- a/target/riscv/cpu_helper.c
70
--- a/target/riscv/cpu_helper.c
10
+++ b/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;
11
@@ -XXX,XX +XXX,XX @@ restart:
86
@@ -XXX,XX +XXX,XX @@ restart:
12
hwaddr vbase;
87
13
88
/* Page table updates need to be atomic with MTTCG enabled */
14
/* Do the second stage translation on the base PTE address. */
89
if (updated_pte != pte && !is_debug) {
15
- get_physical_address(env, &vbase, &vbase_prot, base, MMU_DATA_LOAD,
90
- if (!hade) {
16
- mmu_idx, false, true);
91
+ if (!adue) {
17
+ int vbase_ret = get_physical_address(env, &vbase, &vbase_prot,
92
return TRANSLATE_FAIL;
18
+ base, MMU_DATA_LOAD,
93
}
19
+ mmu_idx, false, true);
94
20
+
95
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
21
+ if (vbase_ret != TRANSLATE_SUCCESS) {
96
index XXXXXXX..XXXXXXX 100644
22
+ return vbase_ret;
97
--- a/target/riscv/csr.c
23
+ }
98
+++ b/target/riscv/csr.c
24
99
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
25
pte_addr = vbase + idx * ptesize;
100
if (riscv_cpu_mxl(env) == MXL_RV64) {
26
} else {
101
mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
102
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
103
- (cfg->ext_svadu ? MENVCFG_HADE : 0);
104
+ (cfg->ext_svadu ? MENVCFG_ADUE : 0);
105
}
106
env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
107
108
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
109
const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
110
uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
111
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
112
- (cfg->ext_svadu ? MENVCFG_HADE : 0);
113
+ (cfg->ext_svadu ? MENVCFG_ADUE : 0);
114
uint64_t valh = (uint64_t)val << 32;
115
116
env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
117
@@ -XXX,XX +XXX,XX @@ static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
118
* henvcfg.stce is read_only 0 when menvcfg.stce = 0
119
* henvcfg.hade is read_only 0 when menvcfg.hade = 0
120
*/
121
- *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) |
122
+ *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
123
env->menvcfg);
124
return RISCV_EXCP_NONE;
125
}
126
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
127
}
128
129
if (riscv_cpu_mxl(env) == MXL_RV64) {
130
- mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE);
131
+ mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE);
132
}
133
134
env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
135
@@ -XXX,XX +XXX,XX @@ static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
136
return ret;
137
}
138
139
- *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_HADE) |
140
+ *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
141
env->menvcfg)) >> 32;
142
return RISCV_EXCP_NONE;
143
}
144
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
145
target_ulong val)
146
{
147
uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE |
148
- HENVCFG_HADE);
149
+ HENVCFG_ADUE);
150
uint64_t valh = (uint64_t)val << 32;
151
RISCVException ret;
152
27
--
153
--
28
2.27.0
154
2.41.0
29
30
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
There is no need to have two functions that have almost the same
3
In the same emulated RISC-V host, the 'host' KVM CPU takes 4 times
4
codes for 32-bit and 64-bit gcsu CPUs.
4
longer to boot than the 'rv64' KVM CPU.
5
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
The reason is an unintended behavior of riscv_cpu_satp_mode_finalize()
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
when satp_mode.supported = 0, i.e. when cpu_init() does not set
8
Message-Id: <1591837729-27486-2-git-send-email-bmeng.cn@gmail.com>
8
satp_mode_max_supported(). satp_mode_max_from_map(map) does:
9
10
31 - __builtin_clz(map)
11
12
This means that, if satp_mode.supported = 0, satp_mode_supported_max
13
wil be '31 - 32'. But this is C, so satp_mode_supported_max will gladly
14
set it to UINT_MAX (4294967295). After that, if the user didn't set a
15
satp_mode, set_satp_mode_default_map(cpu) will make
16
17
cfg.satp_mode.map = cfg.satp_mode.supported
18
19
So satp_mode.map = 0. And then satp_mode_map_max will be set to
20
satp_mode_max_from_map(cpu->cfg.satp_mode.map), i.e. also UINT_MAX. The
21
guard "satp_mode_map_max > satp_mode_supported_max" doesn't protect us
22
here since both are UINT_MAX.
23
24
And finally we have 2 loops:
25
26
for (int i = satp_mode_map_max - 1; i >= 0; --i) {
27
28
Which are, in fact, 2 loops from UINT_MAX -1 to -1. This is where the
29
extra delay when booting the 'host' CPU is coming from.
30
31
Commit 43d1de32f8 already set a precedence for satp_mode.supported = 0
32
in a different manner. We're doing the same here. If supported == 0,
33
interpret as 'the CPU wants the OS to handle satp mode alone' and skip
34
satp_mode_finalize().
35
36
We'll also put a guard in satp_mode_max_from_map() to assert out if map
37
is 0 since the function is not ready to deal with it.
38
39
Cc: Alexandre Ghiti <alexghiti@rivosinc.com>
40
Fixes: 6f23aaeb9b ("riscv: Allow user to set the satp mode")
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>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
44
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
45
---
11
target/riscv/cpu.c | 20 ++++++--------------
46
target/riscv/cpu.c | 23 ++++++++++++++++++++---
12
1 file changed, 6 insertions(+), 14 deletions(-)
47
1 file changed, 20 insertions(+), 3 deletions(-)
13
48
14
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
49
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu.c
51
--- a/target/riscv/cpu.c
17
+++ b/target/riscv/cpu.c
52
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void riscv_base_cpu_init(Object *obj)
53
@@ -XXX,XX +XXX,XX @@ static uint8_t satp_mode_from_str(const char *satp_mode_str)
19
set_resetvec(env, DEFAULT_RSTVEC);
54
55
uint8_t satp_mode_max_from_map(uint32_t map)
56
{
57
+ /*
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);
20
}
70
}
21
71
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
22
-#if defined(TARGET_RISCV32)
72
static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp)
23
-
24
-static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
25
+static void rvxx_gcsu_priv1_10_0_cpu_init(Object *obj)
26
{
73
{
27
CPURISCVState *env = &RISCV_CPU(obj)->env;
74
bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
28
- set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
75
- uint8_t satp_mode_map_max;
29
+ set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
76
- uint8_t satp_mode_supported_max =
30
set_priv_version(env, PRIV_VERSION_1_10_0);
77
- satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
31
set_resetvec(env, DEFAULT_RSTVEC);
78
+ uint8_t satp_mode_map_max, satp_mode_supported_max;
32
}
33
34
+#if defined(TARGET_RISCV32)
35
+
79
+
36
static void rv32imcu_nommu_cpu_init(Object *obj)
80
+ /* The CPU wants the OS to decide which satp mode to use */
37
{
81
+ if (cpu->cfg.satp_mode.supported == 0) {
38
CPURISCVState *env = &RISCV_CPU(obj)->env;
82
+ return;
39
@@ -XXX,XX +XXX,XX @@ static void rv32imafcu_nommu_cpu_init(Object *obj)
83
+ }
40
84
+
41
#elif defined(TARGET_RISCV64)
85
+ satp_mode_supported_max =
42
86
+ satp_mode_max_from_map(cpu->cfg.satp_mode.supported);
43
-static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
87
44
-{
88
if (cpu->cfg.satp_mode.map == 0) {
45
- CPURISCVState *env = &RISCV_CPU(obj)->env;
89
if (cpu->cfg.satp_mode.init == 0) {
46
- set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
47
- set_priv_version(env, PRIV_VERSION_1_10_0);
48
- set_resetvec(env, DEFAULT_RSTVEC);
49
-}
50
-
51
static void rv64imacu_nommu_cpu_init(Object *obj)
52
{
53
CPURISCVState *env = &RISCV_CPU(obj)->env;
54
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
55
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
56
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
57
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
58
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init),
59
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
60
#elif defined(TARGET_RISCV64)
61
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
62
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init),
63
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64gcsu_priv1_10_0_cpu_init),
64
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_gcsu_priv1_10_0_cpu_init),
65
#endif
66
};
67
68
--
90
--
69
2.27.0
91
2.41.0
70
71
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Vineet Gupta <vineetg@rivosinc.com>
2
2
3
There is no need to have two functions that have exactly the same
3
zicond is now codegen supported in both llvm and gcc.
4
codes for 32-bit and 64-bit base CPUs.
5
4
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
5
This change allows seamless enabling/testing of zicond in downstream
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.
9
10
Signed-off-by: Vineet Gupta <vineetg@rivosinc.com>
11
Message-ID: <20230808181715.436395-1-vineetg@rivosinc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1591837729-27486-1-git-send-email-bmeng.cn@gmail.com
9
Message-Id: <1591837729-27486-1-git-send-email-bmeng.cn@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
14
---
12
target/riscv/cpu.c | 18 +++++-------------
15
target/riscv/cpu.c | 2 +-
13
1 file changed, 5 insertions(+), 13 deletions(-)
16
1 file changed, 1 insertion(+), 1 deletion(-)
14
17
15
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
18
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu.c
20
--- a/target/riscv/cpu.c
18
+++ b/target/riscv/cpu.c
21
+++ b/target/riscv/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static void riscv_any_cpu_init(Object *obj)
22
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
20
set_resetvec(env, DEFAULT_RSTVEC);
23
DEFINE_PROP_BOOL("zcf", RISCVCPU, cfg.ext_zcf, false),
21
}
24
DEFINE_PROP_BOOL("zcmp", RISCVCPU, cfg.ext_zcmp, false),
22
25
DEFINE_PROP_BOOL("zcmt", RISCVCPU, cfg.ext_zcmt, false),
23
-#if defined(TARGET_RISCV32)
26
+ DEFINE_PROP_BOOL("zicond", RISCVCPU, cfg.ext_zicond, false),
24
-
27
25
-static void riscv_base32_cpu_init(Object *obj)
28
/* Vendor-specific custom extensions */
26
+static void riscv_base_cpu_init(Object *obj)
29
DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
27
{
30
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
28
CPURISCVState *env = &RISCV_CPU(obj)->env;
31
DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
29
/* We set this in the realise function */
32
30
@@ -XXX,XX +XXX,XX @@ static void riscv_base32_cpu_init(Object *obj)
33
/* These are experimental so mark with 'x-' */
31
set_resetvec(env, DEFAULT_RSTVEC);
34
- DEFINE_PROP_BOOL("x-zicond", RISCVCPU, cfg.ext_zicond, false),
32
}
35
33
36
/* ePMP 0.9.3 */
34
+#if defined(TARGET_RISCV32)
37
DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
35
+
36
static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
37
{
38
CPURISCVState *env = &RISCV_CPU(obj)->env;
39
@@ -XXX,XX +XXX,XX @@ static void rv32imafcu_nommu_cpu_init(Object *obj)
40
41
#elif defined(TARGET_RISCV64)
42
43
-static void riscv_base64_cpu_init(Object *obj)
44
-{
45
- CPURISCVState *env = &RISCV_CPU(obj)->env;
46
- /* We set this in the realise function */
47
- set_misa(env, 0);
48
- set_resetvec(env, DEFAULT_RSTVEC);
49
-}
50
-
51
static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
52
{
53
CPURISCVState *env = &RISCV_CPU(obj)->env;
54
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
55
},
56
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
57
#if defined(TARGET_RISCV32)
58
- DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base32_cpu_init),
59
+ DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
60
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
61
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
62
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
63
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init),
64
#elif defined(TARGET_RISCV64)
65
- DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base64_cpu_init),
66
+ DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
67
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init),
68
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64gcsu_priv1_10_0_cpu_init),
69
#endif
70
--
38
--
71
2.27.0
39
2.41.0
72
73
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
SiFive FU540 SoC supports booting from several sources, which are
3
A build with --enable-debug and without KVM will fail as follows:
4
controlled using the Mode Select (MSEL[3:0]) pins on the chip.
5
Typically, the boot process runs through several stages before it
6
begins execution of user-provided programs.
7
4
8
The SoC supports booting from memory-mapped QSPI flash, which is
5
/usr/bin/ld: libqemu-riscv64-softmmu.fa.p/hw_riscv_virt.c.o: in function `virt_machine_init':
9
how start_in_flash property is used for at present. This matches
6
./qemu/build/../hw/riscv/virt.c:1465: undefined reference to `kvm_riscv_aia_create'
10
MSEL = 1 configuration (QSPI0).
11
7
12
Typical booting flows involve the Zeroth Stage Boot Loader (ZSBL).
8
This happens because the code block with "if virt_use_kvm_aia(s)" isn't
13
It's not necessary for QEMU to implement the full ZSBL ROM codes,
9
being ignored by the debug build, resulting in an undefined reference to
14
because we know ZSBL downloads the next stage program into the L2
10
a KVM only function.
15
LIM at address 0x8000000 and executes from there. We can bypass
16
the whole ZSBL execution and use "-bios" to load the next stage
17
program directly if MSEL indicates a ZSBL booting flow.
18
11
19
Signed-off-by: Bin Meng <bin.meng@windriver.com>
12
Add a 'kvm_enabled()' conditional together with virt_use_kvm_aia() will
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
make the compiler crop the kvm_riscv_aia_create() call entirely from a
21
Message-id: 1592268641-7478-4-git-send-email-bmeng.cn@gmail.com
14
non-KVM build. Note that adding the 'kvm_enabled()' conditional inside
22
Message-Id: <1592268641-7478-4-git-send-email-bmeng.cn@gmail.com>
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>
23
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
24
---
31
---
25
include/hw/riscv/sifive_u.h | 6 ++++++
32
hw/riscv/virt.c | 6 +++---
26
hw/riscv/sifive_u.c | 39 +++++++++++++++++++++++++++++--------
33
1 file changed, 3 insertions(+), 3 deletions(-)
27
2 files changed, 37 insertions(+), 8 deletions(-)
28
34
29
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
35
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
30
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/riscv/sifive_u.h
37
--- a/hw/riscv/virt.c
32
+++ b/include/hw/riscv/sifive_u.h
38
+++ b/hw/riscv/virt.c
33
@@ -XXX,XX +XXX,XX @@ enum {
39
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
34
SIFIVE_U_RTCCLK_FREQ = 1000000
40
}
35
};
41
36
42
/* KVM AIA only has one APLIC instance */
37
+enum {
43
- if (virt_use_kvm_aia(s)) {
38
+ MSEL_MEMMAP_QSPI0_FLASH = 1,
44
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
39
+ MSEL_L2LIM_QSPI0_FLASH = 6,
45
create_fdt_socket_aplic(s, memmap, 0,
40
+ MSEL_L2LIM_QSPI2_SD = 11
46
msi_m_phandle, msi_s_phandle, phandle,
41
+};
47
&intc_phandles[0], xplic_phandles,
42
+
48
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
43
#define SIFIVE_U_MANAGEMENT_CPU_COUNT 1
49
44
#define SIFIVE_U_COMPUTE_CPU_COUNT 4
50
g_free(intc_phandles);
45
51
46
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
52
- if (virt_use_kvm_aia(s)) {
47
index XXXXXXX..XXXXXXX 100644
53
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
48
--- a/hw/riscv/sifive_u.c
54
*irq_mmio_phandle = xplic_phandles[0];
49
+++ b/hw/riscv/sifive_u.c
55
*irq_virtio_phandle = xplic_phandles[0];
50
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
56
*irq_pcie_phandle = xplic_phandles[0];
51
/* create device tree */
57
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
52
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
53
54
- riscv_find_and_load_firmware(machine, BIOS_FILENAME,
55
- memmap[SIFIVE_U_DRAM].base, NULL);
56
+ if (s->start_in_flash) {
57
+ /*
58
+ * If start_in_flash property is given, assign s->msel to a value
59
+ * that representing booting from QSPI0 memory-mapped flash.
60
+ *
61
+ * This also means that when both start_in_flash and msel properties
62
+ * are given, start_in_flash takes the precedence over msel.
63
+ *
64
+ * Note this is to keep backward compatibility not to break existing
65
+ * users that use start_in_flash property.
66
+ */
67
+ s->msel = MSEL_MEMMAP_QSPI0_FLASH;
68
+ }
69
+
70
+ switch (s->msel) {
71
+ case MSEL_MEMMAP_QSPI0_FLASH:
72
+ start_addr = memmap[SIFIVE_U_FLASH0].base;
73
+ break;
74
+ case MSEL_L2LIM_QSPI0_FLASH:
75
+ case MSEL_L2LIM_QSPI2_SD:
76
+ start_addr = memmap[SIFIVE_U_L2LIM].base;
77
+ break;
78
+ default:
79
+ start_addr = memmap[SIFIVE_U_DRAM].base;
80
+ break;
81
+ }
82
+
83
+ riscv_find_and_load_firmware(machine, BIOS_FILENAME, start_addr, NULL);
84
85
if (machine->kernel_filename) {
86
uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename,
87
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
88
}
58
}
89
}
59
}
90
60
91
- if (s->start_in_flash) {
61
- if (virt_use_kvm_aia(s)) {
92
- start_addr = memmap[SIFIVE_U_FLASH0].base;
62
+ if (kvm_enabled() && virt_use_kvm_aia(s)) {
93
- }
63
kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT,
94
-
64
VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS,
95
/* reset vector */
65
memmap[VIRT_APLIC_S].base,
96
uint32_t reset_vec[8] = {
97
- 0x00000000,
98
+ s->msel, /* MSEL pin state */
99
0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
100
0x01c28593, /* addi a1, t0, %pcrel_lo(1b) */
101
0xf1402573, /* csrr a0, mhartid */
102
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_instance_init(Object *obj)
103
sifive_u_machine_set_start_in_flash);
104
object_property_set_description(obj, "start-in-flash",
105
"Set on to tell QEMU's ROM to jump to "
106
- "flash. Otherwise QEMU will jump to DRAM");
107
+ "flash. Otherwise QEMU will jump to DRAM "
108
+ "or L2LIM depending on the msel value");
109
110
s->msel = 0;
111
object_property_add(obj, "msel", "uint32",
112
--
66
--
113
2.27.0
67
2.41.0
114
68
115
69
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
3
Commit 6df0b37e2ab breaks a --enable-debug build in a non-KVM
4
environment with the following error:
5
6
/usr/bin/ld: libqemu-riscv64-softmmu.fa.p/hw_intc_riscv_aplic.c.o: in function `riscv_kvm_aplic_request':
7
./qemu/build/../hw/intc/riscv_aplic.c:486: undefined reference to `kvm_set_irq'
8
collect2: error: ld returned 1 exit status
9
10
This happens because the debug build will poke into the
11
'if (is_kvm_aia(aplic->msimode))' block and fail to find a reference to
12
the KVM only function riscv_kvm_aplic_request().
13
14
There are multiple solutions to fix this. We'll go with the same
15
solution from the previous patch, i.e. add a kvm_enabled() conditional
16
to filter out the block. But there's a catch: riscv_kvm_aplic_request()
17
is a local function that would end up being used if the compiler crops
18
the block, and this won't work. Quoting Richard Henderson's explanation
19
in [1]:
20
21
"(...) the compiler won't eliminate entire unused functions with -O0"
22
23
We'll solve it by moving riscv_kvm_aplic_request() to kvm.c and add its
24
declaration in kvm_riscv.h, where all other KVM specific public
25
functions are already declared. Other archs handles KVM specific code in
26
this manner and we expect to do the same from now on.
27
28
[1] https://lore.kernel.org/qemu-riscv/d2f1ad02-eb03-138f-9d08-db676deeed05@linaro.org/
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>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
---
36
---
3
include/hw/riscv/sifive_e.h | 1 +
37
target/riscv/kvm_riscv.h | 1 +
4
hw/riscv/sifive_e.c | 34 ++++++++++++++++++++++++++++++----
38
hw/intc/riscv_aplic.c | 8 ++------
5
2 files changed, 31 insertions(+), 4 deletions(-)
39
target/riscv/kvm.c | 5 +++++
40
3 files changed, 8 insertions(+), 6 deletions(-)
6
41
7
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
42
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
8
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
9
--- a/include/hw/riscv/sifive_e.h
44
--- a/target/riscv/kvm_riscv.h
10
+++ b/include/hw/riscv/sifive_e.h
45
+++ b/target/riscv/kvm_riscv.h
11
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveEState {
46
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
12
47
uint64_t aia_irq_num, uint64_t aia_msi_num,
13
/*< public >*/
48
uint64_t aplic_base, uint64_t imsic_base,
14
SiFiveESoCState soc;
49
uint64_t guest_num);
15
+ bool revb;
50
+void riscv_kvm_aplic_request(void *opaque, int irq, int level);
16
} SiFiveEState;
51
17
52
#endif
18
#define TYPE_RISCV_E_MACHINE MACHINE_TYPE_NAME("sifive_e")
53
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
19
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
20
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/riscv/sifive_e.c
55
--- a/hw/intc/riscv_aplic.c
22
+++ b/hw/riscv/sifive_e.c
56
+++ b/hw/intc/riscv_aplic.c
23
@@ -XXX,XX +XXX,XX @@ static void riscv_sifive_e_init(MachineState *machine)
57
@@ -XXX,XX +XXX,XX @@
24
memmap[SIFIVE_E_DTIM].base, main_mem);
58
#include "target/riscv/cpu.h"
25
59
#include "sysemu/sysemu.h"
26
/* Mask ROM reset vector */
60
#include "sysemu/kvm.h"
27
- uint32_t reset_vec[2] = {
61
+#include "kvm_riscv.h"
28
- 0x204002b7, /* 0x1000: lui t0,0x20400 */
62
#include "migration/vmstate.h"
29
- 0x00028067, /* 0x1004: jr t0 */
63
30
- };
64
#define APLIC_MAX_IDC (1UL << 14)
31
+ uint32_t reset_vec[2];
65
@@ -XXX,XX +XXX,XX @@ static uint32_t riscv_aplic_idc_claimi(RISCVAPLICState *aplic, uint32_t idc)
32
+
66
return topi;
33
+ if (s->revb) {
34
+ reset_vec[0] = 0x200102b7; /* 0x1000: lui t0,0x20010 */
35
+ } else {
36
+ reset_vec[0] = 0x204002b7; /* 0x1000: lui t0,0x20400 */
37
+ }
38
+ reset_vec[1] = 0x00028067; /* 0x1004: jr t0 */
39
40
/* copy in the reset vector in little_endian byte order */
41
for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
42
@@ -XXX,XX +XXX,XX @@ static void riscv_sifive_e_init(MachineState *machine)
43
}
44
}
67
}
45
68
46
+static bool sifive_e_machine_get_revb(Object *obj, Error **errp)
69
-static void riscv_kvm_aplic_request(void *opaque, int irq, int level)
70
-{
71
- kvm_set_irq(kvm_state, irq, !!level);
72
-}
73
-
74
static void riscv_aplic_request(void *opaque, int irq, int level)
75
{
76
bool update = false;
77
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
78
* have IRQ lines delegated by their parent APLIC.
79
*/
80
if (!aplic->parent) {
81
- if (is_kvm_aia(aplic->msimode)) {
82
+ if (kvm_enabled() && is_kvm_aia(aplic->msimode)) {
83
qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs);
84
} else {
85
qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
86
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/riscv/kvm.c
89
+++ b/target/riscv/kvm.c
90
@@ -XXX,XX +XXX,XX @@
91
#include "sysemu/runstate.h"
92
#include "hw/riscv/numa.h"
93
94
+void riscv_kvm_aplic_request(void *opaque, int irq, int level)
47
+{
95
+{
48
+ SiFiveEState *s = RISCV_E_MACHINE(obj);
96
+ kvm_set_irq(kvm_state, irq, !!level);
49
+
50
+ return s->revb;
51
+}
97
+}
52
+
98
+
53
+static void sifive_e_machine_set_revb(Object *obj, bool value, Error **errp)
99
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
54
+{
100
uint64_t idx)
55
+ SiFiveEState *s = RISCV_E_MACHINE(obj);
56
+
57
+ s->revb = value;
58
+}
59
+
60
static void sifive_e_machine_instance_init(Object *obj)
61
{
101
{
62
+ SiFiveEState *s = RISCV_E_MACHINE(obj);
63
+
64
+ s->revb = false;
65
+ object_property_add_bool(obj, "revb", sifive_e_machine_get_revb,
66
+ sifive_e_machine_set_revb);
67
+ object_property_set_description(obj, "revb",
68
+ "Set on to tell QEMU that it should model "
69
+ "the revB HiFive1 board");
70
}
71
72
static void sifive_e_machine_class_init(ObjectClass *oc, void *data)
73
--
102
--
74
2.27.0
103
2.41.0
75
104
76
105
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Robbin Ehn <rehn@rivosinc.com>
2
2
3
Upstream U-Boot v2020.07 codes switch to access SiFive FU540 OTP
3
This patch adds the new extensions in
4
based on device tree information. Let's generate the device tree
4
linux 6.5 to the hwprobe syscall.
5
node for OTP.
6
5
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
And fixes RVC check to OR with correct value.
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
The previous variable contains 0 therefore it
9
Message-id: 1591625864-31494-5-git-send-email-bmeng.cn@gmail.com
8
did work.
10
Message-Id: <1591625864-31494-5-git-send-email-bmeng.cn@gmail.com>
9
10
Signed-off-by: Robbin Ehn <rehn@rivosinc.com>
11
Acked-by: Richard Henderson <richard.henderson@linaro.org>
12
Acked-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <bc82203b72d7efb30f1b4a8f9eb3d94699799dc8.camel@rivosinc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
15
---
13
hw/riscv/sifive_u.c | 11 +++++++++++
16
linux-user/syscall.c | 14 +++++++++++++-
14
1 file changed, 11 insertions(+)
17
1 file changed, 13 insertions(+), 1 deletion(-)
15
18
16
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
19
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/sifive_u.c
21
--- a/linux-user/syscall.c
19
+++ b/hw/riscv/sifive_u.c
22
+++ b/linux-user/syscall.c
20
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
23
@@ -XXX,XX +XXX,XX @@ static int do_getdents64(abi_long dirfd, abi_long arg2, abi_long count)
21
g_free(cells);
24
#define RISCV_HWPROBE_KEY_IMA_EXT_0 4
22
g_free(nodename);
25
#define RISCV_HWPROBE_IMA_FD (1 << 0)
23
26
#define RISCV_HWPROBE_IMA_C (1 << 1)
24
+ nodename = g_strdup_printf("/soc/otp@%lx",
27
+#define RISCV_HWPROBE_IMA_V (1 << 2)
25
+ (long)memmap[SIFIVE_U_OTP].base);
28
+#define RISCV_HWPROBE_EXT_ZBA (1 << 3)
26
+ qemu_fdt_add_subnode(fdt, nodename);
29
+#define RISCV_HWPROBE_EXT_ZBB (1 << 4)
27
+ qemu_fdt_setprop_cell(fdt, nodename, "fuse-count", SIFIVE_U_OTP_REG_SIZE);
30
+#define RISCV_HWPROBE_EXT_ZBS (1 << 5)
28
+ qemu_fdt_setprop_cells(fdt, nodename, "reg",
31
29
+ 0x0, memmap[SIFIVE_U_OTP].base,
32
#define RISCV_HWPROBE_KEY_CPUPERF_0 5
30
+ 0x0, memmap[SIFIVE_U_OTP].size);
33
#define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
31
+ qemu_fdt_setprop_string(fdt, nodename, "compatible",
34
@@ -XXX,XX +XXX,XX @@ static void risc_hwprobe_fill_pairs(CPURISCVState *env,
32
+ "sifive,fu540-c000-otp");
35
riscv_has_ext(env, RVD) ?
33
+ g_free(nodename);
36
RISCV_HWPROBE_IMA_FD : 0;
34
+
37
value |= riscv_has_ext(env, RVC) ?
35
prci_phandle = phandle++;
38
- RISCV_HWPROBE_IMA_C : pair->value;
36
nodename = g_strdup_printf("/soc/clock-controller@%lx",
39
+ RISCV_HWPROBE_IMA_C : 0;
37
(long)memmap[SIFIVE_U_PRCI].base);
40
+ value |= riscv_has_ext(env, RVV) ?
41
+ RISCV_HWPROBE_IMA_V : 0;
42
+ value |= cfg->ext_zba ?
43
+ RISCV_HWPROBE_EXT_ZBA : 0;
44
+ value |= cfg->ext_zbb ?
45
+ RISCV_HWPROBE_EXT_ZBB : 0;
46
+ value |= cfg->ext_zbs ?
47
+ RISCV_HWPROBE_EXT_ZBS : 0;
48
__put_user(value, &pair->value);
49
break;
50
case RISCV_HWPROBE_KEY_CPUPERF_0:
38
--
51
--
39
2.27.0
52
2.41.0
40
41
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Ard Biesheuvel <ardb@kernel.org>
2
2
3
Do various minor clean-ups to the exisiting codes for:
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
- coding convention conformance
8
Cc: Richard Henderson <richard.henderson@linaro.org>
6
- remove unnecessary blank lines
9
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
7
- spell SiFive correctly
10
Cc: Palmer Dabbelt <palmer@dabbelt.com>
8
11
Cc: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Bin Meng <bin.meng@windriver.com>
12
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 1591625864-31494-6-git-send-email-bmeng.cn@gmail.com
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-Id: <1591625864-31494-6-git-send-email-bmeng.cn@gmail.com>
15
Message-ID: <20230831154118.138727-1-ardb@kernel.org>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
17
---
15
include/hw/riscv/sifive_gpio.h | 7 ++++---
18
target/riscv/crypto_helper.c | 17 +++++------------
16
hw/riscv/sifive_gpio.c | 13 +++++--------
19
1 file changed, 5 insertions(+), 12 deletions(-)
17
2 files changed, 9 insertions(+), 11 deletions(-)
18
20
19
diff --git a/include/hw/riscv/sifive_gpio.h b/include/hw/riscv/sifive_gpio.h
21
diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c
20
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/riscv/sifive_gpio.h
23
--- a/target/riscv/crypto_helper.c
22
+++ b/include/hw/riscv/sifive_gpio.h
24
+++ b/target/riscv/crypto_helper.c
23
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(aes64ks1i)(target_ulong rs1, target_ulong rnum)
24
/*
26
25
- * sifive System-on-Chip general purpose input/output register definition
27
uint8_t enc_rnum = rnum;
26
+ * SiFive System-on-Chip general purpose input/output register definition
28
uint32_t temp = (RS1 >> 32) & 0xFFFFFFFF;
27
*
29
- uint8_t rcon_ = 0;
28
* Copyright 2019 AdaCore
30
- target_ulong result;
29
*
31
+ AESState t, rc = {};
30
@@ -XXX,XX +XXX,XX @@
32
31
* This code is licensed under the GPL version 2 or later. See
33
if (enc_rnum != 0xA) {
32
* the COPYING file in the top-level directory.
34
temp = ror32(temp, 8); /* Rotate right by 8 */
33
*/
35
- rcon_ = round_consts[enc_rnum];
34
+
36
+ rc.w[0] = rc.w[1] = round_consts[enc_rnum];
35
#ifndef SIFIVE_GPIO_H
37
}
36
#define SIFIVE_GPIO_H
38
37
39
- temp = ((uint32_t)AES_sbox[(temp >> 24) & 0xFF] << 24) |
38
#include "hw/sysbus.h"
40
- ((uint32_t)AES_sbox[(temp >> 16) & 0xFF] << 16) |
39
+
41
- ((uint32_t)AES_sbox[(temp >> 8) & 0xFF] << 8) |
40
#define TYPE_SIFIVE_GPIO "sifive_soc.gpio"
42
- ((uint32_t)AES_sbox[(temp >> 0) & 0xFF] << 0);
41
#define SIFIVE_GPIO(obj) OBJECT_CHECK(SIFIVEGPIOState, (obj), TYPE_SIFIVE_GPIO)
43
+ t.w[0] = t.w[1] = t.w[2] = t.w[3] = temp;
42
44
+ aesenc_SB_SR_AK(&t, &t, &rc, false);
43
@@ -XXX,XX +XXX,XX @@ typedef struct SIFIVEGPIOState {
45
44
uint32_t out_xor;
46
- temp ^= rcon_;
45
uint32_t in;
46
uint32_t in_mask;
47
-
47
-
48
} SIFIVEGPIOState;
48
- result = ((uint64_t)temp << 32) | temp;
49
50
-#endif
51
+#endif /* SIFIVE_GPIO_H */
52
diff --git a/hw/riscv/sifive_gpio.c b/hw/riscv/sifive_gpio.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/riscv/sifive_gpio.c
55
+++ b/hw/riscv/sifive_gpio.c
56
@@ -XXX,XX +XXX,XX @@
57
/*
58
- * sifive System-on-Chip general purpose input/output register definition
59
+ * SiFive System-on-Chip general purpose input/output register definition
60
*
61
* Copyright 2019 AdaCore
62
*
63
@@ -XXX,XX +XXX,XX @@
64
65
static void update_output_irq(SIFIVEGPIOState *s)
66
{
67
-
49
-
68
uint32_t pending;
50
- return result;
69
uint32_t pin;
51
+ return t.d[0];
70
71
@@ -XXX,XX +XXX,XX @@ static uint64_t sifive_gpio_read(void *opaque, hwaddr offset, unsigned int size)
72
}
52
}
73
53
74
static void sifive_gpio_write(void *opaque, hwaddr offset,
54
target_ulong HELPER(aes64im)(target_ulong rs1)
75
- uint64_t value, unsigned int size)
76
+ uint64_t value, unsigned int size)
77
{
78
SIFIVEGPIOState *s = SIFIVE_GPIO(opaque);
79
80
@@ -XXX,XX +XXX,XX @@ static void sifive_gpio_reset(DeviceState *dev)
81
s->out_xor = 0;
82
s->in = 0;
83
s->in_mask = 0;
84
-
85
}
86
87
static const VMStateDescription vmstate_sifive_gpio = {
88
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_sifive_gpio = {
89
VMSTATE_UINT32(iof_en, SIFIVEGPIOState),
90
VMSTATE_UINT32(iof_sel, SIFIVEGPIOState),
91
VMSTATE_UINT32(out_xor, SIFIVEGPIOState),
92
- VMSTATE_UINT32(in, SIFIVEGPIOState),
93
- VMSTATE_UINT32(in_mask, SIFIVEGPIOState),
94
+ VMSTATE_UINT32(in, SIFIVEGPIOState),
95
+ VMSTATE_UINT32(in_mask, SIFIVEGPIOState),
96
VMSTATE_END_OF_LIST()
97
}
98
};
99
@@ -XXX,XX +XXX,XX @@ static void sifive_gpio_init(Object *obj)
100
TYPE_SIFIVE_GPIO, SIFIVE_GPIO_SIZE);
101
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
102
103
-
104
for (int i = 0; i < SIFIVE_GPIO_PINS; i++) {
105
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq[i]);
106
}
107
@@ -XXX,XX +XXX,XX @@ static void sifive_gpio_class_init(ObjectClass *klass, void *data)
108
109
dc->vmsd = &vmstate_sifive_gpio;
110
dc->reset = sifive_gpio_reset;
111
- dc->desc = "sifive GPIO";
112
+ dc->desc = "SiFive GPIO";
113
}
114
115
static const TypeInfo sifive_gpio_info = {
116
--
55
--
117
2.27.0
56
2.41.0
118
57
119
58
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Akihiko Odaki <akihiko.odaki@daynix.com>
2
2
3
The HiFive Unleashed board wires GPIO pin#10 to the input of the
3
riscv_trigger_init() had been called on reset events that can happen
4
system reset signal. Let's set up the GPIO pin#10 and insert a
4
several times for a CPU and it allocated timers for itrigger. If old
5
"gpio-restart" device tree node so that reboot is now functional
5
timers were present, they were simply overwritten by the new timers,
6
with QEMU 'sifive_u' machine.
6
resulting in a memory leak.
7
7
8
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Divide riscv_trigger_init() into two functions, namely
9
riscv_trigger_realize() and riscv_trigger_reset() and call them in
10
appropriate timing. The timer allocation will happen only once for a
11
CPU in riscv_trigger_realize().
12
13
Fixes: 5a4ae64cac ("target/riscv: Add itrigger support when icount is enabled")
14
Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 1591625864-31494-10-git-send-email-bmeng.cn@gmail.com
18
Message-ID: <20230818034059.9146-1-akihiko.odaki@daynix.com>
11
Message-Id: <1591625864-31494-10-git-send-email-bmeng.cn@gmail.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
20
---
14
hw/riscv/sifive_u.c | 24 +++++++++++++++++++++++-
21
target/riscv/debug.h | 3 ++-
15
1 file changed, 23 insertions(+), 1 deletion(-)
22
target/riscv/cpu.c | 8 +++++++-
23
target/riscv/debug.c | 15 ++++++++++++---
24
3 files changed, 21 insertions(+), 5 deletions(-)
16
25
17
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
26
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
18
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/riscv/sifive_u.c
28
--- a/target/riscv/debug.h
20
+++ b/hw/riscv/sifive_u.c
29
+++ b/target/riscv/debug.h
21
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_debug_excp_handler(CPUState *cs);
22
#include "qapi/error.h"
31
bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
23
#include "qapi/visitor.h"
32
bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
24
#include "hw/boards.h"
33
25
+#include "hw/irq.h"
34
-void riscv_trigger_init(CPURISCVState *env);
26
#include "hw/loader.h"
35
+void riscv_trigger_realize(CPURISCVState *env);
27
#include "hw/sysbus.h"
36
+void riscv_trigger_reset_hold(CPURISCVState *env);
28
#include "hw/char/serial.h"
37
29
@@ -XXX,XX +XXX,XX @@
38
bool riscv_itrigger_enabled(CPURISCVState *env);
30
#include "net/eth.h"
39
void riscv_itrigger_update_priv(CPURISCVState *env);
31
#include "sysemu/arch_init.h"
40
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
32
#include "sysemu/device_tree.h"
41
index XXXXXXX..XXXXXXX 100644
33
+#include "sysemu/runstate.h"
42
--- a/target/riscv/cpu.c
34
#include "sysemu/sysemu.h"
43
+++ b/target/riscv/cpu.c
35
#include "exec/address-spaces.h"
44
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj)
36
45
37
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
46
#ifndef CONFIG_USER_ONLY
38
uint32_t *cells;
47
if (cpu->cfg.debug) {
39
char *nodename;
48
- riscv_trigger_init(env);
40
char ethclk_names[] = "pclk\0hclk";
49
+ riscv_trigger_reset_hold(env);
41
- uint32_t plic_phandle, prci_phandle, phandle = 1;
50
}
42
+ uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1;
51
43
uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
52
if (kvm_enabled()) {
44
53
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
45
fdt = s->fdt = create_device_tree(&s->fdt_size);
54
46
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
55
riscv_cpu_register_gdb_regs_for_features(cs);
47
g_free(cells);
56
48
g_free(nodename);
57
+#ifndef CONFIG_USER_ONLY
49
58
+ if (cpu->cfg.debug) {
50
+ gpio_phandle = phandle++;
59
+ riscv_trigger_realize(&cpu->env);
51
nodename = g_strdup_printf("/soc/gpio@%lx",
60
+ }
52
(long)memmap[SIFIVE_U_GPIO].base);
61
+#endif
53
qemu_fdt_add_subnode(fdt, nodename);
54
+ qemu_fdt_setprop_cell(fdt, nodename, "phandle", gpio_phandle);
55
qemu_fdt_setprop_cells(fdt, nodename, "clocks",
56
prci_phandle, PRCI_CLK_TLCLK);
57
qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 2);
58
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
59
qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,gpio0");
60
g_free(nodename);
61
62
+ nodename = g_strdup_printf("/gpio-restart");
63
+ qemu_fdt_add_subnode(fdt, nodename);
64
+ qemu_fdt_setprop_cells(fdt, nodename, "gpios", gpio_phandle, 10, 1);
65
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "gpio-restart");
66
+ g_free(nodename);
67
+
62
+
68
phy_phandle = phandle++;
63
qemu_init_vcpu(cs);
69
nodename = g_strdup_printf("/soc/ethernet@%lx",
64
cpu_reset(cs);
70
(long)memmap[SIFIVE_U_GEM].base);
65
71
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
66
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
72
g_free(nodename);
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/debug.c
69
+++ b/target/riscv/debug.c
70
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
71
return false;
73
}
72
}
74
73
75
+static void sifive_u_machine_reset(void *opaque, int n, int level)
74
-void riscv_trigger_init(CPURISCVState *env)
75
+void riscv_trigger_realize(CPURISCVState *env)
76
+{
76
+{
77
+ /* gpio pin active low triggers reset */
77
+ int i;
78
+ if (!level) {
78
+
79
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
79
+ for (i = 0; i < RV_MAX_TRIGGERS; i++) {
80
+ env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
81
+ riscv_itrigger_timer_cb, env);
80
+ }
82
+ }
81
+}
83
+}
82
+
84
+
83
static void sifive_u_machine_init(MachineState *machine)
85
+void riscv_trigger_reset_hold(CPURISCVState *env)
84
{
86
{
85
const struct MemmapEntry *memmap = sifive_u_memmap;
87
target_ulong tdata1 = build_tdata1(env, TRIGGER_TYPE_AD_MATCH, 0, 0);
86
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
88
int i;
87
memory_region_add_subregion(system_memory, memmap[SIFIVE_U_FLASH0].base,
89
@@ -XXX,XX +XXX,XX @@ void riscv_trigger_init(CPURISCVState *env)
88
flash0);
90
env->tdata3[i] = 0;
89
91
env->cpu_breakpoint[i] = NULL;
90
+ /* register gpio-restart */
92
env->cpu_watchpoint[i] = NULL;
91
+ qdev_connect_gpio_out(DEVICE(&(s->soc.gpio)), 10,
93
- env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
92
+ qemu_allocate_irq(sifive_u_machine_reset, NULL, 0));
94
- riscv_itrigger_timer_cb, env);
93
+
95
+ timer_del(env->itrigger_timer[i]);
94
/* create device tree */
96
}
95
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
97
}
96
97
--
98
--
98
2.27.0
99
2.41.0
99
100
100
101
diff view generated by jsdifflib
1
From: Leon Schuermann <leons@opentitan.org>
2
3
When the rule-lock bypass (RLB) bit is set in the mseccfg CSR, the PMP
4
configuration lock bits must not apply. While this behavior is
5
implemented for the pmpcfgX CSRs, this bit is not respected for
6
changes to the pmpaddrX CSRs. This patch ensures that pmpaddrX CSR
7
writes work even on locked regions when the global rule-lock bypass is
8
enabled.
9
10
Signed-off-by: Leon Schuermann <leons@opentitan.org>
11
Reviewed-by: Mayuresh Chitale <mchitale@ventanamicro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <20230829215046.1430463-1-leon@is.currently.online>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Bin Meng <bin.meng@windriver.com>
3
---
15
---
4
target/riscv/pmp.c | 14 +++++++++-----
16
target/riscv/pmp.c | 4 ++++
5
1 file changed, 9 insertions(+), 5 deletions(-)
17
1 file changed, 4 insertions(+)
6
18
7
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
19
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
8
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
9
--- a/target/riscv/pmp.c
21
--- a/target/riscv/pmp.c
10
+++ b/target/riscv/pmp.c
22
+++ b/target/riscv/pmp.c
11
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
23
@@ -XXX,XX +XXX,XX @@ static inline uint8_t pmp_get_a_field(uint8_t cfg)
12
return true;
24
*/
13
}
25
static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
14
26
{
15
- /*
27
+ /* mseccfg.RLB is set */
16
- * if size is unknown (0), assume that all bytes
28
+ if (MSECCFG_RLB_ISSET(env)) {
17
- * from addr to the end of the page will be accessed.
29
+ return 0;
18
- */
30
+ }
19
if (size == 0) {
31
20
- pmp_size = -(addr | TARGET_PAGE_MASK);
32
if (env->pmp_state.pmp[pmp_index].cfg_reg & PMP_LOCK) {
21
+ if (riscv_feature(env, RISCV_FEATURE_MMU)) {
33
return 1;
22
+ /*
23
+ * If size is unknown (0), assume that all bytes
24
+ * from addr to the end of the page will be accessed.
25
+ */
26
+ pmp_size = -(addr | TARGET_PAGE_MASK);
27
+ } else {
28
+ pmp_size = sizeof(target_ulong);
29
+ }
30
} else {
31
pmp_size = size;
32
}
33
--
34
--
34
2.27.0
35
2.41.0
35
36
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Tommy Wu <tommy.wu@sifive.com>
2
2
3
There is no need to retrieve all PLIC IRQ information in order to
3
According to the new spec, when vsiselect has a reserved value, attempts
4
just connect the GEM IRQ. Use qdev_get_gpio_in() directly like
4
from M-mode or HS-mode to access vsireg, or from VS-mode to access
5
what is done for other peripherals.
5
sireg, should preferably raise an illegal instruction exception.
6
6
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
9
Message-id: 1591625864-31494-4-git-send-email-bmeng.cn@gmail.com
9
Message-ID: <20230816061647.600672-1-tommy.wu@sifive.com>
10
Message-Id: <1591625864-31494-4-git-send-email-bmeng.cn@gmail.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
11
---
13
hw/riscv/sifive_u.c | 7 +------
12
target/riscv/csr.c | 7 +++++--
14
1 file changed, 1 insertion(+), 6 deletions(-)
13
1 file changed, 5 insertions(+), 2 deletions(-)
15
14
16
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/sifive_u.c
17
--- a/target/riscv/csr.c
19
+++ b/hw/riscv/sifive_u.c
18
+++ b/target/riscv/csr.c
20
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
19
@@ -XXX,XX +XXX,XX @@ static int rmw_iprio(target_ulong xlen,
21
MemoryRegion *system_memory = get_system_memory();
20
static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
22
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
21
target_ulong new_val, target_ulong wr_mask)
23
MemoryRegion *l2lim_mem = g_new(MemoryRegion, 1);
22
{
24
- qemu_irq plic_gpios[SIFIVE_U_PLIC_NUM_SOURCES];
23
- bool virt;
25
char *plic_hart_config;
24
+ bool virt, isel_reserved;
26
size_t plic_hart_config_len;
25
uint8_t *iprio;
27
int i;
26
int ret = -EINVAL;
28
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
27
target_ulong priv, isel, vgein;
29
sysbus_realize(SYS_BUS_DEVICE(&s->otp), &err);
28
@@ -XXX,XX +XXX,XX @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
30
sysbus_mmio_map(SYS_BUS_DEVICE(&s->otp), 0, memmap[SIFIVE_U_OTP].base);
29
31
30
/* Decode register details from CSR number */
32
- for (i = 0; i < SIFIVE_U_PLIC_NUM_SOURCES; i++) {
31
virt = false;
33
- plic_gpios[i] = qdev_get_gpio_in(DEVICE(s->plic), i);
32
+ isel_reserved = false;
34
- }
33
switch (csrno) {
35
-
34
case CSR_MIREG:
36
if (nd->used) {
35
iprio = env->miprio;
37
qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
36
@@ -XXX,XX +XXX,XX @@ static int rmw_xireg(CPURISCVState *env, int csrno, target_ulong *val,
38
qdev_set_nic_properties(DEVICE(&s->gem), nd);
37
riscv_cpu_mxl_bits(env)),
39
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
38
val, new_val, wr_mask);
39
}
40
+ } else {
41
+ isel_reserved = true;
40
}
42
}
41
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gem), 0, memmap[SIFIVE_U_GEM].base);
43
42
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gem), 0,
44
done:
43
- plic_gpios[SIFIVE_U_GEM_IRQ]);
45
if (ret) {
44
+ qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_GEM_IRQ));
46
- return (env->virt_enabled && virt) ?
45
47
+ return (env->virt_enabled && virt && !isel_reserved) ?
46
create_unimplemented_device("riscv.sifive.u.gem-mgmt",
48
RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
47
memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
49
}
50
return RISCV_EXCP_NONE;
48
--
51
--
49
2.27.0
52
2.41.0
50
51
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Nikita Shubin <n.shubin@yadro.com>
2
2
3
Add a new property to represent the number of GPIO pins supported
3
As per ISA:
4
by the GPIO controller.
5
4
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
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: 1591625864-31494-7-git-send-email-bmeng.cn@gmail.com
13
Message-ID: <20230808090914.17634-1-nikita.shubin@maquefel.me>
9
Message-Id: <1591625864-31494-7-git-send-email-bmeng.cn@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
15
---
12
include/hw/riscv/sifive_gpio.h | 3 +++
16
target/riscv/csr.c | 24 +++++++++++++++---------
13
hw/riscv/sifive_gpio.c | 30 +++++++++++++++++++-----------
17
1 file changed, 15 insertions(+), 9 deletions(-)
14
2 files changed, 22 insertions(+), 11 deletions(-)
15
18
16
diff --git a/include/hw/riscv/sifive_gpio.h b/include/hw/riscv/sifive_gpio.h
19
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/riscv/sifive_gpio.h
21
--- a/target/riscv/csr.c
19
+++ b/include/hw/riscv/sifive_gpio.h
22
+++ b/target/riscv/csr.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct SIFIVEGPIOState {
23
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
21
uint32_t out_xor;
24
target_ulong write_mask)
22
uint32_t in;
25
{
23
uint32_t in_mask;
26
RISCVException ret;
24
+
27
- target_ulong old_value;
25
+ /* config */
28
+ target_ulong old_value = 0;
26
+ uint32_t ngpio;
29
27
} SIFIVEGPIOState;
30
/* execute combined read/write operation if it exists */
28
31
if (csr_ops[csrno].op) {
29
#endif /* SIFIVE_GPIO_H */
32
return csr_ops[csrno].op(env, csrno, ret_value, new_value, write_mask);
30
diff --git a/hw/riscv/sifive_gpio.c b/hw/riscv/sifive_gpio.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/riscv/sifive_gpio.c
33
+++ b/hw/riscv/sifive_gpio.c
34
@@ -XXX,XX +XXX,XX @@
35
#include "qemu/osdep.h"
36
#include "qemu/log.h"
37
#include "hw/irq.h"
38
+#include "hw/qdev-properties.h"
39
#include "hw/riscv/sifive_gpio.h"
40
#include "migration/vmstate.h"
41
#include "trace.h"
42
@@ -XXX,XX +XXX,XX @@ static void update_output_irq(SIFIVEGPIOState *s)
43
pending |= s->rise_ip & s->rise_ie;
44
pending |= s->fall_ip & s->fall_ie;
45
46
- for (int i = 0; i < SIFIVE_GPIO_PINS; i++) {
47
+ for (int i = 0; i < s->ngpio; i++) {
48
pin = 1 << i;
49
qemu_set_irq(s->irq[i], (pending & pin) != 0);
50
trace_sifive_gpio_update_output_irq(i, (pending & pin) != 0);
51
@@ -XXX,XX +XXX,XX @@ static void update_state(SIFIVEGPIOState *s)
52
bool prev_ival, in, in_mask, port, out_xor, pull, output_en, input_en,
53
rise_ip, fall_ip, low_ip, high_ip, oval, actual_value, ival;
54
55
- for (i = 0; i < SIFIVE_GPIO_PINS; i++) {
56
+ for (i = 0; i < s->ngpio; i++) {
57
58
prev_ival = extract32(s->value, i, 1);
59
in = extract32(s->in, i, 1);
60
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_sifive_gpio = {
61
}
33
}
62
};
34
63
35
- /* if no accessor exists then return failure */
64
-static void sifive_gpio_init(Object *obj)
36
- if (!csr_ops[csrno].read) {
65
+static Property sifive_gpio_properties[] = {
37
- return RISCV_EXCP_ILLEGAL_INST;
66
+ DEFINE_PROP_UINT32("ngpio", SIFIVEGPIOState, ngpio, SIFIVE_GPIO_PINS),
38
- }
67
+ DEFINE_PROP_END_OF_LIST(),
39
- /* read old value */
68
+};
40
- ret = csr_ops[csrno].read(env, csrno, &old_value);
69
+
41
- if (ret != RISCV_EXCP_NONE) {
70
+static void sifive_gpio_realize(DeviceState *dev, Error **errp)
42
- return ret;
71
{
43
+ /*
72
- SIFIVEGPIOState *s = SIFIVE_GPIO(obj);
44
+ * ret_value == NULL means that rd=x0 and we're coming from helper_csrw()
73
+ SIFIVEGPIOState *s = SIFIVE_GPIO(dev);
45
+ * and we can't throw side effects caused by CSR reads.
74
46
+ */
75
- memory_region_init_io(&s->mmio, obj, &gpio_ops, s,
47
+ if (ret_value) {
76
+ memory_region_init_io(&s->mmio, OBJECT(dev), &gpio_ops, s,
48
+ /* if no accessor exists then return failure */
77
TYPE_SIFIVE_GPIO, SIFIVE_GPIO_SIZE);
49
+ if (!csr_ops[csrno].read) {
78
- sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
50
+ return RISCV_EXCP_ILLEGAL_INST;
79
51
+ }
80
- for (int i = 0; i < SIFIVE_GPIO_PINS; i++) {
52
+ /* read old value */
81
- sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq[i]);
53
+ ret = csr_ops[csrno].read(env, csrno, &old_value);
82
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
54
+ if (ret != RISCV_EXCP_NONE) {
83
+
55
+ return ret;
84
+ for (int i = 0; i < s->ngpio; i++) {
56
+ }
85
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]);
86
}
57
}
87
58
88
- qdev_init_gpio_in(DEVICE(s), sifive_gpio_set, SIFIVE_GPIO_PINS);
59
/* write value if writable and write mask set, otherwise drop writes */
89
- qdev_init_gpio_out(DEVICE(s), s->output, SIFIVE_GPIO_PINS);
90
+ qdev_init_gpio_in(DEVICE(s), sifive_gpio_set, s->ngpio);
91
+ qdev_init_gpio_out(DEVICE(s), s->output, s->ngpio);
92
}
93
94
static void sifive_gpio_class_init(ObjectClass *klass, void *data)
95
{
96
DeviceClass *dc = DEVICE_CLASS(klass);
97
98
+ device_class_set_props(dc, sifive_gpio_properties);
99
dc->vmsd = &vmstate_sifive_gpio;
100
+ dc->realize = sifive_gpio_realize;
101
dc->reset = sifive_gpio_reset;
102
dc->desc = "SiFive GPIO";
103
}
104
@@ -XXX,XX +XXX,XX @@ static const TypeInfo sifive_gpio_info = {
105
.name = TYPE_SIFIVE_GPIO,
106
.parent = TYPE_SYS_BUS_DEVICE,
107
.instance_size = sizeof(SIFIVEGPIOState),
108
- .instance_init = sifive_gpio_init,
109
.class_init = sifive_gpio_class_init
110
};
111
112
--
60
--
113
2.27.0
61
2.41.0
114
115
diff view generated by jsdifflib