Botan 3.8.1
Crypto and TLS for C&
cpuid_ppc.cpp
Go to the documentation of this file.
1/*
2* Runtime CPU detection for POWER/PowerPC
3* (C) 2009,2010,2013,2017,2021,2024 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/internal/cpuid.h>
9
10#include <botan/internal/target_info.h>
11
12#if defined(BOTAN_HAS_OS_UTILS)
13 #include <botan/internal/os_utils.h>
14#endif
15
16namespace Botan {
17
18uint32_t CPUID::CPUID_Data::detect_cpu_features(uint32_t allowed) {
19 uint32_t feat = 0;
20
21#if defined(BOTAN_HAS_OS_UTILS)
22
23 if(auto auxval = OS::get_auxval_hwcap()) {
24 const auto [hwcap_altivec, hwcap_crypto] = *auxval;
25
26 enum class PPC_hwcap_bit : uint64_t {
27 ALTIVEC_bit = (1 << 28),
28 CRYPTO_bit = (1 << 25),
29 DARN_bit = (1 << 21),
30 };
31
32 feat |= if_set(hwcap_altivec, PPC_hwcap_bit::ALTIVEC_bit, CPUFeature::Bit::ALTIVEC, allowed);
33
34 #if defined(BOTAN_TARGET_ARCH_IS_PPC64)
35 if(feat & CPUFeature::Bit::ALTIVEC) {
36 feat |= if_set(hwcap_crypto, PPC_hwcap_bit::CRYPTO_bit, CPUFeature::Bit::POWER_CRYPTO, allowed);
37 feat |= if_set(hwcap_crypto, PPC_hwcap_bit::DARN_bit, CPUFeature::Bit::DARN, allowed);
38 }
39 #endif
40
41 return feat;
42 }
43#endif
44
45#if defined(BOTAN_USE_GCC_INLINE_ASM) && defined(BOTAN_HAS_OS_UTILS)
46 auto vmx_probe = []() noexcept -> int {
47 asm("vor 0, 0, 0");
48 return 1;
49 };
50
51 if(allowed & CPUFeature::Bit::ALTIVEC) {
52 if(OS::run_cpu_instruction_probe(vmx_probe) == 1) {
53 feat |= CPUFeature::Bit::ALTIVEC;
54 }
55
56 #if defined(BOTAN_TARGET_CPU_IS_PPC64)
57 auto vcipher_probe = []() noexcept -> int {
58 asm("vcipher 0, 0, 0");
59 return 1;
60 };
61
62 auto darn_probe = []() noexcept -> int {
63 uint64_t output = 0;
64 asm volatile("darn %0, 1" : "=r"(output));
65 return (~output) != 0;
66 };
67
68 if(feat & CPUFeature::Bit::ALTIVEC) {
69 if(OS::run_cpu_instruction_probe(vcipher_probe) == 1) {
70 feat |= CPUFeature::Bit::POWER_CRYPTO & allowed;
71 }
72
73 if(OS::run_cpu_instruction_probe(darn_probe) == 1) {
74 feat |= CPUFeature::Bit::DARN & allowed;
75 }
76 }
77 #endif
78 }
79
80#endif
81
82 return feat;
83}
84
85} // namespace Botan
static uint32_t if_set(uint64_t cpuid, T flag, CPUID::Feature bit, uint32_t allowed)
Definition cpuid.h:117
std::optional< std::pair< unsigned long, unsigned long > > get_auxval_hwcap()
Definition os_utils.cpp:136
int BOTAN_TEST_API run_cpu_instruction_probe(const std::function< int()> &probe_fn)
Definition os_utils.cpp:709