riscvcap.c 2.3 KB

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