Botan 3.7.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#if defined(BOTAN_HAS_OS_UTILS)
11 #include <botan/internal/os_utils.h>
12#endif
13
14namespace Botan {
15
16#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
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, CPUID::CPUID_ALTIVEC_BIT, allowed);
33
34 #if defined(BOTAN_TARGET_ARCH_IS_PPC64)
35 if(feat & CPUID::CPUID_ALTIVEC_BIT) {
36 feat |= if_set(hwcap_crypto, PPC_hwcap_bit::CRYPTO_bit, CPUID::CPUID_POWER_CRYPTO_BIT, allowed);
37 feat |= if_set(hwcap_crypto, PPC_hwcap_bit::DARN_bit, CPUID::CPUID_DARN_BIT, 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 & CPUID::CPUID_ALTIVEC_BIT) {
52 if(OS::run_cpu_instruction_probe(vmx_probe) == 1) {
53 feat |= CPUID::CPUID_ALTIVEC_BIT;
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 & CPUID::CPUID_ALTIVEC_BIT) {
69 if(OS::run_cpu_instruction_probe(vcipher_probe) == 1) {
70 feat |= CPUID::CPUID_POWER_CRYPTO_BIT & allowed;
71 }
72
73 if(OS::run_cpu_instruction_probe(darn_probe) == 1) {
74 feat |= CPUID::CPUID_DARN_BIT & allowed;
75 }
76 }
77 #endif
78 }
79
80 #endif
81
82 return feat;
83}
84
85#endif
86
87} // namespace Botan
static uint32_t if_set(uint64_t cpuid, T flag, CPUID::CPUID_bits bit, uint32_t allowed)
Definition cpuid.h:402
std::optional< std::pair< unsigned long, unsigned long > > get_auxval_hwcap()
Definition os_utils.cpp:150
int BOTAN_TEST_API run_cpu_instruction_probe(const std::function< int()> &probe_fn)
Definition os_utils.cpp:717