1 /* 2 * Copyright 2022-2024 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 # endif 26 # endif 27 # endif 28 29 # define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \ 30 HWPROBE_KEY, HWPROBE_VALUE) +1 31 extern uint32_t OPENSSL_riscvcap_P[ (( 32 # include "riscv_arch.def" 33 ) + sizeof(uint32_t) - 1) / sizeof(uint32_t) ]; 34 35 # ifdef OPENSSL_RISCVCAP_IMPL 36 # define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \ 37 HWPROBE_KEY, HWPROBE_VALUE) +1 38 uint32_t OPENSSL_riscvcap_P[ (( 39 # include "riscv_arch.def" 40 ) + sizeof(uint32_t) - 1) / sizeof(uint32_t) ]; 41 # endif 42 43 # define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \ 44 HWPROBE_KEY, HWPROBE_VALUE) \ 45 static inline int RISCV_HAS_##NAME(void) \ 46 { \ 47 return (OPENSSL_riscvcap_P[INDEX] & (1 << BIT_INDEX)) != 0; \ 48 } 49 # include "riscv_arch.def" 50 51 struct RISCV_capability_s { 52 const char *name; 53 size_t index; 54 size_t bit_offset; 55 # ifdef OSSL_RISCV_HWPROBE 56 int32_t hwprobe_key; 57 uint64_t hwprobe_value; 58 # endif 59 }; 60 61 # define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \ 62 OSSL_RISCV_HWPROBE_KEY, OSSL_RISCV_HWPROBE_VALUE) +1 63 extern const struct RISCV_capability_s RISCV_capabilities[ 64 # include "riscv_arch.def" 65 ]; 66 67 # ifdef OPENSSL_RISCVCAP_IMPL 68 # ifdef OSSL_RISCV_HWPROBE 69 # define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \ 70 HWPROBE_KEY, HWPROBE_VALUE) \ 71 { #NAME, INDEX, BIT_INDEX, HWPROBE_KEY, HWPROBE_VALUE }, 72 # else 73 # define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \ 74 HWPROBE_KEY, HWPROBE_VALUE) \ 75 { #NAME, INDEX, BIT_INDEX }, 76 # endif 77 const struct RISCV_capability_s RISCV_capabilities[] = { 78 # include "riscv_arch.def" 79 }; 80 # endif 81 82 # define RISCV_DEFINE_CAP(NAME, INDEX, BIT_INDEX, \ 83 HWPROBE_KEY, HWPROBE_VALUE) +1 84 static const size_t kRISCVNumCaps = 85 # include "riscv_arch.def" 86 ; 87 88 # ifdef OSSL_RISCV_HWPROBE 89 /* 90 * Content is an array of { hwprobe_key, 0 } where 91 * hwprobe_key is copied from asm/hwprobe.h. 92 * It should be updated along with riscv_arch.def. 93 */ 94 # define OSSL_RISCV_HWPROBE_PAIR_COUNT 1 95 # define OSSL_RISCV_HWPROBE_PAIR_CONTENT \ 96 { 4, 0 }, 97 # endif 98 99 /* Extension combination tests. */ 100 #define RISCV_HAS_ZBB_AND_ZBC() (RISCV_HAS_ZBB() && RISCV_HAS_ZBC()) 101 #define RISCV_HAS_ZBKB_AND_ZKND_AND_ZKNE() (RISCV_HAS_ZBKB() && RISCV_HAS_ZKND() && RISCV_HAS_ZKNE()) 102 #define RISCV_HAS_ZKND_AND_ZKNE() (RISCV_HAS_ZKND() && RISCV_HAS_ZKNE()) 103 /* 104 * The ZVBB is the superset of ZVKB extension. We use macro here to replace the 105 * `RISCV_HAS_ZVKB()` with `RISCV_HAS_ZVBB() || RISCV_HAS_ZVKB()`. 106 */ 107 #define RISCV_HAS_ZVKB() (RISCV_HAS_ZVBB() || RISCV_HAS_ZVKB()) 108 #define RISCV_HAS_ZVKB_AND_ZVKNHA() (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKNHA()) 109 #define RISCV_HAS_ZVKB_AND_ZVKNHB() (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKNHB()) 110 #define RISCV_HAS_ZVKB_AND_ZVKSED() (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKSED()) 111 #define RISCV_HAS_ZVKB_AND_ZVKSH() (RISCV_HAS_ZVKB() && RISCV_HAS_ZVKSH()) 112 113 /* 114 * Get the size of a vector register in bits (VLEN). 115 * If RISCV_HAS_V() is false, then this returns 0. 116 */ 117 size_t riscv_vlen(void); 118 119 #endif 120