Warning: This file is not a C or C++ file. It does not have highlighting.
1 | /* Processor capability information handling macros. PowerPC version. |
---|---|
2 | Copyright (C) 2005-2022 Free Software Foundation, Inc. |
3 | This file is part of the GNU C Library. |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library. If not, see |
17 | <https://www.gnu.org/licenses/>. */ |
18 | |
19 | #ifndef _DL_PROCINFO_H |
20 | #define _DL_PROCINFO_H 1 |
21 | |
22 | #include <ldsodefs.h> |
23 | #include <sysdep.h> /* This defines the PPC_FEATURE[2]_* macros. */ |
24 | |
25 | /* The total number of available bits (including those prior to |
26 | _DL_HWCAP_FIRST). Some of these bits might not be used. */ |
27 | #define _DL_HWCAP_COUNT 64 |
28 | |
29 | /* Features started at bit 31 and decremented as new features were added. */ |
30 | #define _DL_HWCAP_LAST 31 |
31 | |
32 | /* AT_HWCAP2 features started at bit 31 and decremented as new features were |
33 | added. HWCAP2 feature bits start at bit 0. */ |
34 | #define _DL_HWCAP2_LAST 31 |
35 | |
36 | /* These bits influence library search. */ |
37 | #define HWCAP_IMPORTANT (PPC_FEATURE_HAS_ALTIVEC \ |
38 | + PPC_FEATURE_HAS_DFP) |
39 | |
40 | #define _DL_PLATFORMS_COUNT 16 |
41 | |
42 | #define _DL_FIRST_PLATFORM 32 |
43 | /* Mask to filter out platforms. */ |
44 | #define _DL_HWCAP_PLATFORM (((1ULL << _DL_PLATFORMS_COUNT) - 1) \ |
45 | << _DL_FIRST_PLATFORM) |
46 | |
47 | /* Platform bits (relative to _DL_FIRST_PLATFORM). */ |
48 | #define PPC_PLATFORM_POWER4 0 |
49 | #define PPC_PLATFORM_PPC970 1 |
50 | #define PPC_PLATFORM_POWER5 2 |
51 | #define PPC_PLATFORM_POWER5_PLUS 3 |
52 | #define PPC_PLATFORM_POWER6 4 |
53 | #define PPC_PLATFORM_CELL_BE 5 |
54 | #define PPC_PLATFORM_POWER6X 6 |
55 | #define PPC_PLATFORM_POWER7 7 |
56 | #define PPC_PLATFORM_PPCA2 8 |
57 | #define PPC_PLATFORM_PPC405 9 |
58 | #define PPC_PLATFORM_PPC440 10 |
59 | #define PPC_PLATFORM_PPC464 11 |
60 | #define PPC_PLATFORM_PPC476 12 |
61 | #define PPC_PLATFORM_POWER8 13 |
62 | #define PPC_PLATFORM_POWER9 14 |
63 | #define PPC_PLATFORM_POWER10 15 |
64 | |
65 | static inline const char * |
66 | __attribute__ ((unused)) |
67 | _dl_hwcap_string (int idx) |
68 | { |
69 | return GLRO(dl_powerpc_cap_flags)[idx]; |
70 | } |
71 | |
72 | static inline int |
73 | __attribute__ ((unused)) |
74 | _dl_string_hwcap (const char *str) |
75 | { |
76 | for (int i = 0; i < _DL_HWCAP_COUNT; ++i) |
77 | if (strcmp (str, _dl_hwcap_string (i)) == 0) |
78 | return i; |
79 | return -1; |
80 | } |
81 | |
82 | static inline int |
83 | __attribute__ ((unused, always_inline)) |
84 | _dl_string_platform (const char *str) |
85 | { |
86 | if (str == NULL) |
87 | return -1; |
88 | |
89 | if (strncmp (str, "power", 5) == 0) |
90 | { |
91 | int ret; |
92 | str += 5; |
93 | switch (*str) |
94 | { |
95 | case '1': |
96 | if (str[1] == '0') |
97 | { |
98 | ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER10; |
99 | str++; |
100 | } |
101 | else |
102 | return -1; |
103 | break; |
104 | case '4': |
105 | ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER4; |
106 | break; |
107 | case '5': |
108 | ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER5; |
109 | if (str[1] == '+') |
110 | { |
111 | ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER5_PLUS; |
112 | ++str; |
113 | } |
114 | break; |
115 | case '6': |
116 | ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER6; |
117 | if (str[1] == 'x') |
118 | { |
119 | ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER6X; |
120 | ++str; |
121 | } |
122 | break; |
123 | case '7': |
124 | ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER7; |
125 | break; |
126 | case '8': |
127 | ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER8; |
128 | break; |
129 | case '9': |
130 | ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER9; |
131 | break; |
132 | default: |
133 | return -1; |
134 | } |
135 | if (str[1] == '\0') |
136 | return ret; |
137 | } |
138 | else if (strncmp (str, "ppc", 3) == 0) |
139 | { |
140 | if (strcmp (str + 3, "970") == 0) |
141 | return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC970; |
142 | else if (strcmp (str + 3, "-cell-be") == 0) |
143 | return _DL_FIRST_PLATFORM + PPC_PLATFORM_CELL_BE; |
144 | else if (strcmp (str + 3, "a2") == 0) |
145 | return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPCA2; |
146 | else if (strcmp (str + 3, "405") == 0) |
147 | return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC405; |
148 | else if (strcmp (str + 3, "440") == 0) |
149 | return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC440; |
150 | else if (strcmp (str + 3, "464") == 0) |
151 | return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC464; |
152 | else if (strcmp (str + 3, "476") == 0) |
153 | return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC476; |
154 | } |
155 | |
156 | return -1; |
157 | } |
158 | |
159 | #if IS_IN (rtld) |
160 | static inline void |
161 | cache_geometry (const char * name, unsigned long int geometry) |
162 | { |
163 | unsigned long int assocty, line; |
164 | |
165 | _dl_printf ("%s", name); |
166 | |
167 | line = geometry & 0xffff; |
168 | assocty = (geometry >> 16) & 0xffff; |
169 | |
170 | if (line == 0) |
171 | _dl_printf ("Unknown line size, "); |
172 | else |
173 | _dl_printf ("%luB line size, ", line); |
174 | |
175 | switch (assocty) |
176 | { |
177 | case 0: |
178 | _dl_printf ("Unknown associativity"); |
179 | break; |
180 | case 1: |
181 | _dl_printf ("Directly mapped"); |
182 | break; |
183 | case 0xffff: |
184 | _dl_printf ("Fully associative"); |
185 | break; |
186 | default: |
187 | _dl_printf ("%lu-way set associative", assocty); |
188 | } |
189 | } |
190 | |
191 | static inline int |
192 | __attribute__ ((unused)) |
193 | _dl_procinfo (unsigned int type, unsigned long int word) |
194 | { |
195 | switch(type) |
196 | { |
197 | case AT_HWCAP: |
198 | _dl_printf ("AT_HWCAP: "); |
199 | |
200 | for (int i = 0; i <= _DL_HWCAP_LAST; ++i) |
201 | if (word & (1 << i)) |
202 | _dl_printf (" %s", _dl_hwcap_string (i)); |
203 | break; |
204 | case AT_HWCAP2: |
205 | { |
206 | unsigned int offset = _DL_HWCAP_LAST + 1; |
207 | |
208 | _dl_printf ("AT_HWCAP2: "); |
209 | |
210 | /* We have to go through them all because the kernel added the |
211 | AT_HWCAP2 features starting with the high bits. */ |
212 | for (int i = 0; i <= _DL_HWCAP2_LAST; ++i) |
213 | if (word & (1 << i)) |
214 | _dl_printf (" %s", _dl_hwcap_string (offset + i)); |
215 | break; |
216 | } |
217 | case AT_L1I_CACHEGEOMETRY: |
218 | { |
219 | cache_geometry ("AT_L1I_CACHEGEOMETRY: ", word); |
220 | break; |
221 | } |
222 | case AT_L1D_CACHEGEOMETRY: |
223 | { |
224 | cache_geometry ("AT_L1D_CACHEGEOMETRY: ", word); |
225 | break; |
226 | } |
227 | case AT_L2_CACHEGEOMETRY: |
228 | { |
229 | cache_geometry ("AT_L2_CACHEGEOMETRY: ", word); |
230 | break; |
231 | } |
232 | case AT_L3_CACHEGEOMETRY: |
233 | { |
234 | cache_geometry ("AT_L3_CACHEGEOMETRY: ", word); |
235 | break; |
236 | } |
237 | default: |
238 | /* Fallback to generic output mechanism. */ |
239 | return -1; |
240 | } |
241 | _dl_printf ("\n"); |
242 | return 0; |
243 | } |
244 | #endif |
245 | |
246 | #endif /* dl-procinfo.h */ |
247 |
Warning: This file is not a C or C++ file. It does not have highlighting.