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