Botan 3.9.0
Crypto and TLS for C&
cpuid_riscv64.cpp
Go to the documentation of this file.
1/*
2* (C) 2025 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/internal/cpuid.h>
8
9#include <botan/assert.h>
10#include <botan/internal/os_utils.h>
11
12#if defined(BOTAN_TARGET_OS_IS_LINUX) && __has_include(<sys/hwprobe.h>)
13 #include <asm/hwprobe.h>
14 #include <sys/hwprobe.h>
15
16 #define BOTAN_TARGET_HAS_RISCV_HWPROBE
17#endif
18
19namespace Botan {
20
21namespace {
22
23template <std::convertible_to<uint64_t>... Bs>
24 requires(sizeof...(Bs) > 0)
25constexpr uint64_t bitflag(Bs... bs) {
26 return ((uint64_t(1) << bs) | ...);
27}
28
29} // namespace
30
31uint32_t CPUID::CPUID_Data::detect_cpu_features(uint32_t allowed) {
32 uint32_t feat = 0;
33
34#if defined(BOTAN_TARGET_HAS_RISCV_HWPROBE)
35 /*
36 * For scalar operations we require additionally
37 * Zba (bit 3), Zbb (bit 4), Zkt (bit 16)
38 *
39 * For vector operations we require
40 * V (bit 2), Vbb (bit 17), VZkt (bit 26),
41 */
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),
47
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),
54 };
55
56 struct riscv_hwprobe p;
57 p.key = RISCV_HWPROBE_KEY_IMA_EXT_0;
58
59 if(__riscv_hwprobe(&p, 1, 0, nullptr, 0) == 0) {
60 const uint64_t riscv_features = p.value;
61
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);
66
67 feat |= if_set(riscv_features, RISCV_HWPROBE_bit::Vector, CPUFeature::Bit::VECTOR, allowed);
68
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);
74 }
75 }
76#else
77 BOTAN_UNUSED(allowed);
78#endif
79
80 return feat;
81}
82
83} // namespace Botan
#define BOTAN_UNUSED
Definition assert.h:144
static uint32_t if_set(uint64_t cpuid, T flag, CPUID::Feature bit, uint32_t allowed)
Definition cpuid.h:117