mirror of https://github.com/ipxe/ipxe.git
[riscv] Check if seed CSR is accessible from S-mode
The seed CSR defined by the Zkr extension is accessible only in M-mode by default. Older versions of OpenSBI (prior to version 1.4) do not set mseccfg.sseed, with the result that attempts to access the seed CSR from S-mode will raise an illegal instruction exception. Add a facility for testing the accessibility of arbitrary CSRs, and use it to check that the seed CSR is accessible before reporting the seed CSR entropy source as being functional. Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/1330/head
parent
e0e102ee24
commit
19f44d2998
|
@ -31,6 +31,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <ipxe/hart.h>
|
#include <ipxe/hart.h>
|
||||||
|
#include <ipxe/csr.h>
|
||||||
#include <ipxe/entropy.h>
|
#include <ipxe/entropy.h>
|
||||||
#include <ipxe/drbg.h>
|
#include <ipxe/drbg.h>
|
||||||
|
|
||||||
|
@ -60,6 +61,12 @@ static int zkr_entropy_enable ( void ) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if seed CSR is accessible in S-mode */
|
||||||
|
if ( ! csr_can_write ( "seed", 0 ) ) {
|
||||||
|
DBGC ( colour, "ZKR cannot access seed CSR\n" );
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
/* RISC-V ISA mandates that 128 bits of full entropy shall be
|
/* RISC-V ISA mandates that 128 bits of full entropy shall be
|
||||||
* obtained from 256 entropy bits read from the seed CSR.
|
* obtained from 256 entropy bits read from the seed CSR.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
#ifndef _IPXE_CSR_H
|
||||||
|
#define _IPXE_CSR_H
|
||||||
|
|
||||||
|
/** @file
|
||||||
|
*
|
||||||
|
* Control and status registers (CSRs)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if CSR can be read
|
||||||
|
*
|
||||||
|
* @v name CSR name
|
||||||
|
* @v allowed CSR can be read
|
||||||
|
*/
|
||||||
|
#define csr_can_read( name ) ( { \
|
||||||
|
unsigned long stvec_orig; \
|
||||||
|
unsigned long stvec_temp; \
|
||||||
|
unsigned long csr; \
|
||||||
|
int allowed = 0; \
|
||||||
|
\
|
||||||
|
__asm__ __volatile__ ( /* Set temporary trap vector */ \
|
||||||
|
"la %3, 1f\n\t" \
|
||||||
|
"csrrw %2, stvec, %3\n\t" \
|
||||||
|
/* Try reading CSR */ \
|
||||||
|
"csrr %1, " name "\n\t" \
|
||||||
|
/* Mark as allowed if not trapped */ \
|
||||||
|
"addi %0, %0, 1\n\t" \
|
||||||
|
/* Temporary trap vector */ \
|
||||||
|
".balign 4\n\t" \
|
||||||
|
"\n1:\n\t" \
|
||||||
|
/* Restore original trap vector */ \
|
||||||
|
"csrw stvec, %2\n\t" \
|
||||||
|
: "+r" ( allowed ), \
|
||||||
|
"=r" ( csr ), \
|
||||||
|
"=r" ( stvec_orig ), \
|
||||||
|
"=r" ( stvec_temp ) ); \
|
||||||
|
allowed; \
|
||||||
|
} )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if CSR can be written
|
||||||
|
*
|
||||||
|
* @v name CSR name
|
||||||
|
* @v value Value to write
|
||||||
|
* @v allowed CSR can be written
|
||||||
|
*/
|
||||||
|
#define csr_can_write( name, value ) ( { \
|
||||||
|
unsigned long stvec_orig; \
|
||||||
|
unsigned long stvec_temp; \
|
||||||
|
unsigned long csr = (value); \
|
||||||
|
int allowed = 0; \
|
||||||
|
\
|
||||||
|
__asm__ __volatile__ ( /* Set temporary trap vector */ \
|
||||||
|
"la %3, 1f\n\t" \
|
||||||
|
"csrrw %2, stvec, %3\n\t" \
|
||||||
|
/* Try writing CSR */ \
|
||||||
|
"csrrw %1, " name ", %1\n\t" \
|
||||||
|
/* Mark as allowed if not trapped */ \
|
||||||
|
"addi %0, %0, 1\n\t" \
|
||||||
|
/* Temporary trap vector */ \
|
||||||
|
".balign 4\n\t" \
|
||||||
|
"\n1:\n\t" \
|
||||||
|
/* Restore original trap vector */ \
|
||||||
|
"csrw stvec, %2\n\t" \
|
||||||
|
: "+r" ( allowed ), \
|
||||||
|
"+r" ( csr ), \
|
||||||
|
"=r" ( stvec_orig ), \
|
||||||
|
"=r" ( stvec_temp ) ); \
|
||||||
|
allowed; \
|
||||||
|
} )
|
||||||
|
|
||||||
|
#endif /* _IPXE_CSR_H */
|
Loading…
Reference in New Issue