riscv_arch.h 3.7 KB

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