1623d7e35SRichard Henderson /* 2623d7e35SRichard Henderson * SPDX-License-Identifier: GPL-2.0-or-later 3d02d06f8SMichael Tokarev * Host specific cpu identification for ppc. 4623d7e35SRichard Henderson */ 5623d7e35SRichard Henderson 6623d7e35SRichard Henderson #include "qemu/osdep.h" 7623d7e35SRichard Henderson #include "host/cpuinfo.h" 8623d7e35SRichard Henderson 91d513e06SNatanael Copa #include <asm/cputable.h> 10623d7e35SRichard Henderson #ifdef CONFIG_GETAUXVAL 11623d7e35SRichard Henderson # include <sys/auxv.h> 12623d7e35SRichard Henderson #else 13623d7e35SRichard Henderson # include "elf.h" 14623d7e35SRichard Henderson #endif 15623d7e35SRichard Henderson 16623d7e35SRichard Henderson unsigned cpuinfo; 17623d7e35SRichard Henderson 18623d7e35SRichard Henderson /* Called both as constructor and (possibly) via other constructors. */ cpuinfo_init(void)19623d7e35SRichard Hendersonunsigned __attribute__((constructor)) cpuinfo_init(void) 20623d7e35SRichard Henderson { 21623d7e35SRichard Henderson unsigned info = cpuinfo; 22623d7e35SRichard Henderson unsigned long hwcap, hwcap2; 23623d7e35SRichard Henderson 24623d7e35SRichard Henderson if (info) { 25623d7e35SRichard Henderson return info; 26623d7e35SRichard Henderson } 27623d7e35SRichard Henderson 28623d7e35SRichard Henderson hwcap = qemu_getauxval(AT_HWCAP); 29623d7e35SRichard Henderson hwcap2 = qemu_getauxval(AT_HWCAP2); 30623d7e35SRichard Henderson info = CPUINFO_ALWAYS; 31623d7e35SRichard Henderson 32623d7e35SRichard Henderson /* Version numbers are monotonic, and so imply all lower versions. */ 33623d7e35SRichard Henderson if (hwcap2 & PPC_FEATURE2_ARCH_3_1) { 34623d7e35SRichard Henderson info |= CPUINFO_V3_1 | CPUINFO_V3_0 | CPUINFO_V2_07 | CPUINFO_V2_06; 35623d7e35SRichard Henderson } else if (hwcap2 & PPC_FEATURE2_ARCH_3_00) { 36623d7e35SRichard Henderson info |= CPUINFO_V3_0 | CPUINFO_V2_07 | CPUINFO_V2_06; 37623d7e35SRichard Henderson } else if (hwcap2 & PPC_FEATURE2_ARCH_2_07) { 38623d7e35SRichard Henderson info |= CPUINFO_V2_07 | CPUINFO_V2_06; 39623d7e35SRichard Henderson } else if (hwcap & PPC_FEATURE_ARCH_2_06) { 40623d7e35SRichard Henderson info |= CPUINFO_V2_06; 41623d7e35SRichard Henderson } 42623d7e35SRichard Henderson 431d513e06SNatanael Copa if (hwcap2 & PPC_FEATURE2_ISEL) { 44623d7e35SRichard Henderson info |= CPUINFO_ISEL; 45623d7e35SRichard Henderson } 46623d7e35SRichard Henderson if (hwcap & PPC_FEATURE_HAS_ALTIVEC) { 47623d7e35SRichard Henderson info |= CPUINFO_ALTIVEC; 48623d7e35SRichard Henderson /* We only care about the portion of VSX that overlaps Altivec. */ 49623d7e35SRichard Henderson if (hwcap & PPC_FEATURE_HAS_VSX) { 50623d7e35SRichard Henderson info |= CPUINFO_VSX; 5157357322SRichard Henderson /* 5257357322SRichard Henderson * We use VSX especially for little-endian, but we should 5357357322SRichard Henderson * always have both anyway, since VSX came with Power7 5457357322SRichard Henderson * and crypto came with Power8. 5557357322SRichard Henderson */ 561d513e06SNatanael Copa if (hwcap2 & PPC_FEATURE2_VEC_CRYPTO) { 5757357322SRichard Henderson info |= CPUINFO_CRYPTO; 5857357322SRichard Henderson } 59623d7e35SRichard Henderson } 60623d7e35SRichard Henderson } 61623d7e35SRichard Henderson 62623d7e35SRichard Henderson cpuinfo = info; 63623d7e35SRichard Henderson return info; 64623d7e35SRichard Henderson } 65