Historically, one could uniquely decode any RISC-V instruction based on
the instruciton to decode, plus a MATCH and MASK pair.
The scalar crypto extension adds instructions for accelerating the AES
algorithm which work very differently on RV32 and RV64. However, they
overlap in terms of opcodes. The instructions are always mutually
exclusive, and so it makes sense to overlap them this way to save
encoding space.
This exposed a problem, where previously Spike assumed the decoder
function was something like:
> decode(instr_word, MATCH, MASK)
Now it needed to be
> decode(instr_word, MATCH, MASK, current_xlen)
To get around this in the initial implementation, the instructions which
shared opcodes were implemented in the same *.h file - e.g. aesds.h
contained an implementation of aes32dsi, and aes64ds. We detected
xlen in the file, and executed the appropriate instruction logic.
This worked fine for our limited set of benchmarks.
After more extensive testing, we found that Spike has an optimisation
which changes the order in which it tries to decode instructions based
on past instructions.
Running more extensive tests exposed the fact that the decoding logic
could still not unambiguously decode the instructions. Hence, more
substantial changes were needed to tell spike that an instruction is
RV32 or RV64 only.
These changes have been implemented as part of
- riscv/encoding.h
- disasm/disasm.cc
- riscv/processor.cc/h
Basically, every instr_desc_t has an extra field which marks which
base architecture the instruction can be exectuted on. This bitfield
can be altered for particular instructions.
The changes to riscv/insns/* simply split out the previously combined
instructions into a separate header files.
On branch scalar-crypto-fix
Changes to be committed:
modified: disasm/disasm.cc
modified: riscv/encoding.h
new file: riscv/insns/aes32dsi.h
new file: riscv/insns/aes32dsmi.h
new file: riscv/insns/aes32esi.h
new file: riscv/insns/aes32esmi.h
new file: riscv/insns/aes64ds.h
new file: riscv/insns/aes64dsm.h
new file: riscv/insns/aes64es.h
new file: riscv/insns/aes64esm.h
deleted: riscv/insns/aesds.h
deleted: riscv/insns/aesdsm.h
deleted: riscv/insns/aeses.h
deleted: riscv/insns/aesesm.h
modified: riscv/processor.cc
modified: riscv/processor.h
modified: riscv/riscv.mk.in
These instructions are RV32 only. Previously, they zero-extended
their 32-bit result to 64-bits, to match the Spike implementation detail
that the X registers are always 64-bits long.
This exposed a data dependant problem when the instruction results fed
into the add and sltu instructions. The lack of sign extension on the
sha512*, combined with the presence of sign extension on the add, meant
sltu would (as it is currently implemented) produce the wrong result.
There were two potential fixes:
1) Sign extend from 32-bits to XLEN the result of the SHA512 instructions.
2) Change the SLTU implementation to truncate RS1/RS2 to be XLEN bits
before it does the comparison.
This patch implements option 1, because I didn't want to mess with a
base ISA instruction. However, this leaves the implementation detail
open to cause problems for people in the future. Fixing this is outside
the scope of this commit.
On branch scalar-crypto-fix
Changes to be committed:
modified: riscv/insns/sha512sig0h.h
modified: riscv/insns/sha512sig0l.h
modified: riscv/insns/sha512sig1h.h
modified: riscv/insns/sha512sig1l.h
modified: riscv/insns/sha512sum0r.h
modified: riscv/insns/sha512sum1r.h
We should check both MSTATUS.VS and VSSTATUS.VS when updating
vector state with virt-on. This patch fixes require_vector_vs()
macro accordingly.
Signed-off-by: Anup Patel <anup.patel@wdc.com>
When transitioning from virt-on (VS/VU) to virt-off (HS/M) we should
mark Host extension status (i.e. FS, VS, and XS bits) as dirty when
Guest/VM extension status is dirty and Host extension status is
initial, clean, or dirty.
Signed-off-by: Anup Patel <anup.patel@wdc.com>
For some reason, the old accessors for the non-sparse version were left
dangling. These methods are used by the --kernel and --initrd options,
and so those options were just broken.
This also fixes a memory leak and refactors the implementation a bit.
Brief:
- This commit adds spike support for the scalar cryptography extension.
See the riscv-crypto repository (https://github.com/riscv/riscv-crypto)
for more information on this extension.
- It is based on the experimental patch which has so far been kept in the
riscv-crypto repository. Now that scalar crypto is nearly at the "freeze"
stage and entering opcode consistency review, it makes sense to start
upstreaming our experimental version.
- In terms of compiler support - we are using an experimental patch in
the riscv-crypto repository at the moment, others are working on an
upstream appropriate version.
Details:
- Add support for dedicated scalar crypto instructions.
- Add very basic support for the entropy source (entropy_source.h).
Much of the behaviour of this is implementation specific. This model
aims to provide the bare minimum of functionality which can be used to
quickly develop software. It uses /dev/urandom as its entropy source for
now.
- Scalar crypto is unique in that it _borrows_ instructions from the
Bitmanipulation extension. This is currently _not_ encoded in the patch,
as I didn't want to damage anything in Bitmanip which is currently under
review. However, I've added a macro in riscv/decode.h called
"require_either_extension(A,B)", which allows instructions to be valid
opcodes iff they are in one or both extensions.
On branch scalar-crypto
Changes to be committed:
modified: README.md
modified: riscv/decode.h
modified: riscv/encoding.h
new file: riscv/entropy_source.h
new file: riscv/insns/aes64im.h
new file: riscv/insns/aes64ks1i.h
new file: riscv/insns/aes64ks2.h
new file: riscv/insns/aes_common.h
new file: riscv/insns/aesds.h
new file: riscv/insns/aesdsm.h
new file: riscv/insns/aeses.h
new file: riscv/insns/aesesm.h
new file: riscv/insns/sha256sig0.h
new file: riscv/insns/sha256sig1.h
new file: riscv/insns/sha256sum0.h
new file: riscv/insns/sha256sum1.h
new file: riscv/insns/sha512sig0.h
new file: riscv/insns/sha512sig0h.h
new file: riscv/insns/sha512sig0l.h
new file: riscv/insns/sha512sig1.h
new file: riscv/insns/sha512sig1h.h
new file: riscv/insns/sha512sig1l.h
new file: riscv/insns/sha512sum0.h
new file: riscv/insns/sha512sum0r.h
new file: riscv/insns/sha512sum1.h
new file: riscv/insns/sha512sum1r.h
new file: riscv/insns/sm3p0.h
new file: riscv/insns/sm3p1.h
new file: riscv/insns/sm4_common.h
new file: riscv/insns/sm4ed.h
new file: riscv/insns/sm4ks.h
modified: riscv/processor.cc
modified: riscv/processor.h
modified: riscv/riscv.mk.in
This patch splites the target-requested memory regions into pages and only
allocates host memory when it is accessed to reduce larget memory sceniaro
in 64 bit target system
Co-authored-by: Dave.Wen <dave.wen@sifive.com>
When deciding HS-mode interrupts in processor_t:take_interrupt()
we should use "~state.hideleg" instead of "~MIP_VS_MASK" because
VS interrupt bits are writeable in HIDELEG CSR.
Signed-off-by: Anup Patel <anup.patel@wdc.com>
We cannot blindly use proc variable in MMU emulation because external
debug emulation instantiates MMU with proc=NULL.
Signed-off-by: Anup Patel <anup.patel@wdc.com>
When a single abstract command writes s0 and executes a program buffer
that leads to an exception, the value of s0 should still persist. The
fact that it did not masked the following bug in OpenOCD:
https://github.com/riscv/riscv-openocd/issues/559