Back to home page

LXR

 
 

    


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

0001 /*
0002  *  This file contains code for displaying the Intel Cpu identification
0003  *  that has been performed by checkCPUtypeSetCr0 function.
0004  */
0005 
0006 /*
0007  *  This file was updated by Joel Sherrill <joel.sherrill@oarcorp.com>
0008  *  to define more capability bits, pick up more CPU model information,
0009  *  and add more model strings. --joel (April 2010)
0010  *
0011  *  COPYRIGHT (c) 1998 valette@crf.canon.fr
0012  *  COPYRIGHT (c) 2010 OAR Corporation
0013  *
0014  *  The license and distribution terms for this file may be
0015  *  found in the file LICENSE in this distribution or at
0016  *  http://www.rtems.org/license/LICENSE.
0017  */
0018 
0019 /*
0020  * Tell us the machine setup..
0021  */
0022 #include <stdio.h>
0023 #include <rtems/score/cpu.h>
0024 #include <string.h>
0025 #include <libcpu/cpuModel.h>
0026 #include <rtems/bspIo.h>
0027 #include <rtems.h>
0028 
0029 unsigned char Cx86_step = 0;
0030 
0031 static const char *Cx86_type[] = {
0032   "unknown", "1.3", "1.4", "1.5", "1.6",
0033   "2.4", "2.5", "2.6", "2.7 or 3.7", "4.2"
0034   };
0035 
0036 static const char *i486model(unsigned int nr)
0037 {
0038   static const char *model[] = {
0039     "0","DX","SX","DX/2","4","SX/2","6","DX/2-WB","DX/4","DX/4-WB",
0040     "10","11","12","13","Am5x86-WT","Am5x86-WB"
0041   };
0042 
0043   if (nr < sizeof(model)/sizeof(char *))
0044     return model[nr];
0045   return NULL;
0046 }
0047 
0048 static const char * i586model(unsigned int nr)
0049 {
0050   static const char *model[] = {
0051     "0", "Pentium 60/66","Pentium 75+","OverDrive PODP5V83",
0052     "Pentium MMX", NULL, NULL, "Mobile Pentium 75+",
0053     "Mobile Pentium MMX"
0054   };
0055   if (nr < sizeof(model)/sizeof(char *))
0056     return model[nr];
0057   return NULL;
0058 }
0059 
0060 static const char *Cx86model(void)
0061 {
0062   unsigned char nr6x86 = 0;
0063   static const char *model[] = {
0064     "unknown", "6x86", "6x86L", "6x86MX", "MII"
0065   };
0066 
0067   switch (x86) {
0068     case 5:
0069       /* cx8 flag only on 6x86L */
0070       nr6x86 = ((x86_capability & (1 << 8)) ? 2 : 1);
0071       break;
0072     case 6:
0073       nr6x86 = 3;
0074       break;
0075     default:
0076       nr6x86 = 0;
0077   }
0078 
0079   /* We must get the stepping number by reading DIR1 */
0080   outport_byte(0x22,0xff);
0081   inport_byte(0x23, x86_mask);
0082   switch (x86_mask) {
0083     case 0x03:
0084       Cx86_step =  1;  /* 6x86MX Rev 1.3 */
0085       break;
0086     case 0x04:
0087       Cx86_step =  2;  /* 6x86MX Rev 1.4 */
0088       break;
0089     case 0x05:
0090       Cx86_step =  3;  /* 6x86MX Rev 1.5 */
0091       break;
0092     case 0x06:
0093       Cx86_step =  4;  /* 6x86MX Rev 1.6 */
0094       break;
0095     case 0x14:
0096       Cx86_step =  5;  /* 6x86 Rev 2.4 */
0097       break;
0098     case 0x15:
0099       Cx86_step =  6;  /* 6x86 Rev 2.5 */
0100       break;
0101     case 0x16:
0102       Cx86_step =  7;  /* 6x86 Rev 2.6 */
0103       break;
0104     case 0x17:
0105       Cx86_step =  8;  /* 6x86 Rev 2.7 or 3.7 */
0106       break;
0107     case 0x22:
0108       Cx86_step =  9;  /* 6x86L Rev 4.2 */
0109       break;
0110     default:
0111       Cx86_step = 0;
0112   }
0113   return model[nr6x86];
0114 }
0115 
0116 static const char * i686model(unsigned int nr)
0117 {
0118   static const char *model[] = {
0119     "PPro A-step",
0120     "Pentium Pro"
0121   };
0122   if (nr < sizeof(model)/sizeof(char *))
0123     return model[nr];
0124   return NULL;
0125 }
0126 
0127 struct cpu_model_info {
0128   int x86;
0129   char *model_names[16];
0130 };
0131 
0132 static struct cpu_model_info amd_models[] = {
0133   { 4,
0134     { NULL, NULL, NULL, "DX/2", NULL, NULL, NULL, "DX/2-WB", "DX/4",
0135       "DX/4-WB", NULL, NULL, NULL, NULL, "Am5x86-WT", "Am5x86-WB" }},
0136   { 5,
0137     { "K5/SSA5 (PR-75, PR-90, PR-100)", "K5 (PR-120, PR-133)",
0138       "K5 (PR-166)", "K5 (PR-200)", NULL, NULL,
0139       "K6 (166 - 266)", "K6 (166 - 300)", "K6-2 (200 - 450)",
0140       "K6-3D-Plus (200 - 450)", NULL, NULL, NULL, NULL, NULL, NULL }},
0141 };
0142 
0143 static const char * AMDmodel(void)
0144 {
0145   const char *p=NULL;
0146   int i;
0147 
0148   if (x86_model < 16)
0149     for (i=0; i<sizeof(amd_models)/sizeof(struct cpu_model_info); i++)
0150       if (amd_models[i].x86 == x86) {
0151         p = amd_models[i].model_names[(int)x86_model];
0152         break;
0153       }
0154   return p;
0155 }
0156 
0157 static const char * getmodel(int x86, int model)
0158 {
0159   const char *p = NULL;
0160   static char nbuf[12];
0161 
0162   if (strncmp(x86_vendor_id, "Cyrix", 5) == 0)
0163     p = Cx86model();
0164   else if(strcmp(x86_vendor_id, "AuthenticAMD")==0)
0165     p = AMDmodel();
0166   else {
0167     switch (x86) {
0168       case 4:
0169         p = i486model(model);
0170         break;
0171       case 5:
0172         p = i586model(model);
0173         break;
0174       case 6:
0175         p = i686model(model);
0176         break;
0177     }
0178   }
0179   if (p)
0180     return p;
0181 
0182   sprintf(nbuf, "%d", model);
0183   return nbuf;
0184 }
0185 
0186 void printCpuInfo(void)
0187 {
0188   int i,j;
0189   static const char *x86_cap_flags[] = {
0190     "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
0191     "cx8", "apic", "10", "sep", "mtrr", "pge", "mca", "cmov",
0192     "pat", "pse36", "psn", "cflsh", "20", "ds", "acpi", "mmx",
0193     "fxsr", "sse", "sse2", "ss", "htt", "tm", "30", "pbe"
0194   };
0195   static const char *x86_cap_x_flags[] = {
0196     "sse3", "pclmulqdq", "dtes64", "monitor", "ds-cpl", "vmx", "smx", "est",
0197     "tm2", "ssse3", "cnxt-id", "11", "12", "cmpxchg16b", "xtpr", "pdcm",
0198     "16",  "pcid", "dca", "sse4.1", "sse4.2", "x2APIC", "movbe", "popcnt"
0199     "24",  "aesni", "xsave", "xsave", "avx", "29", "30", "31"
0200   };
0201 
0202   printk("cpu         : %c86\n", x86+'0');
0203   printk("model       : %s\n",
0204    have_cpuid ? getmodel(x86, x86_model) : "unknown");
0205   if (x86_vendor_id [0] == '\0')
0206     strcpy(x86_vendor_id, "unknown");
0207   printk("vendor_id   : %s\n", x86_vendor_id);
0208 
0209   if (x86_mask) {
0210     if (strncmp(x86_vendor_id, "Cyrix", 5) != 0) {
0211       printk("stepping    : %d\n", x86_mask);
0212     }
0213     else {       /* we have a Cyrix */
0214       printk("stepping    : %s\n", Cx86_type[Cx86_step]);
0215     }
0216   } else
0217     printk("stepping    : unknown\n");
0218 
0219   printk("fpu         : %s\n", (hard_math ? "yes" : "no"));
0220   printk("cpuid       : %s\n", (have_cpuid ? "yes" : "no"));
0221   printk("flags       :");
0222   for ( i = j = 0 ; i < 32 ; i++ ) {
0223     if ( x86_capability & (1 << i) ) {
0224       if ( j && 0 == (j & 7) )
0225     printk("\n             ");
0226       printk(" %s", x86_cap_flags[i]);
0227       j++;
0228     }
0229   }
0230   printk("\n");
0231   printk("flags (ext.):");
0232   for ( i = j = 0 ; i < 32 ; i++ ) {
0233     if ( x86_capability_x & (1 << i) ) {
0234       if ( j && 0 == (j & 7) )
0235     printk("\n             ");
0236       printk(" %s", x86_cap_x_flags[i]);
0237       j++;
0238     }
0239   }
0240   printk("\n");
0241   printk( "x86_capability_ebx=0x%08x\n", x86_capability_ebx);
0242   printk( "x86_capability_cores=0x%08x\n", x86_capability_cores);
0243 }