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 9272d3decSBrad Smith #ifdef CONFIG_LINUX 101d513e06SNatanael Copa # include <asm/cputable.h> 11623d7e35SRichard Henderson # ifdef CONFIG_GETAUXVAL 12623d7e35SRichard Henderson # include <sys/auxv.h> 13623d7e35SRichard Henderson # else 14623d7e35SRichard Henderson # include "elf.h" 15623d7e35SRichard Henderson # endif 16272d3decSBrad Smith #endif 17*27fca0a0SBrad Smith #if defined(CONFIG_ELF_AUX_INFO) 18*27fca0a0SBrad Smith # include <sys/auxv.h> 196527cee2SBrad Smith # include <machine/cpu.h> 206527cee2SBrad Smith # ifndef PPC_FEATURE2_ARCH_3_1 216527cee2SBrad Smith # define PPC_FEATURE2_ARCH_3_1 0 226527cee2SBrad Smith # endif 236527cee2SBrad Smith # define PPC_FEATURE2_VEC_CRYPTO PPC_FEATURE2_HAS_VEC_CRYPTO 246527cee2SBrad Smith #endif 25623d7e35SRichard Henderson 26623d7e35SRichard Henderson unsigned cpuinfo; 27623d7e35SRichard Henderson 28623d7e35SRichard Henderson /* Called both as constructor and (possibly) via other constructors. */ cpuinfo_init(void)29623d7e35SRichard Hendersonunsigned __attribute__((constructor)) cpuinfo_init(void) 30623d7e35SRichard Henderson { 31623d7e35SRichard Henderson unsigned info = cpuinfo; 32623d7e35SRichard Henderson 33623d7e35SRichard Henderson if (info) { 34623d7e35SRichard Henderson return info; 35623d7e35SRichard Henderson } 36623d7e35SRichard Henderson 37623d7e35SRichard Henderson info = CPUINFO_ALWAYS; 38623d7e35SRichard Henderson 39*27fca0a0SBrad Smith #if defined(CONFIG_LINUX) || defined(CONFIG_ELF_AUX_INFO) 40272d3decSBrad Smith unsigned long hwcap = qemu_getauxval(AT_HWCAP); 41272d3decSBrad Smith unsigned long hwcap2 = qemu_getauxval(AT_HWCAP2); 42272d3decSBrad Smith 43623d7e35SRichard Henderson /* Version numbers are monotonic, and so imply all lower versions. */ 44623d7e35SRichard Henderson if (hwcap2 & PPC_FEATURE2_ARCH_3_1) { 45623d7e35SRichard Henderson info |= CPUINFO_V3_1 | CPUINFO_V3_0 | CPUINFO_V2_07 | CPUINFO_V2_06; 46623d7e35SRichard Henderson } else if (hwcap2 & PPC_FEATURE2_ARCH_3_00) { 47623d7e35SRichard Henderson info |= CPUINFO_V3_0 | CPUINFO_V2_07 | CPUINFO_V2_06; 48623d7e35SRichard Henderson } else if (hwcap2 & PPC_FEATURE2_ARCH_2_07) { 49623d7e35SRichard Henderson info |= CPUINFO_V2_07 | CPUINFO_V2_06; 50623d7e35SRichard Henderson } else if (hwcap & PPC_FEATURE_ARCH_2_06) { 51623d7e35SRichard Henderson info |= CPUINFO_V2_06; 52623d7e35SRichard Henderson } 53623d7e35SRichard Henderson 541d513e06SNatanael Copa if (hwcap2 & PPC_FEATURE2_ISEL) { 55623d7e35SRichard Henderson info |= CPUINFO_ISEL; 56623d7e35SRichard Henderson } 57623d7e35SRichard Henderson if (hwcap & PPC_FEATURE_HAS_ALTIVEC) { 58623d7e35SRichard Henderson info |= CPUINFO_ALTIVEC; 59623d7e35SRichard Henderson /* We only care about the portion of VSX that overlaps Altivec. */ 60623d7e35SRichard Henderson if (hwcap & PPC_FEATURE_HAS_VSX) { 61623d7e35SRichard Henderson info |= CPUINFO_VSX; 6257357322SRichard Henderson /* 6357357322SRichard Henderson * We use VSX especially for little-endian, but we should 6457357322SRichard Henderson * always have both anyway, since VSX came with Power7 6557357322SRichard Henderson * and crypto came with Power8. 6657357322SRichard Henderson */ 671d513e06SNatanael Copa if (hwcap2 & PPC_FEATURE2_VEC_CRYPTO) { 6857357322SRichard Henderson info |= CPUINFO_CRYPTO; 6957357322SRichard Henderson } 70623d7e35SRichard Henderson } 71623d7e35SRichard Henderson } 72272d3decSBrad Smith #endif 73623d7e35SRichard Henderson 74623d7e35SRichard Henderson cpuinfo = info; 75623d7e35SRichard Henderson return info; 76623d7e35SRichard Henderson } 77