proc_destroy() refcnting issues dealt with
[akaros.git] / kern / arch / i686 / cpuinfo.c
1 /*
2  * Copyright (c) 2009 The Regents of the University of California
3  * Barret Rhoden <brho@cs.berkeley.edu>
4  * See LICENSE for details.
5  */
6
7 #ifdef __SHARC__
8 #pragma nosharc
9 #endif
10
11 #include <arch/arch.h>
12 #include <arch/x86.h>
13 #include <arch/mmu.h>
14 #include <stdio.h>
15 #include <assert.h>
16 #include <ros/memlayout.h>
17 #include <pmap.h>
18 #include <kdebug.h>
19 #include <string.h>
20
21 void print_cpuinfo(void)
22 {
23         uint32_t eax, ebx, ecx, edx;
24         uint32_t model, family;
25         uint64_t msr_val;
26         char vendor_id[13];
27         extern char (SNT RO _start)[];
28
29         asm volatile ("cpuid;"
30                   "movl    %%ebx, (%2);"
31                   "movl    %%edx, 4(%2);"
32                   "movl    %%ecx, 8(%2);"
33                  : "=a"(eax)
34                  : "a"(0), "D"(vendor_id)
35                  : "%ebx", "%ecx", "%edx");
36
37         vendor_id[12] = '\0';
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 ) {
51                 case(0x061a):
52                         cprintf("Processor: Core i7\n");
53                         break;
54                 case(0x060f):
55                         cprintf("Processor: Core 2 Duo or Similar\n");
56                         break;
57                 default:
58                         cprintf("Unknown or non-Intel CPU\n");
59         }
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!");
68         if (ecx & 0x00200000)
69                 cprintf("x2APIC Detected\n");
70         else
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");
77                 else
78                         printk("Hardware virtualization not supported\n");
79         } else { 
80                 printk("Hardware virtualization not supported\n");
81         }
82         /* FP and SSE Checks */
83         if (edx & 0x00000001)
84                 printk("FPU Detected\n");
85         else
86                 panic("FPU Not Detected!!\n");
87         printk("SSE support: ");
88         if (edx & (1 << 25))
89                 printk("sse ");
90         else
91                 panic("SSE Support Not Detected!!\n");
92         if (edx & (1 << 26))
93                 printk("sse2 ");
94         if (ecx & (1 << 0))
95                 printk("sse3 ");
96         if (ecx & (1 << 9))
97                 printk("ssse3 ");
98         if (ecx & (1 << 19))
99                 printk("sse4.1 ");
100         if (ecx & (1 << 20))
101                 printk("sse4.2 ");
102         if (edx & (1 << 23))
103                 printk("mmx ");
104         if ((edx & (1 << 25)) && (!(edx & (1 << 24))))
105                 panic("SSE support, but no FXSAVE!");
106         printk("\n");
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");
114         else
115                 cprintf("Local APIC Disabled\n");
116         if (msr_val & 0x00000100)
117                 cprintf("I am the Boot Strap Processor\n");
118         else
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");
123         else
124                 printk("Invariant TSC not present\n");
125 }
126
127 void show_mapping(uintptr_t start, size_t size)
128 {
129         pde_t LCKD(&vpd_lock) *CT(PTSIZE) pgdir =
130             (pde_t LCKD(&vpd_lock) *CT(PTSIZE))vpd;
131         pte_t *pte;
132         pte_t LCKD(&vpd_lock) *pde;
133         page_t *page;
134         uintptr_t i;
135
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);
141                 if (page) {
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);
148                 } else
149                         cprintf("%08p\n", 0);
150         }
151 }
152
153 void backtrace(void)
154 { TRUSTEDBLOCK
155         extern char (SNT RO _start)[];
156         uint32_t *ebp, eip;
157         eipdebuginfo_t debuginfo;
158         char buf[256];
159         int j, i = 1;
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
169         while (ebp != 0) {
170                 debuginfo_eip(eip, &debuginfo);
171                 memset(buf, 0, 256);
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));
180                 cprintf("\n");
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))
185                         break;
186                 #endif /* __CONFIG_RESET_STACKS__ */
187         }
188 }
189
190 /* Like backtrace, this is probably not the best place for this. */
191 void spinlock_debug(spinlock_t *lock)
192 {
193 #ifdef __CONFIG_SPINLOCK_DEBUG__
194         eipdebuginfo_t debuginfo;
195         char buf[256];
196         uint32_t eip = (uint32_t)lock->call_site;
197
198         if (!eip) {
199                 printk("Lock %p: never locked\n", lock);
200                 return;
201         }
202         debuginfo_eip(eip, &debuginfo);
203         memset(buf, 0, 256);
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);
208 #endif
209 }
210