2 * Copyright (c) 2009 The Regents of the University of California
3 * Barret Rhoden <brho@cs.berkeley.edu>
4 * See LICENSE for details.
11 #include <arch/arch.h>
16 #include <ros/memlayout.h>
21 void print_cpuinfo(void)
23 uint32_t eax, ebx, ecx, edx;
24 uint32_t model, family;
27 extern char (SNT RO _start)[];
29 asm volatile ("cpuid;"
34 : "a"(0), "D"(vendor_id)
35 : "%ebx", "%ecx", "%edx");
38 cprintf("Vendor ID: %s\n", vendor_id);
39 cprintf("Largest Standard Function Number Supported: %d\n", eax);
40 cpuid(0x80000000, &eax, 0, 0, 0);
41 cprintf("Largest Extended Function Number Supported: 0x%08x\n", eax);
42 cpuid(1, &eax, &ebx, &ecx, &edx);
43 family = ((eax & 0x0FF00000) >> 20) + ((eax & 0x00000F00) >> 8);
44 model = ((eax & 0x000F0000) >> 12) + ((eax & 0x000000F0) >> 4);
45 cprintf("Family: %d\n", family);
46 cprintf("Model: %d\n", model);
47 cprintf("Stepping: %d\n", eax & 0x0000000F);
48 // eventually can fill this out with SDM Vol3B App B info, or
49 // better yet with stepping info. or cpuid 8000_000{2,3,4}
50 switch ( family << 8 | model ) {
52 cprintf("Processor: Core i7\n");
55 cprintf("Processor: Core 2 Duo or Similar\n");
58 cprintf("Unknown or non-Intel CPU\n");
60 if (!(edx & 0x00000020))
61 panic("MSRs not supported!");
62 if (!(edx & 0x00001000))
63 panic("MTRRs not supported!");
64 if (!(edx & 0x00002000))
65 panic("Global Pages not supported!");
66 if (!(edx & 0x00000200))
67 panic("Local APIC Not Detected!");
69 cprintf("x2APIC Detected\n");
71 cprintf("x2APIC Not Detected\n");
72 if (ecx & 0x00000060) {
73 msr_val = read_msr(IA32_FEATURE_CONTROL);
74 printd("64 Bit Feature Control: 0x%08x\n", msr_val);
75 if ((msr_val & 0x5) == 0x5)
76 printk("Hardware virtualization supported\n");
78 printk("Hardware virtualization not supported\n");
80 printk("Hardware virtualization not supported\n");
82 /* FP and SSE Checks */
84 printk("FPU Detected\n");
86 panic("FPU Not Detected!!\n");
87 printk("SSE support: ");
91 panic("SSE Support Not Detected!!\n");
104 if ((edx & (1 << 25)) && (!(edx & (1 << 24))))
105 panic("SSE support, but no FXSAVE!");
107 cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
108 cprintf("Physical Address Bits: %d\n", eax & 0x000000FF);
109 cprintf("Cores per Die: %d\n", (ecx & 0x000000FF) + 1);
110 cprintf("This core's Default APIC ID: 0x%08x\n", lapic_get_default_id());
111 msr_val = read_msr(IA32_APIC_BASE);
112 if (msr_val & MSR_APIC_ENABLE)
113 cprintf("Local APIC Enabled\n");
115 cprintf("Local APIC Disabled\n");
116 if (msr_val & 0x00000100)
117 cprintf("I am the Boot Strap Processor\n");
119 cprintf("I am an Application Processor\n");
120 cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
121 if (edx & 0x00000100)
122 printk("Invariant TSC present\n");
124 printk("Invariant TSC not present\n");
127 void show_mapping(uintptr_t start, size_t size)
129 pde_t LCKD(&vpd_lock) *CT(PTSIZE) pgdir =
130 (pde_t LCKD(&vpd_lock) *CT(PTSIZE))vpd;
132 pte_t LCKD(&vpd_lock) *pde;
136 cprintf(" Virtual Physical Ps Dr Ac CD WT U W\n");
137 cprintf("------------------------------------------\n");
138 for(i = 0; i < size; i += PGSIZE, start += PGSIZE) {
139 page = page_lookup(pgdir, (void*SNT)start, &pte);
140 cprintf("%08p ", start);
142 pde = &pgdir[PDX(start)];
143 // for a jumbo, pde = pte and PTE_PS (better be) = 1
144 cprintf("%08p %1d %1d %1d %1d %1d %1d %1d\n", page2pa(page),
145 (*pte & PTE_PS) >> 7, (*pte & PTE_D) >> 6, (*pte & PTE_A) >> 5,
146 (*pte & PTE_PCD) >> 4, (*pte & PTE_PWT) >> 3,
147 (*pte & *pde & PTE_U) >> 2, (*pte & *pde & PTE_W) >> 1);
149 cprintf("%08p\n", 0);
155 extern char (SNT RO _start)[];
157 eipdebuginfo_t debuginfo;
160 ebp = (uint32_t*)read_ebp();
161 // this is part of the way back into the call() instruction's bytes
162 // eagle-eyed readers should be able to explain why this is good enough,
163 // and retaddr (just *(ebp + 1) is not)
164 eip = *(ebp + 1) - 1;
165 // jump back a frame (out of backtrace)
166 ebp = (uint32_t*)(*ebp);
167 printk("Stack Backtrace on Core %d:\n", core_id());
168 // on each iteration, ebp holds the stack frame and eip an addr in that func
170 debuginfo_eip(eip, &debuginfo);
172 strncpy(buf, debuginfo.eip_fn_name, MIN(debuginfo.eip_fn_namelen, 256));
173 buf[MIN(debuginfo.eip_fn_namelen, 255)] = 0;
174 cprintf("#%02d [<%p>] in %s+%x(%p) from %s:%d\n", i++, eip, buf,
175 debuginfo.eip_fn_addr - (uint32_t)_start, debuginfo.eip_fn_addr,
176 debuginfo.eip_file, debuginfo.eip_line);
177 cprintf(" ebp: %x Args:", ebp);
178 for (j = 0; j < MIN(debuginfo.eip_fn_narg, 5); j++)
179 cprintf(" %08x", *(ebp + 2 + j));
181 eip = *(ebp + 1) - 1;
182 ebp = (uint32_t*)(*ebp);
183 #ifdef __CONFIG_RESET_STACKS__
184 if (!strncmp("__smp_idle", debuginfo.eip_fn_name, 10))
186 #endif /* __CONFIG_RESET_STACKS__ */
190 /* Like backtrace, this is probably not the best place for this. */
191 void spinlock_debug(spinlock_t *lock)
193 #ifdef __CONFIG_SPINLOCK_DEBUG__
194 eipdebuginfo_t debuginfo;
196 uint32_t eip = (uint32_t)lock->call_site;
199 printk("Lock %p: never locked\n", lock);
202 debuginfo_eip(eip, &debuginfo);
204 strncpy(buf, debuginfo.eip_fn_name, MIN(debuginfo.eip_fn_namelen, 256));
205 buf[MIN(debuginfo.eip_fn_namelen, 255)] = 0;
206 printk("Lock %p: last locked at [<%p>] in %s(%p) on core %d\n", lock, eip, buf,
207 debuginfo.eip_fn_addr, lock->calling_core);