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