1 /* 2 * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #ifndef OSSL_CRYPTO_RISCV_ARCH_H 11 # define OSSL_CRYPTO_RISCV_ARCH_H 12 13 # include <ctype.h> 14 # include <stdint.h> 15 16 # if defined(OPENSSL_SYS_LINUX) && !defined(FIPS_MODULE) 17 # if __has_include(<asm/hwprobe.h>) 18 # include <sys/syscall.h> 19 # /* 20 * Some environments using musl are reported to have the hwprobe.h include 21 * file but not have the __NR_riscv_hwprobe define. 22 */ 23 # ifdef __NR_riscv_hwprobe 24 # define OSSL_RISCV_HWPROBE 25 # include <asm/hwcap.h> 26 extern unsigned int OPENSSL_riscv_hwcap_P; 27 # define VECTOR_CAPABLE (OPENSSL_riscv_hwcap_P & COMPAT_HWCAP_ISA_V) 28 # define ZVX_MIN 15 29 # define ZVX_MAX 23 30 # define IS_IN_DEPEND_VECTOR(offset) ((ZVX_MIN >= offset) && (offset <= ZVX_MAX)) 31 # endif 32 # endif 33 # endif 34 35 # define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \ 36 HWPROBE_KEY, HWPROBE_VALUE) +1 37 extern uint32_t OPENSSL_riscvcap_P[ (( 38 # include "riscv_arch.def" 39 ) + sizeof(uint32_t) - 1) / sizeof(uint32_t) ]; 40 41 # ifdef OPENSSL_RISCVCAP_IMPL 42 # define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \ 43 HWPROBE_KEY, HWPROBE_VALUE) +1 44 uint32_t OPENSSL_riscvcap_P[ (( 45 # include "riscv_arch.def" 46 ) + sizeof(uint32_t) - 1) / sizeof(uint32_t) ]; 47 # endif 48 49 # define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \ 50 HWPROBE_KEY, HWPROBE_VALUE) \ 51 static inline int RISCV_HAS_##NAME(void) \ 52 { \ 53 return (OPENSSL_riscvcap_P[INDEX] & (1 << BIT_INDEX)) != 0; \ 54 } 55 # include "riscv_arch.def" 56 57 struct RISCV_capability_s { 58 const char *name; 59 size_t index; 60 size_t bit_offset; 61 # ifdef OSSL_RISCV_HWPROBE 62 int32_t hwprobe_key; 63 uint64_t hwprobe_value; 64 # endif 65 }; 66 67 # define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \ 68 OSSL_RISCV_HWPROBE_KEY, OSSL_RISCV_HWPROBE_VALUE) +1 69 extern const struct RISCV_capability_s RISCV_capabilities[ 70 # include "riscv_arch.def" 71 ]; 72 73 # ifdef OPENSSL_RISCVCAP_IMPL 74 # ifdef OSSL_RISCV_HWPROBE 75 # define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \ 76 HWPROBE_KEY, HWPROBE_VALUE) \ 77 { #NAME, INDEX, BIT_INDEX, HWPROBE_KEY, HWPROBE_VALUE }, 78 # else 79 # define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \ 80 HWPROBE_KEY, HWPROBE_VALUE) \ 81 { #NAME, INDEX, BIT_INDEX }, 82 # endif 83 const struct RISCV_capability_s RISCV_capabilities[] = { 84 # include "riscv_arch.def" 85 }; 86 # endif 87 88 # define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \ 89 HWPROBE_KEY, HWPROBE_VALUE) +1 90 static const size_t kRISCVNumCaps = 91 # include "riscv_arch.def" 92 ; 93 94 # ifdef OSSL_RISCV_HWPROBE 95 /* 96 * Content is an array of { hwprobe_key, 0 } where 97 * hwprobe_key is copied from asm/hwprobe.h. 98 * It should be updated along with riscv_arch.def. 99 */ 100 # define OSSL_RISCV_HWPROBE_PAIR_COUNT 1 101 # define OSSL_RISCV_HWPROBE_PAIR_CONTENT \ 102 { 4, 0 }, 103 # endif 104 105 /* Extension combination tests. */ 106 #define RISCV_HAS_ZBB_AND_ZBC() (RISCV_HAS_ZBB() && RISCV_HAS_ZBC()) 107 #define RISCV_HAS_ZBKB_AND_ZKND_AND_ZKNE() (RISCV_HAS_ZBKB() && RISCV_HAS_ZKND() && RISCV_HAS_ZKNE()) 108 #define RISCV_HAS_ZKND_AND_ZKNE() (RISCV_HAS_ZKND() && RISCV_HAS_ZKNE()) 109 /* 110 * The ZVBB is the superset of ZVKB extension. We use macro here to replace the 111 * `RISCV_HAS_ZVKB()` with `RISCV_HAS_ZVBB() || RISCV_HAS_ZVKB()`. 112 */ 113 #define RISCV_HAS_ZVKB() (RISCV_HAS_ZVBB() || RISCV_HAS_ZVKB()) 114 #define RISCV_HAS_ZVKB_AND_ZVKNHA() (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKNHA()) 115 #define RISCV_HAS_ZVKB_AND_ZVKNHB() (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKNHB()) 116 #define RISCV_HAS_ZVKB_AND_ZVKSED() (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKSED()) 117 #define RISCV_HAS_ZVKB_AND_ZVKSH() (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKSH()) 118 119 /* 120 * Get the size of a vector register in bits (VLEN). 121 * If RISCV_HAS_V() is false, then this returns 0. 122 */ 123 size_t riscv_vlen(void); 124 125 #endif 126