]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/powerpc/dl-procinfo.h
powerpc: Placeholder and infrastructure/build support to add Power11 related changes.
[thirdparty/glibc.git] / sysdeps / powerpc / dl-procinfo.h
1 /* Processor capability information handling macros. PowerPC version.
2 Copyright (C) 2005-2024 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 /* Feature masks are all 32-bits in size. */
26 #define _DL_HWCAP_SIZE 32
27
28 /* AT_HWCAP2 feature strings follow the AT_HWCAP feature strings. */
29 #define _DL_HWCAP2_OFFSET _DL_HWCAP_SIZE
30
31 /* AT_HWCAP3 feature strings follow the AT_HWCAP2 feature strings. */
32 #define _DL_HWCAP3_OFFSET (_DL_HWCAP2_OFFSET + _DL_HWCAP_SIZE)
33
34 /* AT_HWCAP4 feature strings follow the AT_HWCAP3 feature strings. */
35 #define _DL_HWCAP4_OFFSET (_DL_HWCAP3_OFFSET + _DL_HWCAP_SIZE)
36
37 /* These bits influence library search. */
38 #define HWCAP_IMPORTANT (PPC_FEATURE_HAS_ALTIVEC \
39 + PPC_FEATURE_HAS_DFP)
40
41 #define _DL_PLATFORMS_COUNT 17
42
43 #define _DL_FIRST_PLATFORM 32
44 /* Mask to filter out platforms. */
45 #define _DL_HWCAP_PLATFORM (((1ULL << _DL_PLATFORMS_COUNT) - 1) \
46 << _DL_FIRST_PLATFORM)
47
48 /* Platform bits (relative to _DL_FIRST_PLATFORM). */
49 #define PPC_PLATFORM_POWER4 0
50 #define PPC_PLATFORM_PPC970 1
51 #define PPC_PLATFORM_POWER5 2
52 #define PPC_PLATFORM_POWER5_PLUS 3
53 #define PPC_PLATFORM_POWER6 4
54 #define PPC_PLATFORM_CELL_BE 5
55 #define PPC_PLATFORM_POWER6X 6
56 #define PPC_PLATFORM_POWER7 7
57 #define PPC_PLATFORM_PPCA2 8
58 #define PPC_PLATFORM_PPC405 9
59 #define PPC_PLATFORM_PPC440 10
60 #define PPC_PLATFORM_PPC464 11
61 #define PPC_PLATFORM_PPC476 12
62 #define PPC_PLATFORM_POWER8 13
63 #define PPC_PLATFORM_POWER9 14
64 #define PPC_PLATFORM_POWER10 15
65 #define PPC_PLATFORM_POWER11 16
66
67 static inline const char *
68 __attribute__ ((unused))
69 _dl_hwcap_string (int idx)
70 {
71 return GLRO(dl_powerpc_cap_flags)[idx];
72 }
73
74 static inline int
75 __attribute__ ((unused, always_inline))
76 _dl_string_platform (const char *str)
77 {
78 if (str == NULL)
79 return -1;
80
81 if (strncmp (str, "power", 5) == 0)
82 {
83 int ret;
84 str += 5;
85 switch (*str)
86 {
87 case '1':
88 if (str[1] == '0')
89 {
90 ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER10;
91 str++;
92 }
93 else if (str[1] == '1')
94 {
95 ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER11;
96 str++;
97 }
98 else
99 return -1;
100 break;
101 case '4':
102 ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER4;
103 break;
104 case '5':
105 ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER5;
106 if (str[1] == '+')
107 {
108 ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER5_PLUS;
109 ++str;
110 }
111 break;
112 case '6':
113 ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER6;
114 if (str[1] == 'x')
115 {
116 ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER6X;
117 ++str;
118 }
119 break;
120 case '7':
121 ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER7;
122 break;
123 case '8':
124 ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER8;
125 break;
126 case '9':
127 ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER9;
128 break;
129 default:
130 return -1;
131 }
132 if (str[1] == '\0')
133 return ret;
134 }
135 else if (strncmp (str, "ppc", 3) == 0)
136 {
137 if (strcmp (str + 3, "970") == 0)
138 return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC970;
139 else if (strcmp (str + 3, "-cell-be") == 0)
140 return _DL_FIRST_PLATFORM + PPC_PLATFORM_CELL_BE;
141 else if (strcmp (str + 3, "a2") == 0)
142 return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPCA2;
143 else if (strcmp (str + 3, "405") == 0)
144 return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC405;
145 else if (strcmp (str + 3, "440") == 0)
146 return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC440;
147 else if (strcmp (str + 3, "464") == 0)
148 return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC464;
149 else if (strcmp (str + 3, "476") == 0)
150 return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC476;
151 }
152
153 return -1;
154 }
155
156 #if IS_IN (rtld)
157 static inline void
158 cache_geometry (const char * name, unsigned long int geometry)
159 {
160 unsigned long int assocty, line;
161
162 _dl_printf ("%s", name);
163
164 line = geometry & 0xffff;
165 assocty = (geometry >> 16) & 0xffff;
166
167 if (line == 0)
168 _dl_printf ("Unknown line size, ");
169 else
170 _dl_printf ("%luB line size, ", line);
171
172 switch (assocty)
173 {
174 case 0:
175 _dl_printf ("Unknown associativity");
176 break;
177 case 1:
178 _dl_printf ("Directly mapped");
179 break;
180 case 0xffff:
181 _dl_printf ("Fully associative");
182 break;
183 default:
184 _dl_printf ("%lu-way set associative", assocty);
185 }
186 }
187
188 static inline int
189 __attribute__ ((unused))
190 _dl_procinfo (unsigned int type, unsigned long int word)
191 {
192 switch(type)
193 {
194 case AT_HWCAP:
195 _dl_printf ("AT_HWCAP: ");
196
197 for (int i = 0; i < _DL_HWCAP_SIZE; ++i)
198 if (word & (1 << i))
199 _dl_printf (" %s", _dl_hwcap_string (i));
200 break;
201 case AT_HWCAP2:
202 {
203
204 _dl_printf ("AT_HWCAP2: ");
205
206 /* We have to go through them all because the kernel added the
207 AT_HWCAP2 features starting with the high bits. */
208 for (int i = 0; i < _DL_HWCAP_SIZE; ++i)
209 if (word & (1 << i))
210 _dl_printf (" %s", _dl_hwcap_string (_DL_HWCAP2_OFFSET + i));
211 break;
212 }
213 case AT_HWCAP3:
214 {
215 _dl_printf ("AT_HWCAP3: ");
216
217 /* We have to go through them all because the kernel added the
218 AT_HWCAP3 features starting with the high bits. */
219 for (int i = 0; i < _DL_HWCAP_SIZE; ++i)
220 if (word & (1 << i))
221 _dl_printf (" %s", _dl_hwcap_string (_DL_HWCAP3_OFFSET + i));
222 break;
223 }
224 case AT_HWCAP4:
225 {
226 _dl_printf ("AT_HWCAP4: ");
227
228 /* We have to go through them all because the kernel added the
229 AT_HWCAP4 features starting with the high bits. */
230 for (int i = 0; i <= _DL_HWCAP_SIZE; ++i)
231 if (word & (1 << i))
232 _dl_printf (" %s", _dl_hwcap_string (_DL_HWCAP4_OFFSET + i));
233 break;
234 }
235 case AT_L1I_CACHEGEOMETRY:
236 {
237 cache_geometry ("AT_L1I_CACHEGEOMETRY: ", word);
238 break;
239 }
240 case AT_L1D_CACHEGEOMETRY:
241 {
242 cache_geometry ("AT_L1D_CACHEGEOMETRY: ", word);
243 break;
244 }
245 case AT_L2_CACHEGEOMETRY:
246 {
247 cache_geometry ("AT_L2_CACHEGEOMETRY: ", word);
248 break;
249 }
250 case AT_L3_CACHEGEOMETRY:
251 {
252 cache_geometry ("AT_L3_CACHEGEOMETRY: ", word);
253 break;
254 }
255 default:
256 /* Fallback to generic output mechanism. */
257 return -1;
258 }
259 _dl_printf ("\n");
260 return 0;
261 }
262 #endif
263
264 #endif /* dl-procinfo.h */