I'm on GCC112, which is a little-endian Power8 machine running Linux. Power8 has in-core crypto providing AES, SHA and a few other useful features. I'm trying to determine the availability of the features at runtime using getauxval
. The use case is distros building for a "minimum" capable machine, and we need to swap-in a faster function at runtime.
The dump of hwcaps.h
is shown below, but it lacks specific bits for Power8, AES, SHA and others. However, I believe Power8 is ISA 2.07, and ISA 2.07 has the bit PPC_FEATURE2_ARCH_2_07
.
The thing I am not clear on is, is Power8 in-core crypto optional like ARM's crypto under ARMv8. I can't find a document that clearly states the requirement, and I don't have a membership to OpenPower to access ISA documents. (Another possibility is, it is stated but I missed it in the docs).
Is it possible to use getauxval
to query the runtime environment for the features? If not, then how do we determine feature availability at runtime? Is CPU probing the only alternative available?
Maybe more generally, how do we determine Power6, Power7 and Power8 runtime environments?
auxv.h
is mostly empty. The header file includes hwcaps.h
.
$ cat /usr/include/bits/hwcap.h
...
/* The bit numbers must match those in the kernel's asm/cputable.h. */
/* Feature definitions in AT_HWCAP. */
#define PPC_FEATURE_32 0x80000000 /* 32-bit mode. */
#define PPC_FEATURE_64 0x40000000 /* 64-bit mode. */
#define PPC_FEATURE_601_INSTR 0x20000000 /* 601 chip, Old POWER ISA. */
#define PPC_FEATURE_HAS_ALTIVEC 0x10000000 /* SIMD/Vector Unit. */
#define PPC_FEATURE_HAS_FPU 0x08000000 /* Floating Point Unit. */
#define PPC_FEATURE_HAS_MMU 0x04000000 /* Memory Management Unit. */
#define PPC_FEATURE_HAS_4xxMAC 0x02000000 /* 4xx Multiply Accumulator. */
#define PPC_FEATURE_UNIFIED_CACHE 0x01000000 /* Unified I/D cache. */
#define PPC_FEATURE_HAS_SPE 0x00800000 /* Signal Processing ext. */
#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000 /* SPE Float. */
#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000 /* SPE Double. */
#define PPC_FEATURE_NO_TB 0x00100000 /* 601/403gx have no timebase */
#define PPC_FEATURE_POWER4 0x00080000 /* POWER4 ISA 2.00 */
#define PPC_FEATURE_POWER5 0x00040000 /* POWER5 ISA 2.02 */
#define PPC_FEATURE_POWER5_PLUS 0x00020000 /* POWER5+ ISA 2.03 */
#define PPC_FEATURE_CELL_BE 0x00010000 /* CELL Broadband Engine */
#define PPC_FEATURE_BOOKE 0x00008000 /* ISA Category Embedded */
#define PPC_FEATURE_SMT 0x00004000 /* Simultaneous
Multi-Threading */
#define PPC_FEATURE_ICACHE_SNOOP 0x00002000
#define PPC_FEATURE_ARCH_2_05 0x00001000 /* ISA 2.05 */
#define PPC_FEATURE_PA6T 0x00000800 /* PA Semi 6T Core */
#define PPC_FEATURE_HAS_DFP 0x00000400 /* Decimal FP Unit */
#define PPC_FEATURE_POWER6_EXT 0x00000200 /* P6 + mffgpr/mftgpr */
#define PPC_FEATURE_ARCH_2_06 0x00000100 /* ISA 2.06 */
#define PPC_FEATURE_HAS_VSX 0x00000080 /* P7 Vector Extension. */
#define PPC_FEATURE_PSERIES_PERFMON_COMPAT 0x00000040
#define PPC_FEATURE_TRUE_LE 0x00000002
#define PPC_FEATURE_PPC_LE 0x00000001
/* Feature definitions in AT_HWCAP2. */
#define PPC_FEATURE2_ARCH_2_07 0x80000000 /* ISA 2.07 */
#define PPC_FEATURE2_HAS_HTM 0x40000000 /* Hardware Transactional
Memory */
#define PPC_FEATURE2_HAS_DSCR 0x20000000 /* Data Stream Control
Register */
#define PPC_FEATURE2_HAS_EBB 0x10000000 /* Event Base Branching */
#define PPC_FEATURE2_HAS_ISEL 0x08000000 /* Integer Select */
#define PPC_FEATURE2_HAS_TAR 0x04000000 /* Target Address Register */
I'd say that
getauxval()
would be the best way to do this; theHWCAP
&HWCAP2
values are exactly for determining hardware features. Missing from your list is thePPC_FEATURE2_VEC_CRYPTO
, which indicates the presence of the vector crypto instructions, which sounds like the one you need.As a side note: you probably don't want to detect processor implementations, but processor features. Specifically, check for the individual feature, rather than trying to check for a process that provides that feature. (eg., detect
VEC_CRYPTO
directly, rather than trying to check for POWER8, and assume that that implies crypto functionality).As a bit of detail, Linux's cputable entries specify the
HWCAP
/HWCAP2
values. Using POWER8 as an example:That's from
arch/powerpc/include/asm/cputable.h
in the kernel (which also provides the actual hwcap bits that can be set in the aux vector).Finally, I'm fairly sure you don't need to be an OpenPOWER foundation member to download the ISA (latest is 3.0B) - you just need an account on the website.