7#include <botan/internal/cpuid.h>
9#include <botan/assert.h>
10#include <botan/internal/os_utils.h>
12#if defined(BOTAN_TARGET_OS_IS_LINUX) && __has_include(<sys/hwprobe.h>)
13 #include <asm/hwprobe.h>
14 #include <sys/hwprobe.h>
16 #define BOTAN_TARGET_HAS_RISCV_HWPROBE
23template <std::convertible_to<u
int64_t>... Bs>
24 requires(
sizeof...(Bs) > 0)
25constexpr uint64_t bitflag(Bs... bs) {
26 return ((uint64_t(1) << bs) | ...);
31uint32_t CPUID::CPUID_Data::detect_cpu_features(uint32_t allowed) {
34#if defined(BOTAN_TARGET_HAS_RISCV_HWPROBE)
42 enum class RISCV_HWPROBE_bit : uint64_t {
43 Scalar_Aes = bitflag(3, 4, 16, 11, 12),
44 Scalar_Sha256 = bitflag(3, 4, 16, 13),
45 Scalar_SM4 = bitflag(3, 4, 16, 14),
46 Scalar_SM3 = bitflag(3, 4, 16, 15),
48 Vector = bitflag(2, 17, 26),
49 Vector_Aes = bitflag(2, 17, 26, 21),
50 Vector_Sha256 = bitflag(2, 17, 26, 22, 23),
51 Vector_SM4 = bitflag(2, 17, 26, 24),
52 Vector_SM3 = bitflag(2, 17, 26, 25),
53 Vector_GCM = bitflag(2, 17, 26, 20),
56 struct riscv_hwprobe p;
57 p.key = RISCV_HWPROBE_KEY_IMA_EXT_0;
59 if(__riscv_hwprobe(&p, 1, 0,
nullptr, 0) == 0) {
60 const uint64_t riscv_features = p.value;
62 feat |=
if_set(riscv_features, RISCV_HWPROBE_bit::Scalar_Aes, CPUFeature::Bit::SCALAR_AES, allowed);
63 feat |=
if_set(riscv_features, RISCV_HWPROBE_bit::Scalar_Sha256, CPUFeature::Bit::SCALAR_SHA256, allowed);
64 feat |=
if_set(riscv_features, RISCV_HWPROBE_bit::Scalar_SM3, CPUFeature::Bit::SCALAR_SM3, allowed);
65 feat |=
if_set(riscv_features, RISCV_HWPROBE_bit::Scalar_SM4, CPUFeature::Bit::SCALAR_SM4, allowed);
67 feat |=
if_set(riscv_features, RISCV_HWPROBE_bit::Vector, CPUFeature::Bit::VECTOR, allowed);
69 if(is_set(feat, CPUFeature::Bit::VECTOR)) {
70 feat |=
if_set(riscv_features, RISCV_HWPROBE_bit::Vector_Aes, CPUFeature::Bit::VECTOR_AES, allowed);
71 feat |=
if_set(riscv_features, RISCV_HWPROBE_bit::Vector_Sha256, CPUFeature::Bit::VECTOR_SHA256, allowed);
72 feat |=
if_set(riscv_features, RISCV_HWPROBE_bit::Vector_SM3, CPUFeature::Bit::VECTOR_SM3, allowed);
73 feat |=
if_set(riscv_features, RISCV_HWPROBE_bit::Vector_SM4, CPUFeature::Bit::VECTOR_SM4, allowed);
static uint32_t if_set(uint64_t cpuid, T flag, CPUID::Feature bit, uint32_t allowed)