Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:59

0001 /*
0002  *  cpuIdent.c -- Cpu identification code
0003  *
0004  *  Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
0005  *
0006  *  Added MPC8260 Andy Dachs <a.dachs@sstl.co.uk>
0007  *  Surrey Satellite Technology Limited
0008  *
0009  *  The license and distribution terms for this file may be
0010  *  found in the file LICENSE in this distribution or at
0011  *  http://www.rtems.org/license/LICENSE.
0012  *
0013  */
0014 
0015 #include <libcpu/cpuIdent.h>
0016 #include <libcpu/spr.h>
0017 #include <rtems/bspIo.h>
0018 
0019 /*
0020  * Generate inline code to read Processor Version Register
0021  */
0022 SPR_RO(PPC_PVR)
0023 
0024 ppc_cpu_id_t       current_ppc_cpu      = PPC_UNKNOWN;
0025 ppc_cpu_revision_t current_ppc_revision = 0xff;
0026 ppc_feature_t      current_ppc_features;
0027 
0028 const char *get_ppc_cpu_type_name(ppc_cpu_id_t cpu)
0029 {
0030   switch (cpu) {
0031     case PPC_405:       return "PPC405";
0032     case PPC_405GP:     return "PPC405GP";
0033     case PPC_405EX:     return "PPC405EX";
0034     case PPC_440:               return "PPC440";
0035     case PPC_601:       return "MPC601";
0036     case PPC_5XX:       return "MPC5XX";
0037     case PPC_603:       return "MPC603";
0038     case PPC_603ev:     return "MPC603ev";
0039     case PPC_604:       return "MPC604";
0040     case PPC_750:       return "MPC750";
0041     case PPC_750_IBM:       return "IBM PPC750";
0042     case PPC_7400:      return "MPC7400";
0043     case PPC_7455:      return "MPC7455";
0044     case PPC_7457:              return "MPC7457";
0045     case PPC_603le:     return "MPC603le";
0046     case PPC_604e:      return "MPC604e";
0047     case PPC_604r:      return "MPC604r";
0048     case PPC_620:       return "MPC620";
0049     case PPC_860:       return "MPC860";
0050     case PPC_8260:      return "MPC8260";
0051     case PPC_8245:      return "MPC8245";
0052     case PPC_8540:      return "MPC8540";
0053     case PPC_PSIM:      return "PSIM";
0054     case PPC_e200z0:        return "e200z0";
0055     case PPC_e200z1:        return "e200z1";
0056     case PPC_e200z4:        return "e200z4";
0057     case PPC_e200z6:        return "e200z6";
0058     case PPC_e200z7:        return "e200z7";
0059     case PPC_e500v2:        return "e500v2";
0060     case PPC_e6500:     return "e6500";
0061     default:
0062       printk("Unknown CPU value of 0x%x. Please add it to "
0063              "<libcpu/powerpc/shared/include/cpuIdent.c>\n", cpu );
0064   }
0065   return "UNKNOWN";
0066 }
0067 
0068 ppc_cpu_id_t get_ppc_cpu_type(void)
0069 {
0070   /*
0071    * cpu types listed here have the lowermost nibble as a version identifier
0072    * we will tweak them to the standard version
0073    */
0074   const uint32_t ppc_cpu_id_version_nibble[] = {
0075     PPC_e200z0,
0076     PPC_e200z1,
0077     PPC_e200z4,
0078     PPC_e200z6,
0079     PPC_e200z7
0080   };
0081 
0082   unsigned int pvr;
0083   int i;
0084 
0085   if ( PPC_UNKNOWN != current_ppc_cpu )
0086     return current_ppc_cpu;
0087 
0088   pvr = (_read_PPC_PVR() >> 16);
0089   /*
0090    * apply tweaks to ignore version
0091    */
0092   for (i = 0;
0093        i < (sizeof(ppc_cpu_id_version_nibble)
0094         /sizeof(ppc_cpu_id_version_nibble[0]));
0095        i++) {
0096     if ((pvr & 0xfff0) == (ppc_cpu_id_version_nibble[i] & 0xfff0)) {
0097       pvr = ppc_cpu_id_version_nibble[i];
0098       break;
0099     }
0100   }
0101 
0102   current_ppc_cpu = (ppc_cpu_id_t) pvr;
0103 
0104   switch (pvr) {
0105     case PPC_405:
0106     case PPC_405GP:
0107     case PPC_405EX:
0108     case PPC_440:
0109     case PPC_601:
0110     case PPC_5XX:
0111     case PPC_603:
0112     case PPC_603ev:
0113     case PPC_603le:
0114     case PPC_604:
0115     case PPC_604r:
0116     case PPC_750:
0117     case PPC_750_IBM:
0118     case PPC_7400:
0119     case PPC_7455:
0120     case PPC_7457:
0121     case PPC_604e:
0122     case PPC_620:
0123     case PPC_860:
0124     case PPC_8260:
0125     case PPC_8245:
0126     case PPC_PSIM:
0127     case PPC_8540:
0128     case PPC_e200z0:
0129     case PPC_e200z1:
0130     case PPC_e200z4:
0131     case PPC_e200z6:
0132     case PPC_e200z7:
0133     case PPC_e300c1:
0134     case PPC_e300c2:
0135     case PPC_e300c3:
0136     case PPC_e500v2:
0137     case PPC_e6500:
0138       break;
0139     default:
0140       printk("Unknown PVR value of 0x%x. Please add it to "
0141              "<libcpu/powerpc/shared/include/cpuIdent.c>\n", pvr );
0142     return PPC_UNKNOWN;
0143   }
0144 
0145   /* determine features */
0146 
0147   /* FIXME: This is incomplete; I couldn't go through all the
0148    * manuals (yet).
0149    */
0150   switch ( current_ppc_cpu ) {
0151     case PPC_7455:
0152     case PPC_7457:
0153         current_ppc_features.has_8_bats         = 1;
0154     case PPC_7400:
0155     /* NOTE: PSIM PVR doesn't tell us anything (its
0156      *       contents are not set based on what model
0157        *       the user chooses but has to be programmed via
0158      *       the device file with the special value 0xfffe
0159      *       telling us that we have a 'psim cpu').
0160      *
0161      *       I'm not sure pagetables work if the user chooses
0162      *       e.g., the 603 model...
0163      */
0164     case PPC_PSIM:
0165         current_ppc_features.has_altivec        = 1;
0166     case PPC_604:
0167     case PPC_604e:
0168     case PPC_604r:
0169     case PPC_750:
0170     case PPC_750_IBM:
0171         current_ppc_features.has_hw_ptbl_lkup   = 1;
0172     case PPC_8260:
0173     case PPC_8245:
0174     case PPC_601:
0175     case PPC_603:
0176     case PPC_603e:
0177     case PPC_603ev:
0178     case PPC_603le:
0179         current_ppc_features.is_60x             = 1;
0180     default:
0181     break;
0182   }
0183 
0184   switch ( current_ppc_cpu ) {
0185     case PPC_e6500:
0186       current_ppc_features.has_altivec = 1;
0187       break;
0188     default:
0189       break;
0190   }
0191 
0192   switch ( current_ppc_cpu ) {
0193     case PPC_405:
0194     case PPC_405GP:
0195     case PPC_405EX:
0196         current_ppc_features.is_bookE           = PPC_BOOKE_405;
0197     break;
0198     case PPC_440:
0199       current_ppc_features.is_bookE          = PPC_BOOKE_STD;
0200       break;
0201     case PPC_8540:
0202     case PPC_e200z0:
0203     case PPC_e200z1:
0204     case PPC_e200z4:
0205     case PPC_e200z6:
0206     case PPC_e200z7:
0207     case PPC_e500v2:
0208     case PPC_e6500:
0209         current_ppc_features.is_bookE           = PPC_BOOKE_E500;
0210         break;
0211     default:
0212     break;
0213   }
0214 
0215   switch ( current_ppc_cpu ) {
0216     case PPC_860:
0217         current_ppc_features.has_16byte_clne    = 1;
0218     default:
0219     break;
0220   }
0221 
0222   switch ( current_ppc_cpu ) {
0223     case PPC_603e:
0224     case PPC_603ev:
0225     case PPC_603le:
0226     case PPC_e300c1:
0227     case PPC_e300c2:
0228     case PPC_e300c3:
0229     case PPC_8240:
0230         current_ppc_features.has_shadowed_gprs  = 1;
0231     default:
0232     break;
0233   }
0234 
0235   return current_ppc_cpu;
0236 }
0237 
0238 ppc_cpu_revision_t get_ppc_cpu_revision(void)
0239 {
0240   ppc_cpu_revision_t rev = (ppc_cpu_revision_t) (_read_PPC_PVR() & 0xffff);
0241   current_ppc_revision = rev;
0242   return rev;
0243 }