summaryrefslogblamecommitdiffstats
path: root/c/src/lib/libcpu/i386/displayCpu.c
blob: 716acec54c976d21ca3cb0a71e93cbd70f9dad85 (plain) (tree)
1
2
3
4
5
6
7
8
9




                                                                       



                                                                       
                                           
                                      


                                                           
                                         








                              
                        
                  

                            
 
                                  


                                          
 
                                             
 







                                                                   



                                              







                                                            

 
                                  
 



















































                                                       



                                              






                                        


                       

                        


                                             







                                                                      



                                  









                                                                      



                                                
























                                                   

 
                       
 
          

                                                          


                                                              
    
                                          



                                                                            
    

                                          
                              
                                                      

                                     
                                              
 
                 
                                                  
                                             
     
                                      
                                                         
     
        
                                      
 



                                                            
                                      
                              
                              
                                      
          

     
               

                                    
                                        
                              
                              
                                        
          


               

                                                                 
 
/*  displayCpu.c
 *
 *  This file contains code for displaying the Intel Cpu identification
 *  that has been performed by checkCPUtypeSetCr0 function.
 *
 *  This file was updated by Joel Sherrill <joel.sherrill@oarcorp.com>
 *  to define more capability bits, pick up more CPU model information,
 *  and add more model strings. --joel (April 2010)
 *
 *  COPYRIGHT (c) 1998 valette@crf.canon.fr
 *  COPYRIGHT (c) 2010 OAR Corporation
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.com/license/LICENSE.
 */

/*
 * Tell us the machine setup..
 */
#include <stdio.h>
#include <libcpu/cpu.h>
#include <string.h>
#include <libcpu/cpuModel.h>
#include <rtems/bspIo.h>
#include <rtems.h>

unsigned char Cx86_step = 0;

static const char *Cx86_type[] = {
  "unknown", "1.3", "1.4", "1.5", "1.6",
  "2.4", "2.5", "2.6", "2.7 or 3.7", "4.2"
  };

static const char *i486model(unsigned int nr)
{
  static const char *model[] = {
    "0","DX","SX","DX/2","4","SX/2","6","DX/2-WB","DX/4","DX/4-WB",
    "10","11","12","13","Am5x86-WT","Am5x86-WB"
  };

  if (nr < sizeof(model)/sizeof(char *))
    return model[nr];
  return NULL;
}

static const char * i586model(unsigned int nr)
{
  static const char *model[] = {
    "0", "Pentium 60/66","Pentium 75+","OverDrive PODP5V83",
    "Pentium MMX", NULL, NULL, "Mobile Pentium 75+",
    "Mobile Pentium MMX"
  };
  if (nr < sizeof(model)/sizeof(char *))
    return model[nr];
  return NULL;
}

static const char *Cx86model(void)
{
  unsigned char nr6x86 = 0;
  static const char *model[] = {
    "unknown", "6x86", "6x86L", "6x86MX", "MII"
  };

  switch (x86) {
    case 5:
      /* cx8 flag only on 6x86L */
      nr6x86 = ((x86_capability & (1 << 8)) ? 2 : 1);
      break;
    case 6:
      nr6x86 = 3;
      break;
    default:
      nr6x86 = 0;
  }

  /* We must get the stepping number by reading DIR1 */
  outport_byte(0x22,0xff);
  inport_byte(0x23, x86_mask);
  switch (x86_mask) {
    case 0x03:
      Cx86_step =  1;  /* 6x86MX Rev 1.3 */
      break;
    case 0x04:
      Cx86_step =  2;  /* 6x86MX Rev 1.4 */
      break;
    case 0x05:
      Cx86_step =  3;  /* 6x86MX Rev 1.5 */
      break;
    case 0x06:
      Cx86_step =  4;  /* 6x86MX Rev 1.6 */
      break;
    case 0x14:
      Cx86_step =  5;  /* 6x86 Rev 2.4 */
      break;
    case 0x15:
      Cx86_step =  6;  /* 6x86 Rev 2.5 */
      break;
    case 0x16:
      Cx86_step =  7;  /* 6x86 Rev 2.6 */
      break;
    case 0x17:
      Cx86_step =  8;  /* 6x86 Rev 2.7 or 3.7 */
      break;
    case 0x22:
      Cx86_step =  9;  /* 6x86L Rev 4.2 */
      break;
    default:
      Cx86_step = 0;
  }
  return model[nr6x86];
}

