7f17c9598c45bcbd6e511530336eff3406c76228
[coreboot.git] / src / drivers / generic / debug / debug_dev.c
1 #include <console/console.h>
2 #include <device/device.h>
3 #include <device/smbus.h>
4 #include <device/pci.h>
5 #include <device/pci_ids.h>
6 #include <device/pci_ops.h>
7 #include <cpu/x86/msr.h>
8 #include "chip.h"
9
10 static void print_pci_regs(struct device *dev)
11 {
12       uint8_t byte;
13       int i;
14
15       for(i=0;i<256;i++) {
16               byte = pci_read_config8(dev, i);
17    
18               if((i & 0xf)==0) printk_debug("\n%02x:",i);
19               printk_debug(" %02x",byte);
20       }
21       printk_debug("\n");
22 }
23
24 static void print_mem(void)
25 {
26         unsigned int i;
27         unsigned int start = 0xfffff000;
28         for(i=start;i<0xffffffff;i++) {
29              if((i & 0xf)==0) printk_debug("\n %08x:",i);
30              printk_debug(" %02x",(unsigned char)*((unsigned char *)i));
31              }
32         printk_debug(" %02x\n",(unsigned char)*((unsigned char *)i));
33
34  }
35 static void print_pci_regs_all(void)
36 {
37         struct device *dev;
38         unsigned bus, device, function;
39
40         for(bus=0; bus<256; bus++) {
41                 for(device=0; device<=0x1f; device++) {
42                         for (function=0; function<=7; function++){
43                                 unsigned devfn;
44                                 devfn = PCI_DEVFN(device, function);
45                                 dev = dev_find_slot(bus, devfn);
46                                 if(!dev) {
47                                         continue;
48                                 }
49                                 if(!dev->enabled) {
50                                         continue;
51                                 }
52                                 printk_debug("\n%02x:%02x:%02x aka %s", 
53                                         bus, device, function, dev_path(dev));
54                                 print_pci_regs(dev);
55                         }
56                 }
57         }
58 }
59
60 static void print_cpuid()
61 {
62         msr_t msr;
63         unsigned index;
64         unsigned eax, ebx, ecx, edx;
65         index = 0x80000007;
66         printk_debug("calling cpuid 0x%08x\n", index);
67         asm volatile(
68                 "cpuid"
69                 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
70                 : "a" (index)
71                 );
72         printk_debug("cpuid[%08x]: %08x %08x %08x %08x\n",
73                 index, eax, ebx, ecx, edx);
74         if (edx & (3 << 1)) {
75                 index = 0xC0010042;
76                 printk_debug("Reading msr: 0x%08x\n", index);
77                 msr = rdmsr(index);
78                 printk_debug("msr[0x%08x]: 0x%08x%08x\n",
79                         index, msr.hi, msr.lo);
80         }
81
82 }
83 static void print_smbus_regs(struct device *dev)
84 {               
85         int j;
86         printk_debug("smbus: %s[%d]->", dev_path(dev->bus->dev), dev->bus->link);
87         printk_debug("%s", dev_path(dev));
88         for(j = 0; j < 256; j++) {
89                 int status;
90                 unsigned char byte;
91                 status = smbus_read_byte(dev, j);
92                 if (status < 0) {
93                 //      printk_debug("bad device status= %08x\r\n", status);
94                         break;
95                 }
96                 if ((j & 0xf) == 0) {
97                         printk_debug("\r\n%02x: ", j);
98                 }  
99                 byte = status & 0xff;
100                 printk_debug("%02x ", byte);
101         }
102         printk_debug("\r\n");
103 }
104
105 static void print_smbus_regs_all(struct device *dev)
106 {
107         struct device *child;
108         int i;
109         if (dev->enabled && dev->path.type == DEVICE_PATH_I2C)
110         {
111                 // Here don't need to call smbus_set_link, because we scan it from top to down
112                 if( dev->bus->dev->path.type == DEVICE_PATH_I2C) { // it's under i2c MUX so set mux at first
113                         if(ops_smbus_bus(get_pbus_smbus(dev->bus->dev))) {
114                                 if(dev->bus->dev->ops && dev->bus->dev->ops->set_link) 
115                                         dev->bus->dev->ops->set_link(dev->bus->dev, dev->bus->link);
116                         }
117                 }
118                 
119                 if(ops_smbus_bus(get_pbus_smbus(dev))) print_smbus_regs(dev);   
120         }
121
122         for(i=0; i< dev->links; i++) {
123                 for (child = dev->link[i].children; child; child = child->sibling) {
124                         print_smbus_regs_all(child);
125                 }
126         }
127 }
128 static void print_msr_dualcore(void)
129 {
130         msr_t msr;
131         unsigned index;
132         unsigned eax, ebx, ecx, edx;
133         index = 0x80000008;
134         printk_debug("calling cpuid 0x%08x\n", index);
135         asm volatile(
136                 "cpuid"
137                 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
138                 : "a" (index)
139                 );
140         printk_debug("cpuid[%08x]: %08x %08x %08x %08x\n",
141                 index, eax, ebx, ecx, edx);
142
143         printk_debug("core number %d\n", ecx & 0xff);   
144
145         index = 0xc001001f;
146         printk_debug("Reading msr: 0x%08x\n", index);
147         msr = rdmsr(index);
148         printk_debug("msr[0x%08x]: 0x%08x%08x bit 54 is %d\n",
149                 index, msr.hi, msr.lo, (msr.hi>> (54-32)) & 1);
150 #if 0
151         msr.hi |= (1<<(54-32));
152         wrmsr(index, msr);
153
154         msr = rdmsr(index);
155         printk_debug("msr[0x%08x]: 0x%08x%08x\n",
156                 index, msr.hi, msr.lo);
157 #endif
158
159 }
160
161 static void print_cache_size(void)
162 {
163         unsigned index;
164         unsigned int n, eax, ebx, ecx, edx;
165
166         index = 0x80000000;
167         printk_debug("calling cpuid 0x%08x\n", index);
168         asm volatile(
169                 "cpuid"
170                 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
171                 : "a" (index)
172                 );
173         n = eax;
174
175         if (n >= 0x80000005) {
176                 index = 0x80000005;
177                 printk_debug("calling cpuid 0x%08x\n", index);
178                 asm volatile(
179                         "cpuid"
180                         : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
181                         : "a" (index)
182                         );
183                 printk_debug("CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n",
184                         edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
185         }
186
187         if (n >= 0x80000006) {
188                 index = 0x80000006;
189                 printk_debug("calling cpuid 0x%08x\n", index);
190                 asm volatile(
191                         "cpuid"
192                         : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
193                         : "a" (index)
194                         );
195                 printk_debug("CPU: L2 Cache: %dK (%d bytes/line)\n",
196                         ecx >> 16, ecx & 0xFF);
197         }
198
199 }
200
201 struct tsc_struct {
202         unsigned lo;
203         unsigned hi;
204 };
205 typedef struct tsc_struct tsc_t;
206
207 static tsc_t rdtsc(void)
208 {
209         tsc_t res;
210         asm volatile(
211                 "rdtsc"
212                 : "=a" (res.lo), "=d"(res.hi) /* outputs */
213                 );
214         return res;
215 }
216
217 static void print_tsc(void) {
218         
219         tsc_t tsc;
220         tsc = rdtsc();
221         printk_debug("tsc: 0x%08x%08x\n",
222                      tsc.hi, tsc.lo);
223         udelay(1);
224         tsc = rdtsc();
225         printk_debug("tsc: 0x%08x%08x after udelay(1) \n",
226                      tsc.hi, tsc.lo);
227
228 }
229
230 static void debug_init(device_t dev)
231 {
232 #if CONFIG_CHIP_NAME
233         device_t parent;
234 #endif
235         if (!dev->enabled)
236                 return;
237         switch(dev->path.pnp.device) {
238 #if CONFIG_CHIP_NAME
239         case 0:
240                 parent = dev->bus->dev;
241                 printk_debug("DEBUG: %s", dev_path(parent));
242                 if(parent->chip_ops && parent->chip_ops->name) {
243                         printk_debug(": %s\n", parent->chip_ops->name);
244                 } else {
245                         printk_debug("\n");
246                 }
247                 break;
248 #endif
249                 
250         case 1:
251                 print_pci_regs_all();
252                 break;
253         case 2: 
254                 print_mem();
255                 break;
256         case 3:
257                 print_cpuid();
258                 break;
259         case 4: 
260                 print_smbus_regs_all(&dev_root);
261                 break;
262         case 5: 
263                 print_msr_dualcore();
264                 break;
265         case 6: 
266                 print_cache_size();
267                 break;
268         case 7:
269                 print_tsc();
270                 break;
271         case 8: 
272                 hard_reset();
273                 break;
274         }
275 }
276
277 static void debug_noop(device_t dummy)
278 {
279 }
280
281 static struct device_operations debug_operations = {
282         .read_resources   = debug_noop,
283         .set_resources    = debug_noop,
284         .enable_resources = debug_noop,
285         .init             = debug_init,
286 };
287
288 static void enable_dev(struct device *dev)
289 {
290         dev->ops = &debug_operations;
291 }
292
293 struct chip_operations drivers_generic_debug_ops = {
294         CHIP_NAME("Debug device")
295         .enable_dev = enable_dev, 
296 };