1 /* 2 * SPDX-License-Identifier: GPL-2.0-or-later 3 * Host specific cpu identification for ppc. 4 */ 5 6 #include "qemu/osdep.h" 7 #include "host/cpuinfo.h" 8 9 #include <asm/cputable.h> 10 #ifdef CONFIG_GETAUXVAL 11 # include <sys/auxv.h> 12 #else 13 # include "elf.h" 14 #endif 15 16 unsigned cpuinfo; 17 18 /* Called both as constructor and (possibly) via other constructors. */ 19 unsigned __attribute__((constructor)) cpuinfo_init(void) 20 { 21 unsigned info = cpuinfo; 22 unsigned long hwcap, hwcap2; 23 24 if (info) { 25 return info; 26 } 27 28 hwcap = qemu_getauxval(AT_HWCAP); 29 hwcap2 = qemu_getauxval(AT_HWCAP2); 30 info = CPUINFO_ALWAYS; 31 32 /* Version numbers are monotonic, and so imply all lower versions. */ 33 if (hwcap2 & PPC_FEATURE2_ARCH_3_1) { 34 info |= CPUINFO_V3_1 | CPUINFO_V3_0 | CPUINFO_V2_07 | CPUINFO_V2_06; 35 } else if (hwcap2 & PPC_FEATURE2_ARCH_3_00) { 36 info |= CPUINFO_V3_0 | CPUINFO_V2_07 | CPUINFO_V2_06; 37 } else if (hwcap2 & PPC_FEATURE2_ARCH_2_07) { 38 info |= CPUINFO_V2_07 | CPUINFO_V2_06; 39 } else if (hwcap & PPC_FEATURE_ARCH_2_06) { 40 info |= CPUINFO_V2_06; 41 } 42 43 if (hwcap2 & PPC_FEATURE2_ISEL) { 44 info |= CPUINFO_ISEL; 45 } 46 if (hwcap & PPC_FEATURE_HAS_ALTIVEC) { 47 info |= CPUINFO_ALTIVEC; 48 /* We only care about the portion of VSX that overlaps Altivec. */ 49 if (hwcap & PPC_FEATURE_HAS_VSX) { 50 info |= CPUINFO_VSX; 51 /* 52 * We use VSX especially for little-endian, but we should 53 * always have both anyway, since VSX came with Power7 54 * and crypto came with Power8. 55 */ 56 if (hwcap2 & PPC_FEATURE2_VEC_CRYPTO) { 57 info |= CPUINFO_CRYPTO; 58 } 59 } 60 } 61 62 cpuinfo = info; 63 return info; 64 } 65