diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/CMakeLists.txt | 12 | ||||
-rw-r--r-- | src/arch/arm.c | 37 | ||||
-rw-r--r-- | src/arch/arm.h | 18 | ||||
-rw-r--r-- | src/arch/intel.c | 80 | ||||
-rw-r--r-- | src/arch/intel.h | 22 | ||||
-rw-r--r-- | src/arch/ppc.c | 40 | ||||
-rw-r--r-- | src/arch/ppc.h | 24 | ||||
-rw-r--r-- | src/arch/probe.cc | 26 | ||||
-rw-r--r-- | src/arch/probe.h | 16 |
9 files changed, 275 insertions, 0 deletions
diff --git a/src/arch/CMakeLists.txt b/src/arch/CMakeLists.txt new file mode 100644 index 00000000..b2386285 --- /dev/null +++ b/src/arch/CMakeLists.txt @@ -0,0 +1,12 @@ +set(arch_srcs + probe.cc) + +if(HAVE_ARM) + list(APPEND arch_srcs arm.c) +elseif(HAVE_INTEL) + list(APPEND arch_srcs intel.c) +elseif(HAVE_POWER8) + list(APPEND arch_srcs ppc.c) +endif() + +add_library(arch STATIC ${arch_srcs}) diff --git a/src/arch/arm.c b/src/arch/arm.c new file mode 100644 index 00000000..02f0107b --- /dev/null +++ b/src/arch/arm.c @@ -0,0 +1,37 @@ +#include "acconfig.h" +#include "arch/probe.h" + +/* flags we export */ +int ceph_arch_neon = 0; +int ceph_arch_aarch64_crc32 = 0; +int ceph_arch_aarch64_pmull = 0; + +#include <stdio.h> + +#if __linux__ + +#include <elf.h> +#include <link.h> // ElfW macro +#include <sys/auxv.h> + +#if __arm__ || __aarch64__ +#include <asm/hwcap.h> +#endif // __arm__ + +#endif // __linux__ + +int ceph_arch_arm_probe(void) +{ +#if __linux__ + unsigned long hwcap = getauxval(AT_HWCAP); +#if __arm__ + ceph_arch_neon = (hwcap & HWCAP_NEON) == HWCAP_NEON; +#elif __aarch64__ + ceph_arch_neon = (hwcap & HWCAP_ASIMD) == HWCAP_ASIMD; + ceph_arch_aarch64_crc32 = (hwcap & HWCAP_CRC32) == HWCAP_CRC32; + ceph_arch_aarch64_pmull = (hwcap & HWCAP_PMULL) == HWCAP_PMULL; +#endif +#endif // __linux__ + return 0; +} + diff --git a/src/arch/arm.h b/src/arch/arm.h new file mode 100644 index 00000000..dacc450b --- /dev/null +++ b/src/arch/arm.h @@ -0,0 +1,18 @@ +#ifndef CEPH_ARCH_ARM_H +#define CEPH_ARCH_ARM_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern int ceph_arch_neon; /* true if we have ARM NEON or ASIMD abilities */ +extern int ceph_arch_aarch64_crc32; /* true if we have AArch64 CRC32/CRC32C abilities */ +extern int ceph_arch_aarch64_pmull; /* true if we have AArch64 PMULL abilities */ + +extern int ceph_arch_arm_probe(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/arch/intel.c b/src/arch/intel.c new file mode 100644 index 00000000..5c483dcc --- /dev/null +++ b/src/arch/intel.c @@ -0,0 +1,80 @@ +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2013,2014 Inktank Storage, Inc. + * Copyright (C) 2014 Cloudwatt <libre.licensing@cloudwatt.com> + * + * Author: Loic Dachary <loic@dachary.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + */ +#include <stdio.h> +#include "arch/probe.h" + +/* flags we export */ +int ceph_arch_intel_pclmul = 0; +int ceph_arch_intel_sse42 = 0; +int ceph_arch_intel_sse41 = 0; +int ceph_arch_intel_ssse3 = 0; +int ceph_arch_intel_sse3 = 0; +int ceph_arch_intel_sse2 = 0; +int ceph_arch_intel_aesni = 0; + +#ifdef __x86_64__ +#include <cpuid.h> + +/* http://en.wikipedia.org/wiki/CPUID#EAX.3D1:_Processor_Info_and_Feature_Bits */ + +#define CPUID_PCLMUL (1 << 1) +#define CPUID_SSE42 (1 << 20) +#define CPUID_SSE41 (1 << 19) +#define CPUID_SSSE3 (1 << 9) +#define CPUID_SSE3 (1) +#define CPUID_SSE2 (1 << 26) +#define CPUID_AESNI (1 << 25) + +int ceph_arch_intel_probe(void) +{ + /* i know how to check this on x86_64... */ + unsigned int eax, ebx, ecx = 0, edx = 0; + if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx)) { + return 1; + } + if ((ecx & CPUID_PCLMUL) != 0) { + ceph_arch_intel_pclmul = 1; + } + if ((ecx & CPUID_SSE42) != 0) { + ceph_arch_intel_sse42 = 1; + } + if ((ecx & CPUID_SSE41) != 0) { + ceph_arch_intel_sse41 = 1; + } + if ((ecx & CPUID_SSSE3) != 0) { + ceph_arch_intel_ssse3 = 1; + } + if ((ecx & CPUID_SSE3) != 0) { + ceph_arch_intel_sse3 = 1; + } + if ((edx & CPUID_SSE2) != 0) { + ceph_arch_intel_sse2 = 1; + } + if ((ecx & CPUID_AESNI) != 0) { + ceph_arch_intel_aesni = 1; + } + + return 0; +} + +#else // __x86_64__ + +int ceph_arch_intel_probe(void) +{ + /* no features */ + return 0; +} + +#endif // __x86_64__ diff --git a/src/arch/intel.h b/src/arch/intel.h new file mode 100644 index 00000000..3f4ae948 --- /dev/null +++ b/src/arch/intel.h @@ -0,0 +1,22 @@ +#ifndef CEPH_ARCH_INTEL_H +#define CEPH_ARCH_INTEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern int ceph_arch_intel_pclmul; /* true if we have PCLMUL features */ +extern int ceph_arch_intel_sse42; /* true if we have sse 4.2 features */ +extern int ceph_arch_intel_sse41; /* true if we have sse 4.1 features */ +extern int ceph_arch_intel_ssse3; /* true if we have ssse 3 features */ +extern int ceph_arch_intel_sse3; /* true if we have sse 3 features */ +extern int ceph_arch_intel_sse2; /* true if we have sse 2 features */ +extern int ceph_arch_intel_aesni; /* true if we have aesni features */ + +extern int ceph_arch_intel_probe(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/arch/ppc.c b/src/arch/ppc.c new file mode 100644 index 00000000..11d3a499 --- /dev/null +++ b/src/arch/ppc.c @@ -0,0 +1,40 @@ +/* Copyright (C) 2017 International Business Machines Corp. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include "arch/ppc.h" +#include "arch/probe.h" + +/* flags we export */ +int ceph_arch_ppc_crc32 = 0; + +#include <stdio.h> + +#ifdef HAVE_PPC64LE +#include <sys/auxv.h> +#include <asm/cputable.h> +#endif /* HAVE_PPC64LE */ + +#ifndef PPC_FEATURE2_VEC_CRYPTO +#define PPC_FEATURE2_VEC_CRYPTO 0x02000000 +#endif + +#ifndef AT_HWCAP2 +#define AT_HWCAP2 26 +#endif + +int ceph_arch_ppc_probe(void) +{ + ceph_arch_ppc_crc32 = 0; + +#ifdef HAVE_PPC64LE + if (getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) ceph_arch_ppc_crc32 = 1; +#endif /* HAVE_PPC64LE */ + + return 0; +} + diff --git a/src/arch/ppc.h b/src/arch/ppc.h new file mode 100644 index 00000000..e53d63e3 --- /dev/null +++ b/src/arch/ppc.h @@ -0,0 +1,24 @@ +/* Copyright (C) 2017 International Business Machines Corp. + * All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#ifndef CEPH_ARCH_PPC_H +#define CEPH_ARCH_PPC_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern int ceph_arch_ppc_crc32; + +extern int ceph_arch_ppc_probe(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/arch/probe.cc b/src/arch/probe.cc new file mode 100644 index 00000000..52b913b1 --- /dev/null +++ b/src/arch/probe.cc @@ -0,0 +1,26 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "arch/probe.h" + +#include "arch/intel.h" +#include "arch/arm.h" +#include "arch/ppc.h" + +int ceph_arch_probe(void) +{ + if (ceph_arch_probed) + return 1; +#if defined(__i386__) || defined(__x86_64__) + ceph_arch_intel_probe(); +#elif defined(__arm__) || defined(__aarch64__) + ceph_arch_arm_probe(); +#elif defined(__powerpc__) || defined(__ppc__) + ceph_arch_ppc_probe(); +#endif + ceph_arch_probed = 1; + return 1; +} + +// do this once using the magic of c++. +int ceph_arch_probed = ceph_arch_probe(); diff --git a/src/arch/probe.h b/src/arch/probe.h new file mode 100644 index 00000000..a789c4e8 --- /dev/null +++ b/src/arch/probe.h @@ -0,0 +1,16 @@ +#ifndef CEPH_ARCH_PROBE_H +#define CEPH_ARCH_PROBE_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern int ceph_arch_probed; /* non-zero if we've probed features */ + +extern int ceph_arch_probe(void); + +#ifdef __cplusplus +} +#endif + +#endif |