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