]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/riscvcap.c
db75c21b2895c34cd98166535ef484bd5d87b616
[thirdparty/openssl.git] / crypto / riscvcap.c
1 /*
2 * Copyright 2022 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 #include <stdlib.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include <stdint.h>
14 #include <openssl/crypto.h>
15 #include "internal/cryptlib.h"
16
17 #define OPENSSL_RISCVCAP_IMPL
18 #include "crypto/riscv_arch.h"
19
20 extern size_t riscv_vlen_asm(void);
21
22 static void parse_env(const char *envstr);
23 static void strtoupper(char *str);
24
25 static size_t vlen = 0;
26
27 uint32_t OPENSSL_rdtsc(void)
28 {
29 return 0;
30 }
31
32 size_t OPENSSL_instrument_bus(unsigned int *out, size_t cnt)
33 {
34 return 0;
35 }
36
37 size_t OPENSSL_instrument_bus2(unsigned int *out, size_t cnt, size_t max)
38 {
39 return 0;
40 }
41
42 static void strtoupper(char *str)
43 {
44 for (char *x = str; *x; ++x)
45 *x = toupper(*x);
46 }
47
48 /* parse_env() parses a RISC-V architecture string. An example of such a string
49 * is "rv64gc_zba_zbb_zbc_zbs". Currently, the rv64gc part is ignored
50 * and we simply search for "_[extension]" in the arch string to see if we
51 * should enable a given extension.
52 */
53 #define BUFLEN 256
54 static void parse_env(const char *envstr)
55 {
56 char envstrupper[BUFLEN];
57 char buf[BUFLEN];
58
59 /* Convert env str to all uppercase */
60 OPENSSL_strlcpy(envstrupper, envstr, sizeof(envstrupper));
61 strtoupper(envstrupper);
62
63 for (size_t i = 0; i < kRISCVNumCaps; ++i) {
64 /* Prefix capability with underscore in preparation for search */
65 BIO_snprintf(buf, BUFLEN, "_%s", RISCV_capabilities[i].name);
66 if (strstr(envstrupper, buf) != NULL) {
67 /* Match, set relevant bit in OPENSSL_riscvcap_P[] */
68 OPENSSL_riscvcap_P[RISCV_capabilities[i].index] |=
69 (1 << RISCV_capabilities[i].bit_offset);
70 }
71 }
72 }
73
74 size_t riscv_vlen(void)
75 {
76 return vlen;
77 }
78
79 # if defined(__GNUC__) && __GNUC__>=2
80 __attribute__ ((constructor))
81 # endif
82 void OPENSSL_cpuid_setup(void)
83 {
84 char *e;
85 static int trigger = 0;
86
87 if (trigger != 0)
88 return;
89 trigger = 1;
90
91 if ((e = getenv("OPENSSL_riscvcap"))) {
92 parse_env(e);
93 }
94
95 if (RISCV_HAS_V()) {
96 vlen = riscv_vlen_asm();
97 }
98 }