diff --git a/crypto/riscv64cpuid.pl b/crypto/riscv64cpuid.pl index 675e9b6111..5dcdc5c584 100644 --- a/crypto/riscv64cpuid.pl +++ b/crypto/riscv64cpuid.pl @@ -84,6 +84,22 @@ OPENSSL_cleanse: ___ } +{ +my ($ret) = ('a0'); +$code .= <<___; +################################################################################ +# size_t riscv_vlen_asm(void) +# Return VLEN (i.e. the length of a vector register in bits). +.p2align 3 +.globl riscv_vlen_asm +.type riscv_vlen_asm,\@function +riscv_vlen_asm: + csrr $ret, vlenb + slli $ret, $ret, 3 + ret +.size riscv_vlen_asm,.-riscv_vlen_asm +___ +} print $code; close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/riscvcap.c b/crypto/riscvcap.c index 1cbfb4a574..db75c21b28 100644 --- a/crypto/riscvcap.c +++ b/crypto/riscvcap.c @@ -17,9 +17,13 @@ #define OPENSSL_RISCVCAP_IMPL #include "crypto/riscv_arch.h" +extern size_t riscv_vlen_asm(void); + static void parse_env(const char *envstr); static void strtoupper(char *str); +static size_t vlen = 0; + uint32_t OPENSSL_rdtsc(void) { return 0; @@ -67,6 +71,11 @@ static void parse_env(const char *envstr) } } +size_t riscv_vlen(void) +{ + return vlen; +} + # if defined(__GNUC__) && __GNUC__>=2 __attribute__ ((constructor)) # endif @@ -81,6 +90,9 @@ void OPENSSL_cpuid_setup(void) if ((e = getenv("OPENSSL_riscvcap"))) { parse_env(e); - return; + } + + if (RISCV_HAS_V()) { + vlen = riscv_vlen_asm(); } } diff --git a/include/crypto/riscv_arch.def b/include/crypto/riscv_arch.def index 6c26dbf401..b355fa4ddc 100644 --- a/include/crypto/riscv_arch.def +++ b/include/crypto/riscv_arch.def @@ -32,6 +32,7 @@ RISCV_DEFINE_CAP(ZKSED, 0, 10) RISCV_DEFINE_CAP(ZKSH, 0, 11) RISCV_DEFINE_CAP(ZKR, 0, 12) RISCV_DEFINE_CAP(ZKT, 0, 13) +RISCV_DEFINE_CAP(V, 0, 14) /* * In the future ... diff --git a/include/crypto/riscv_arch.h b/include/crypto/riscv_arch.h index 9518584111..8bd281ad80 100644 --- a/include/crypto/riscv_arch.h +++ b/include/crypto/riscv_arch.h @@ -61,4 +61,10 @@ static const size_t kRISCVNumCaps = #define RISCV_HAS_ZBKB_AND_ZKND_AND_ZKNE() (RISCV_HAS_ZBKB() && RISCV_HAS_ZKND() && RISCV_HAS_ZKNE()) #define RISCV_HAS_ZKND_AND_ZKNE() (RISCV_HAS_ZKND() && RISCV_HAS_ZKNE()) +/* + * Get the size of a vector register in bits (VLEN). + * If RISCV_HAS_V() is false, then this returns 0. + */ +size_t riscv_vlen(void); + #endif