eal: revert C++ app build fix
[dpdk.git] / lib / librte_eal / common / include / arch / ppc_64 / rte_cpuflags.h
1 /*
2  *   BSD LICENSE
3  *
4  *   Copyright (C) IBM Corporation 2014.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided with the
15  *       distribution.
16  *     * Neither the name of IBM Corporation nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #ifndef _RTE_CPUFLAGS_PPC_64_H_
34 #define _RTE_CPUFLAGS_PPC_64_H_
35
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39
40 #include <elf.h>
41 #include <fcntl.h>
42 #include <assert.h>
43 #include <unistd.h>
44
45 #include "generic/rte_cpuflags.h"
46
47 /* Symbolic values for the entries in the auxiliary table */
48 #define AT_HWCAP  16
49 #define AT_HWCAP2 26
50
51 /* software based registers */
52 enum cpu_register_t {
53         REG_HWCAP = 0,
54         REG_HWCAP2,
55 };
56
57 /**
58  * Enumeration of all CPU features supported
59  */
60 enum rte_cpu_flag_t {
61         RTE_CPUFLAG_PPC_LE = 0,
62         RTE_CPUFLAG_TRUE_LE,
63         RTE_CPUFLAG_PSERIES_PERFMON_COMPAT,
64         RTE_CPUFLAG_VSX,
65         RTE_CPUFLAG_ARCH_2_06,
66         RTE_CPUFLAG_POWER6_EXT,
67         RTE_CPUFLAG_DFP,
68         RTE_CPUFLAG_PA6T,
69         RTE_CPUFLAG_ARCH_2_05,
70         RTE_CPUFLAG_ICACHE_SNOOP,
71         RTE_CPUFLAG_SMT,
72         RTE_CPUFLAG_BOOKE,
73         RTE_CPUFLAG_CELLBE,
74         RTE_CPUFLAG_POWER5_PLUS,
75         RTE_CPUFLAG_POWER5,
76         RTE_CPUFLAG_POWER4,
77         RTE_CPUFLAG_NOTB,
78         RTE_CPUFLAG_EFP_DOUBLE,
79         RTE_CPUFLAG_EFP_SINGLE,
80         RTE_CPUFLAG_SPE,
81         RTE_CPUFLAG_UNIFIED_CACHE,
82         RTE_CPUFLAG_4xxMAC,
83         RTE_CPUFLAG_MMU,
84         RTE_CPUFLAG_FPU,
85         RTE_CPUFLAG_ALTIVEC,
86         RTE_CPUFLAG_PPC601,
87         RTE_CPUFLAG_PPC64,
88         RTE_CPUFLAG_PPC32,
89         RTE_CPUFLAG_TAR,
90         RTE_CPUFLAG_LSEL,
91         RTE_CPUFLAG_EBB,
92         RTE_CPUFLAG_DSCR,
93         RTE_CPUFLAG_HTM,
94         RTE_CPUFLAG_ARCH_2_07,
95         /* The last item */
96         RTE_CPUFLAG_NUMFLAGS,/**< This should always be the last! */
97 };
98
99 static const struct feature_entry cpu_feature_table[] = {
100         FEAT_DEF(PPC_LE, 0x00000001, 0, REG_HWCAP,  0)
101         FEAT_DEF(TRUE_LE, 0x00000001, 0, REG_HWCAP,  1)
102         FEAT_DEF(PSERIES_PERFMON_COMPAT, 0x00000001, 0, REG_HWCAP,  6)
103         FEAT_DEF(VSX, 0x00000001, 0, REG_HWCAP,  7)
104         FEAT_DEF(ARCH_2_06, 0x00000001, 0, REG_HWCAP,  8)
105         FEAT_DEF(POWER6_EXT, 0x00000001, 0, REG_HWCAP,  9)
106         FEAT_DEF(DFP, 0x00000001, 0, REG_HWCAP,  10)
107         FEAT_DEF(PA6T, 0x00000001, 0, REG_HWCAP,  11)
108         FEAT_DEF(ARCH_2_05, 0x00000001, 0, REG_HWCAP,  12)
109         FEAT_DEF(ICACHE_SNOOP, 0x00000001, 0, REG_HWCAP,  13)
110         FEAT_DEF(SMT, 0x00000001, 0, REG_HWCAP,  14)
111         FEAT_DEF(BOOKE, 0x00000001, 0, REG_HWCAP,  15)
112         FEAT_DEF(CELLBE, 0x00000001, 0, REG_HWCAP,  16)
113         FEAT_DEF(POWER5_PLUS, 0x00000001, 0, REG_HWCAP,  17)
114         FEAT_DEF(POWER5, 0x00000001, 0, REG_HWCAP,  18)
115         FEAT_DEF(POWER4, 0x00000001, 0, REG_HWCAP,  19)
116         FEAT_DEF(NOTB, 0x00000001, 0, REG_HWCAP,  20)
117         FEAT_DEF(EFP_DOUBLE, 0x00000001, 0, REG_HWCAP,  21)
118         FEAT_DEF(EFP_SINGLE, 0x00000001, 0, REG_HWCAP,  22)
119         FEAT_DEF(SPE, 0x00000001, 0, REG_HWCAP,  23)
120         FEAT_DEF(UNIFIED_CACHE, 0x00000001, 0, REG_HWCAP,  24)
121         FEAT_DEF(4xxMAC, 0x00000001, 0, REG_HWCAP,  25)
122         FEAT_DEF(MMU, 0x00000001, 0, REG_HWCAP,  26)
123         FEAT_DEF(FPU, 0x00000001, 0, REG_HWCAP,  27)
124         FEAT_DEF(ALTIVEC, 0x00000001, 0, REG_HWCAP,  28)
125         FEAT_DEF(PPC601, 0x00000001, 0, REG_HWCAP,  29)
126         FEAT_DEF(PPC64, 0x00000001, 0, REG_HWCAP,  30)
127         FEAT_DEF(PPC32, 0x00000001, 0, REG_HWCAP,  31)
128         FEAT_DEF(TAR, 0x00000001, 0, REG_HWCAP2,  26)
129         FEAT_DEF(LSEL, 0x00000001, 0, REG_HWCAP2,  27)
130         FEAT_DEF(EBB, 0x00000001, 0, REG_HWCAP2,  28)
131         FEAT_DEF(DSCR, 0x00000001, 0, REG_HWCAP2,  29)
132         FEAT_DEF(HTM, 0x00000001, 0, REG_HWCAP2,  30)
133         FEAT_DEF(ARCH_2_07, 0x00000001, 0, REG_HWCAP2,  31)
134 };
135
136 /*
137  * Read AUXV software register and get cpu features for Power
138  */
139 static inline void
140 rte_cpu_get_features(__attribute__((unused)) uint32_t leaf,
141         __attribute__((unused)) uint32_t subleaf, cpuid_registers_t out)
142 {
143         int auxv_fd;
144         Elf64_auxv_t auxv;
145
146         auxv_fd = open("/proc/self/auxv", O_RDONLY);
147         assert(auxv_fd);
148         while (read(auxv_fd, &auxv,
149                 sizeof(Elf64_auxv_t)) == sizeof(Elf64_auxv_t)) {
150                 if (auxv.a_type == AT_HWCAP)
151                         out[REG_HWCAP] = auxv.a_un.a_val;
152                 else if (auxv.a_type == AT_HWCAP2)
153                         out[REG_HWCAP2] = auxv.a_un.a_val;
154         }
155 }
156
157 /*
158  * Checks if a particular flag is available on current machine.
159  */
160 static inline int
161 rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
162 {
163         const struct feature_entry *feat;
164         cpuid_registers_t regs = {0};
165
166         if (feature >= RTE_CPUFLAG_NUMFLAGS)
167                 /* Flag does not match anything in the feature tables */
168                 return -ENOENT;
169
170         feat = &cpu_feature_table[feature];
171
172         if (!feat->leaf)
173                 /* This entry in the table wasn't filled out! */
174                 return -EFAULT;
175
176         /* get the cpuid leaf containing the desired feature */
177         rte_cpu_get_features(feat->leaf, feat->subleaf, regs);
178
179         /* check if the feature is enabled */
180         return (regs[feat->reg] >> feat->bit) & 1;
181 }
182
183 #ifdef __cplusplus
184 }
185 #endif
186
187 #endif /* _RTE_CPUFLAGS_PPC_64_H_ */