This, ladies and gentlement, is commit #4000.
[coreboot.git] / src / drivers / generic / debug / debug_dev.c
index 712a7e30823eb4e88a5e3ac2206a9d2614e5ffa1..210600c59fac6069748daeccf01014f57a883579 100644 (file)
@@ -1,8 +1,12 @@
 #include <console/console.h>
 #include <device/device.h>
+#include <device/smbus.h>
 #include <device/pci.h>
 #include <device/pci_ids.h>
 #include <device/pci_ops.h>
+#include <cpu/x86/msr.h>
+#include <part/hard_reset.h>
+#include <delay.h>
 #include "chip.h"
 
 static void print_pci_regs(struct device *dev)
@@ -11,61 +15,124 @@ static void print_pci_regs(struct device *dev)
       int i;
 
       for(i=0;i<256;i++) {
-            byte = pci_read_config8(dev, i);
+             byte = pci_read_config8(dev, i);
    
-             if((i & 0xf)==0) printk_debug("\n%02x:",i);
-             printk_debug(" %02x",byte);
+             if((i & 0xf)==0) printk_debug("\n%02x:",i);
+             printk_debug(" %02x",byte);
       }
       printk_debug("\n");
-
 }
+
 static void print_mem(void)
 {
         unsigned int i;
        unsigned int start = 0xfffff000;
        for(i=start;i<0xffffffff;i++) {
              if((i & 0xf)==0) printk_debug("\n %08x:",i);
-             printk_debug(" %02x ",(unsigned char)*((unsigned char *)i));
+             printk_debug(" %02x",(unsigned char)*((unsigned char *)i));
              }
-       printk_debug(" %02x \n",(unsigned char)*((unsigned char *)i));
+       printk_debug(" %02x\n",(unsigned char)*((unsigned char *)i));
 
  }
 static void print_pci_regs_all(void)
 {
         struct device *dev;
-       unsigned char i,j,k;
+       unsigned bus, device, function;
 
-       for(i=0;i<=15;i++) {
-               for(j=0;j<=0x1f;j++) {
-                       for (k=0;k<=6;k++){
-                               dev = dev_find_slot(i, PCI_DEVFN(j, k));
+       for(bus=0; bus<256; bus++) {
+               for(device=0; device<=0x1f; device++) {
+                       for (function=0; function<=7; function++){
+                               unsigned devfn;
+                               devfn = PCI_DEVFN(device, function);
+                               dev = dev_find_slot(bus, devfn);
                                if(!dev) {
                                        continue;
                                }
                                if(!dev->enabled) {
                                        continue;
                                }
-                               printk_debug("\n%02x:%02x:%02x aka %s",i,j,k, dev_path(dev));
+                               printk_debug("\n%02x:%02x:%02x aka %s", 
+                                       bus, device, function, dev_path(dev));
                                print_pci_regs(dev);
                        }
                }
        }
-
 }
-static void debug_init(device_t dev)
+
+static void print_cpuid()
 {
-        unsigned bus;
-        unsigned devfn;
+       msr_t msr;
+       unsigned index;
+       unsigned eax, ebx, ecx, edx;
+       index = 0x80000007;
+       printk_debug("calling cpuid 0x%08x\n", index);
+       asm volatile(
+               "cpuid"
+               : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
+               : "a" (index)
+               );
+       printk_debug("cpuid[%08x]: %08x %08x %08x %08x\n",
+               index, eax, ebx, ecx, edx);
+       if (edx & (3 << 1)) {
+               index = 0xC0010042;
+               printk_debug("Reading msr: 0x%08x\n", index);
+               msr = rdmsr(index);
+               printk_debug("msr[0x%08x]: 0x%08x%08x\n",
+                       index, msr.hi, msr.lo);
+       }
 
-//     print_pci_regs_all();
+}
+static void print_smbus_regs(struct device *dev)
+{               
+       int j;
+       printk_debug("smbus: %s[%d]->", dev_path(dev->bus->dev), dev->bus->link);
+       printk_debug("%s", dev_path(dev));
+       for(j = 0; j < 256; j++) {
+               int status;
+               unsigned char byte;
+               status = smbus_read_byte(dev, j);
+               if (status < 0) {
+               //      printk_debug("bad device status= %08x\r\n", status);
+                       break;
+               }
+                if ((j & 0xf) == 0) {
+                        printk_debug("\r\n%02x: ", j);
+                }  
+               byte = status & 0xff;
+               printk_debug("%02x ", byte);
+       }
+       printk_debug("\r\n");
+}
 
-       print_mem();
-#if 0
+static void print_smbus_regs_all(struct device *dev)
+{
+       struct device *child;
+       int i;
+       if (dev->enabled && dev->path.type == DEVICE_PATH_I2C)
+       {
+               // Here don't need to call smbus_set_link, because we scan it from top to down
+               if( dev->bus->dev->path.type == DEVICE_PATH_I2C) { // it's under i2c MUX so set mux at first
+                       if(ops_smbus_bus(get_pbus_smbus(dev->bus->dev))) {
+                               if(dev->bus->dev->ops && dev->bus->dev->ops->set_link) 
+                                       dev->bus->dev->ops->set_link(dev->bus->dev, dev->bus->link);
+                       }
+               }
+               
+               if(ops_smbus_bus(get_pbus_smbus(dev))) print_smbus_regs(dev);   
+       }
+
+       for(i=0; i< dev->links; i++) {
+               for (child = dev->link[i].children; child; child = child->sibling) {
+                       print_smbus_regs_all(child);
+               }
+       }
+}
+static void print_msr_dualcore(void)
+{
         msr_t msr;
         unsigned index;
         unsigned eax, ebx, ecx, edx;
-        index = 0x80000007;
+        index = 0x80000008;
         printk_debug("calling cpuid 0x%08x\n", index);
         asm volatile(
                 "cpuid"
@@ -74,14 +141,139 @@ static void debug_init(device_t dev)
                 );
         printk_debug("cpuid[%08x]: %08x %08x %08x %08x\n",
                 index, eax, ebx, ecx, edx);
-        if (edx & (3 << 1)) {
-                index = 0xC0010042;
-                printk_debug("Reading msr: 0x%08x\n", index);
-                msr = rdmsr(index);
-                printk_debug("msr[0x%08x]: 0x%08x%08x\n",
-                        index, msr.hi, msr.hi);
+
+        printk_debug("core number %d\n", ecx & 0xff);   
+
+        index = 0xc001001f;
+        printk_debug("Reading msr: 0x%08x\n", index);
+        msr = rdmsr(index);
+        printk_debug("msr[0x%08x]: 0x%08x%08x bit 54 is %d\n",
+                index, msr.hi, msr.lo, (msr.hi>> (54-32)) & 1);
+#if 0
+        msr.hi |= (1<<(54-32));
+        wrmsr(index, msr);
+
+        msr = rdmsr(index);
+        printk_debug("msr[0x%08x]: 0x%08x%08x\n",
+                index, msr.hi, msr.lo);
+#endif
+
+}
+
+static void print_cache_size(void)
+{
+       unsigned index;
+       unsigned int n, eax, ebx, ecx, edx;
+
+        index = 0x80000000;
+        printk_debug("calling cpuid 0x%08x\n", index);
+        asm volatile(
+                "cpuid"
+                : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
+                : "a" (index)
+                );
+        n = eax;
+
+        if (n >= 0x80000005) {
+               index = 0x80000005;
+               printk_debug("calling cpuid 0x%08x\n", index);
+               asm volatile(
+                       "cpuid"
+                       : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
+                       : "a" (index)
+                       );
+                printk_debug("CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n",
+                        edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
+        }
+
+        if (n >= 0x80000006) {
+                index = 0x80000006;
+                printk_debug("calling cpuid 0x%08x\n", index);
+                asm volatile(
+                        "cpuid"
+                        : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
+                        : "a" (index)
+                        );
+               printk_debug("CPU: L2 Cache: %dK (%d bytes/line)\n",
+                       ecx >> 16, ecx & 0xFF);
         }
+
+}
+
+struct tsc_struct {
+        unsigned lo;
+        unsigned hi;
+};
+typedef struct tsc_struct tsc_t;
+
+static tsc_t rdtsc(void)
+{
+        tsc_t res;
+        asm volatile(
+                "rdtsc"
+                : "=a" (res.lo), "=d"(res.hi) /* outputs */
+                );
+        return res;
+}
+
+static void print_tsc(void) {
+       
+       tsc_t tsc;
+       tsc = rdtsc();
+        printk_debug("tsc: 0x%08x%08x\n",
+                     tsc.hi, tsc.lo);
+       udelay(1);
+        tsc = rdtsc();
+        printk_debug("tsc: 0x%08x%08x after udelay(1) \n",
+                     tsc.hi, tsc.lo);
+
+}
+
+static void debug_init(device_t dev)
+{
+#if CONFIG_CHIP_NAME
+       device_t parent;
 #endif
+       if (!dev->enabled)
+               return;
+       switch(dev->path.pnp.device) {
+#if CONFIG_CHIP_NAME
+       case 0:
+               parent = dev->bus->dev;
+               printk_debug("DEBUG: %s", dev_path(parent));
+               if(parent->chip_ops && parent->chip_ops->name) {
+                       printk_debug(": %s\n", parent->chip_ops->name);
+               } else {
+                       printk_debug("\n");
+               }
+               break;
+#endif
+               
+       case 1:
+               print_pci_regs_all();
+               break;
+       case 2: 
+               print_mem();
+               break;
+       case 3:
+               print_cpuid();
+               break;
+       case 4: 
+               print_smbus_regs_all(&dev_root);
+               break;
+        case 5: 
+                print_msr_dualcore();
+                break;
+       case 6: 
+               print_cache_size();
+               break;
+       case 7:
+               print_tsc();
+               break;
+       case 8: 
+               hard_reset();
+               break;
+       }
 }
 
 static void debug_noop(device_t dummy)