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