Botan 3.6.0
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/os_utils.h>
11
12namespace Botan {
13
14#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
15
16uint32_t CPUID::CPUID_Data::detect_cpu_features(uint32_t allowed) {
17 uint32_t feat = 0;
18
19 if(OS::has_auxval()) {
20 enum class PPC_hwcap_bit : uint64_t {
21 ALTIVEC_bit = (1 << 28),
22 CRYPTO_bit = (1 << 25),
23 DARN_bit = (1 << 21),
24 };
25
26 const uint64_t hwcap_altivec = OS::get_auxval(OS::auxval_hwcap());
27
28 feat |= if_set(hwcap_altivec, PPC_hwcap_bit::ALTIVEC_bit, CPUID::CPUID_ALTIVEC_BIT, allowed);
29
30 #if defined(BOTAN_TARGET_ARCH_IS_PPC64)
31 if(feat & CPUID::CPUID_ALTIVEC_BIT) {
32 const uint64_t hwcap_crypto = OS::get_auxval(OS::auxval_hwcap2());
33 feat |= if_set(hwcap_crypto, PPC_hwcap_bit::CRYPTO_bit, CPUID::CPUID_POWER_CRYPTO_BIT, allowed);
34 feat |= if_set(hwcap_crypto, PPC_hwcap_bit::DARN_bit, CPUID::CPUID_DARN_BIT, allowed);
35 }
36 #endif
37
38 return feat;
39 }
40
41 #if defined(BOTAN_USE_GCC_INLINE_ASM)
42 auto vmx_probe = []() noexcept -> int {
43 asm("vor 0, 0, 0");
44 return 1;
45 };
46
47 if(allowed & CPUID::CPUID_ALTIVEC_BIT) {
48 if(OS::run_cpu_instruction_probe(vmx_probe) == 1) {
49 feat |= CPUID::CPUID_ALTIVEC_BIT;
50 }
51
52 #if defined(BOTAN_TARGET_CPU_IS_PPC64)
53 auto vcipher_probe = []() noexcept -> int {
54 asm("vcipher 0, 0, 0");
55 return 1;
56 };
57
58 auto darn_probe = []() noexcept -> int {
59 uint64_t output = 0;
60 asm volatile("darn %0, 1" : "=r"(output));
61 return (~output) != 0;
62 };
63
64 if(feat & CPUID::CPUID_ALTIVEC_BIT) {
65 if(OS::run_cpu_instruction_probe(vcipher_probe) == 1) {
66 feat |= CPUID::CPUID_POWER_CRYPTO_BIT & allowed;
67 }
68
69 if(OS::run_cpu_instruction_probe(darn_probe) == 1) {
70 feat |= CPUID::CPUID_DARN_BIT & allowed;
71 }
72 }
73 #endif
74 }
75
76 #endif
77
78 return feat;
79}
80
81#endif
82
83} // namespace Botan
unsigned long auxval_hwcap()
Definition os_utils.cpp:136
bool has_auxval()
Definition os_utils.cpp:124
int BOTAN_TEST_API run_cpu_instruction_probe(const std::function< int()> &probe_fn)
Definition os_utils.cpp:716
unsigned long get_auxval(unsigned long id)
Definition os_utils.cpp:156
unsigned long auxval_hwcap2()
Definition os_utils.cpp:146