(root)/
glibc-2.38/
sysdeps/
powerpc/
dl-procinfo.h
       1  /* Processor capability information handling macros.  PowerPC version.
       2     Copyright (C) 2005-2023 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, always_inline))
      74  _dl_string_platform (const char *str)
      75  {
      76    if (str == NULL)
      77      return -1;
      78  
      79    if (strncmp (str, "power", 5) == 0)
      80      {
      81        int ret;
      82        str += 5;
      83        switch (*str)
      84  	{
      85  	case '1':
      86  	  if (str[1] == '0')
      87  	    {
      88  	      ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER10;
      89  	      str++;
      90  	    }
      91  	  else
      92  	    return -1;
      93  	  break;
      94  	case '4':
      95  	  ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER4;
      96  	  break;
      97  	case '5':
      98  	  ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER5;
      99  	  if (str[1] == '+')
     100  	    {
     101  	      ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER5_PLUS;
     102  	      ++str;
     103  	    }
     104  	  break;
     105  	case '6':
     106  	  ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER6;
     107  	  if (str[1] == 'x')
     108  	    {
     109  	      ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER6X;
     110  	      ++str;
     111  	    }
     112  	  break;
     113  	case '7':
     114  	  ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER7;
     115  	  break;
     116  	case '8':
     117  	  ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER8;
     118  	  break;
     119  	case '9':
     120  	  ret = _DL_FIRST_PLATFORM + PPC_PLATFORM_POWER9;
     121  	  break;
     122  	default:
     123  	  return -1;
     124  	}
     125        if (str[1] == '\0')
     126         return ret;
     127      }
     128    else if (strncmp (str, "ppc", 3) == 0)
     129      {
     130        if (strcmp (str + 3, "970") == 0)
     131  	return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC970;
     132        else if (strcmp (str + 3, "-cell-be") == 0)
     133  	return _DL_FIRST_PLATFORM + PPC_PLATFORM_CELL_BE;
     134        else if (strcmp (str + 3, "a2") == 0)
     135  	return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPCA2;
     136        else if (strcmp (str + 3, "405") == 0)
     137  	return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC405;
     138        else if (strcmp (str + 3, "440") == 0)
     139  	return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC440;
     140        else if (strcmp (str + 3, "464") == 0)
     141  	return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC464;
     142        else if (strcmp (str + 3, "476") == 0)
     143  	return _DL_FIRST_PLATFORM + PPC_PLATFORM_PPC476;
     144      }
     145  
     146    return -1;
     147  }
     148  
     149  #if IS_IN (rtld)
     150  static inline void
     151  cache_geometry (const char * name, unsigned long int geometry)
     152  {
     153    unsigned long int assocty, line;
     154  
     155    _dl_printf ("%s", name);
     156  
     157    line = geometry & 0xffff;
     158    assocty = (geometry >> 16) & 0xffff;
     159  
     160    if (line == 0)
     161      _dl_printf ("Unknown line size, ");
     162    else
     163      _dl_printf ("%luB line size, ", line);
     164  
     165    switch (assocty)
     166      {
     167      case 0:
     168        _dl_printf ("Unknown associativity");
     169        break;
     170      case 1:
     171        _dl_printf ("Directly mapped");
     172        break;
     173      case 0xffff:
     174        _dl_printf ("Fully associative");
     175        break;
     176      default:
     177        _dl_printf ("%lu-way set associative", assocty);
     178      }
     179  }
     180  
     181  static inline int
     182  __attribute__ ((unused))
     183  _dl_procinfo (unsigned int type, unsigned long int word)
     184  {
     185    switch(type)
     186      {
     187      case AT_HWCAP:
     188        _dl_printf ("AT_HWCAP:            ");
     189  
     190        for (int i = 0; i <= _DL_HWCAP_LAST; ++i)
     191         if (word & (1 << i))
     192           _dl_printf (" %s", _dl_hwcap_string (i));
     193        break;
     194      case AT_HWCAP2:
     195        {
     196         unsigned int offset = _DL_HWCAP_LAST + 1;
     197  
     198         _dl_printf ("AT_HWCAP2:           ");
     199  
     200          /* We have to go through them all because the kernel added the
     201            AT_HWCAP2 features starting with the high bits.  */
     202         for (int i = 0; i <= _DL_HWCAP2_LAST; ++i)
     203           if (word & (1 << i))
     204             _dl_printf (" %s", _dl_hwcap_string (offset + i));
     205         break;
     206        }
     207      case AT_L1I_CACHEGEOMETRY:
     208        {
     209  	cache_geometry ("AT_L1I_CACHEGEOMETRY: ", word);
     210  	break;
     211        }
     212      case AT_L1D_CACHEGEOMETRY:
     213        {
     214  	cache_geometry ("AT_L1D_CACHEGEOMETRY: ", word);
     215  	break;
     216        }
     217      case AT_L2_CACHEGEOMETRY:
     218        {
     219  	cache_geometry ("AT_L2_CACHEGEOMETRY:  ", word);
     220  	break;
     221        }
     222      case AT_L3_CACHEGEOMETRY:
     223        {
     224  	cache_geometry ("AT_L3_CACHEGEOMETRY:  ", word);
     225  	break;
     226        }
     227      default:
     228        /* Fallback to generic output mechanism.  */
     229        return -1;
     230      }
     231     _dl_printf ("\n");
     232    return 0;
     233  }
     234  #endif
     235  
     236  #endif /* dl-procinfo.h */