static const char * i686model(unsigned int nr)
{
  static const char *model[] = {
    "PPro A-step",
    "Pentium Pro"
  };
  if (nr < sizeof(model)/sizeof(char *))
    return model[nr];
  return NULL;
}

struct cpu_model_info {
  int x86;
  char *model_names[16];
};

static struct cpu_model_info amd_models[] = {
  { 4,
    { NULL, NULL, NULL, "DX/2", NULL, NULL, NULL, "DX/2-WB", "DX/4",
      "DX/4-WB", NULL, NULL, NULL, NULL, "Am5x86-WT", "Am5x86-WB" }},
  { 5,
    { "K5/SSA5 (PR-75, PR-90, PR-100)", "K5 (PR-120, PR-133)",
      "K5 (PR-166)", "K5 (PR-200)", NULL, NULL,
      "K6 (166 - 266)", "K6 (166 - 300)", "K6-2 (200 - 450)",
      "K6-3D-Plus (200 - 450)", NULL, NULL, NULL, NULL, NULL, NULL }},
};

static const char * AMDmodel(void)
{
  const char *p=NULL;
  int i;

  if (x86_model < 16)
    for (i=0; i<sizeof(amd_models)/sizeof(struct cpu_model_info); i++)
      if (amd_models[i].x86 == x86) {
        p = amd_models[i].model_names[(int)x86_model];
        break;
      }
  return p;
}

static const char * getmodel(int x86, int model)
{
  const char *p = NULL;
  static char nbuf[12];

  if (strncmp(x86_vendor_id, "Cyrix", 5) == 0)
    p = Cx86model();
  else if(strcmp(x86_vendor_id, "AuthenticAMD")==0)
    p = AMDmodel();
  else {
    switch (x86) {
      case 4:
        p = i486model(model);
        break;
      case 5:
        p = i586model(model);
        break;
      case 6:
        p = i686model(model);
        break;
    }
  }
  if (p)
    return p;

  sprintf(nbuf, "%d", model);
  return nbuf;
}

void printCpuInfo(void)
{
  int i,j;
  static const char *x86_cap_flags[] = {
    "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
    "cx8", "apic", "10", "sep", "mtrr", "pge", "mca", "cmov",
    "pat", "pse36", "psn", "cflsh", "20", "ds", "acpi", "mmx",
    "fxsr", "sse", "sse2", "ss", "htt", "tm", "30", "pbe"
  };
  static const char *x86_cap_x_flags[] = {
    "sse3", "pclmulqdq", "dtes64", "monitor", "ds-cpl", "vmx", "smx", "est",
    "tm2", "ssse3", "cnxt-id", "11", "12", "cmpxchg16b", "xtpr", "pdcm",
    "16",  "pcid", "dca", "sse4.1", "sse4.2", "x2APIC", "movbe", "popcnt"
    "24",  "aesni", "xsave", "xsave", "avx", "29", "30", "31"
  };

  printk("cpu         : %c86\n", x86+'0');
  printk("model       : %s\n",
   have_cpuid ? getmodel(x86, x86_model) : "unknown");
  if (x86_vendor_id [0] == '\0')
    strcpy(x86_vendor_id, "unknown");
  printk("vendor_id   : %s\n", x86_vendor_id);

  if (x86_mask) {
    if (strncmp(x86_vendor_id, "Cyrix", 5) != 0) {
      printk("stepping    : %d\n", x86_mask);
    }
    else {       /* we have a Cyrix */
      printk("stepping    : %s\n", Cx86_type[Cx86_step]);
    }
  } else
    printk("stepping    : unknown\n");

  printk("fpu         : %s\n", (hard_math ? "yes" : "no"));
  printk("cpuid       : %s\n", (have_cpuid ? "yes" : "no"));
  printk("flags       :");
  for ( i = j = 0 ; i < 32 ; i++ ) {
    if ( x86_capability & (1 << i) ) {
      if ( j && 0 == (j & 7) )
    printk("\n             ");
      printk(" %s", x86_cap_flags[i]);
      j++;
    }
  }
  printk("\n");
  printk("flags (ext.):");
  for ( i = j = 0 ; i < 32 ; i++ ) {
    if ( x86_capability_x & (1 << i) ) {
      if ( j && 0 == (j & 7) )
    printk("\n             ");
      printk(" %s", x86_cap_x_flags[i]);
      j++;
    }
  }
  printk("\n");
  printk( "x86_capability_ebx=0x%08x\n", x86_capability_ebx);
  printk( "x86_capability_cores=0x%08x\n", x86_capability_cores);
}