1 /* Get system-specific information at run-time.  Linux/powerpc version.
2    Copyright (C) 2017-2021 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 #include <errno.h>
20 #include <unistd.h>
21 #include <sys/auxv.h>
22 
23 static long linux_sysconf (int name);
24 
25 static inline long
auxv2sysconf_cache_associativity(unsigned long type)26 auxv2sysconf_cache_associativity (unsigned long type)
27 {
28   return (__getauxval (type) & 0xffff0000) >> 16;
29 }
30 
31 static inline long
auxv2sysconf_cache_linesize(unsigned long type)32 auxv2sysconf_cache_linesize (unsigned long type)
33 {
34   return __getauxval (type) & 0xffff;
35 }
36 
37 /* Get the value of the system variable NAME.  */
38 long int
__sysconf(int name)39 __sysconf (int name)
40 {
41   switch (name)
42     {
43       case _SC_LEVEL1_ICACHE_SIZE:
44 	return __getauxval (AT_L1I_CACHESIZE);
45       case _SC_LEVEL1_ICACHE_ASSOC:
46 	return auxv2sysconf_cache_associativity (AT_L1I_CACHEGEOMETRY);
47       case _SC_LEVEL1_ICACHE_LINESIZE:
48 	return auxv2sysconf_cache_linesize (AT_L1I_CACHEGEOMETRY);
49       case _SC_LEVEL1_DCACHE_SIZE:
50 	return __getauxval (AT_L1D_CACHESIZE);
51       case _SC_LEVEL1_DCACHE_ASSOC:
52 	return auxv2sysconf_cache_associativity (AT_L1D_CACHEGEOMETRY);
53       case _SC_LEVEL1_DCACHE_LINESIZE:
54 	return auxv2sysconf_cache_linesize (AT_L1D_CACHEGEOMETRY);
55       case _SC_LEVEL2_CACHE_SIZE:
56 	return __getauxval (AT_L2_CACHESIZE);
57       case _SC_LEVEL2_CACHE_ASSOC:
58 	return auxv2sysconf_cache_associativity (AT_L2_CACHEGEOMETRY);
59       case _SC_LEVEL2_CACHE_LINESIZE:
60 	return auxv2sysconf_cache_linesize (AT_L2_CACHEGEOMETRY);
61       case _SC_LEVEL3_CACHE_SIZE:
62 	return __getauxval (AT_L3_CACHESIZE);
63       case _SC_LEVEL3_CACHE_ASSOC:
64 	return auxv2sysconf_cache_associativity (AT_L3_CACHEGEOMETRY);
65       case _SC_LEVEL3_CACHE_LINESIZE:
66 	return auxv2sysconf_cache_linesize (AT_L3_CACHEGEOMETRY);
67       default:
68 	return linux_sysconf (name);
69     }
70 }
71 
72 /* Now the generic Linux version.  */
73 #undef __sysconf
74 #define __sysconf static linux_sysconf
75 #include "../sysconf.c"
76