x86: detect FS/GS MSRs
[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 /* Check Intel's SDM 2a for Table 3-17 for the cpuid leaves */
22 void print_cpuinfo(void)
23 {
24         uint32_t eax, ebx, ecx, edx;
25         uint32_t model, family;
26         uint64_t msr_val;
27         char vendor_id[13];
28         extern char (SNT RO _start)[];
29
30         asm volatile ("cpuid;"
31                   "movl    %%ebx, (%2);"
32                   "movl    %%edx, 4(%2);"
33                   "movl    %%ecx, 8(%2);"
34                  : "=a"(eax)
35                  : "a"(0), "D"(vendor_id)
36                  : "%ebx", "%ecx", "%edx");
37
38         vendor_id[12] = '\0';
39         cprintf("Vendor ID: %s\n", vendor_id);
40         cprintf("Largest Standard Function Number Supported: %d\n", eax);
41         cpuid(0x80000000, 0x0, &eax, 0, 0, 0);
42         cprintf("Largest Extended Function Number Supported: 0x%08x\n", eax);
43         cpuid(1, 0x0, &eax, &ebx, &ecx, &edx);
44         family = ((eax & 0x0FF00000) >> 20) + ((eax & 0x00000F00) >> 8);
45         model = ((eax & 0x000F0000) >> 12) + ((eax & 0x000000F0) >> 4);
46         cprintf("Family: %d\n", family);
47         cprintf("Model: %d\n", model);
48         cprintf("Stepping: %d\n", eax & 0x0000000F);
49         // eventually can fill this out with SDM Vol3B App B info, or
50         // better yet with stepping info.  or cpuid 8000_000{2,3,4}
51         switch ( family << 8 | model ) {
52                 case(0x061a):
53                         cprintf("Processor: Core i7\n");
54                         break;
55                 case(0x060f):
56                         cprintf("Processor: Core 2 Duo or Similar\n");
57                         break;
58                 default:
59                         cprintf("Unknown or non-Intel CPU\n");
60         }
61         if (!(edx & 0x00000020))
62                 panic("MSRs not supported!");
63         if (!(edx & 0x00001000))
64                 panic("MTRRs not supported!");
65         if (!(edx & 0x00002000))
66                 panic("Global Pages not supported!");
67         if (!(edx & 0x00000200))
68                 panic("Local APIC Not Detected!");
69         if (ecx & 0x00200000)
70                 cprintf("x2APIC Detected\n");
71         else
72                 cprintf("x2APIC Not Detected\n");
73         if (ecx & 0x00000060) {
74                 msr_val = read_msr(IA32_FEATURE_CONTROL);
75                 printd("64 Bit Feature Control: 0x%08x\n", msr_val);
76                 if ((msr_val & 0x5) == 0x5)
77                         printk("Hardware virtualization supported\n");
78                 else
79                         printk("Hardware virtualization not supported\n");
80         } else { 
81                 printk("Hardware virtualization not supported\n");
82         }
83         /* FP and SSE Checks */
84         if (edx & 0x00000001)
85                 printk("FPU Detected\n");
86         else
87                 panic("FPU Not Detected!!\n");
88         printk("SSE support: ");
89         if (edx & (1 << 25))
90                 printk("sse ");
91         else
92                 panic("SSE Support Not Detected!!\n");
93         if (edx & (1 << 26))
94                 printk("sse2 ");
95         if (ecx & (1 << 0))
96                 printk("sse3 ");
97         if (ecx & (1 << 9))
98                 printk("ssse3 ");
99         if (ecx & (1 << 19))
100                 printk("sse4.1 ");
101         if (ecx & (1 << 20))
102                 printk("sse4.2 ");
103         if (edx & (1 << 23))
104                 printk("mmx ");
105         if ((edx & (1 << 25)) && (!(edx & (1 << 24))))
106                 panic("SSE support, but no FXSAVE!");
107         printk("\n");
108         cpuid(0x80000008, 0x0, &eax, &ebx, &ecx, &edx);
109         cprintf("Physical Address Bits: %d\n", eax & 0x000000FF);
110         cprintf("Cores per Die: %d\n", (ecx & 0x000000FF) + 1);
111     cprintf("This core's Default APIC ID: 0x%08x\n", lapic_get_default_id());
112         msr_val = read_msr(IA32_APIC_BASE);
113         if (msr_val & MSR_APIC_ENABLE)
114                 cprintf("Local APIC Enabled\n");
115         else
116                 cprintf("Local APIC Disabled\n");
117         if (msr_val & 0x00000100)
118                 cprintf("I am the Boot Strap Processor\n");
119         else
120                 cprintf("I am an Application Processor\n");
121         cpuid(0x80000007, 0x0, &eax, &ebx, &ecx, &edx);
122         if (edx & 0x00000100)
123                 printk("Invariant TSC present\n");
124         else
125                 printk("Invariant TSC not present\n");
126         cpuid(0x07, 0x0, &eax, &ebx, &ecx, &edx);
127         if (ebx & 0x00000001)
128                 printk("FS/GS Base RD/W supported\n");
129         else
130                 printk("FS/GS Base RD/W not supported\n");
131         cpuid(0x80000001, 0x0, &eax, &ebx, &ecx, &edx);
132         if (edx & (1 << 27))
133                 printk("RDTSCP supported\n");
134         else
135                 printk("RDTSCP not supported: don't trust detailed measurements\n");
136         printk("FS/GS MSRs %ssupported\n", edx & (1 << 29) ? "" : "not ");
137         msr_val = read_msr(IA32_MISC_ENABLE);
138         /* we want this to be not set for cpuid.6h to work. */
139         if (msr_val & (1 << 22))
140                 write_msr(IA32_MISC_ENABLE, msr_val & ~(1 << 22));
141         cpuid(0x00000006, 0x0, &eax, 0, 0, 0);
142         if (eax & (1 << 2))
143                 printk("Always running APIC detected\n");
144         else
145                 printk("Always running APIC *not* detected\n");
146 }
147
148 void show_mapping(uintptr_t start, size_t size)
149 {
150         pde_t LCKD(&vpd_lock) *CT(PTSIZE) pgdir =
151             (pde_t LCKD(&vpd_lock) *CT(PTSIZE))vpd;
152         pte_t *pte;
153         pte_t LCKD(&vpd_lock) *pde;
154         page_t *page;
155         uintptr_t i;
156
157         printk("   Virtual    Physical  Ps Dr Ac CD WT U W P\n");
158         printk("--------------------------------------------\n");
159         for(i = 0; i < size; i += PGSIZE, start += PGSIZE) {
160                 pte = pgdir_walk(pgdir, (void*)start, 0);
161                 printk("%08p  ", start);
162                 if (pte) {
163                         pde = &pgdir[PDX(start)];
164                         /* for a jumbo, pde = pte and PTE_PS (better be) = 1 */
165                         printk("%08p  %1d  %1d  %1d  %1d  %1d  %1d %1d %1d\n",
166                                PTE_ADDR(*pte), (*pte & PTE_PS) >> 7, (*pte & PTE_D) >> 6,
167                                (*pte & PTE_A) >> 5, (*pte & PTE_PCD) >> 4,
168                                (*pte & PTE_PWT) >> 3, (*pte & *pde & PTE_U) >> 2,
169                                (*pte & *pde & PTE_W) >> 1, (*pte & PTE_P));
170                 } else {
171                         printk("%08p\n", 0);
172                 }
173         }
174 }
175
176 /* Like backtrace, this is probably not the best place for this. */
177 void spinlock_debug(spinlock_t *lock)
178 {
179 #ifdef __CONFIG_SPINLOCK_DEBUG__
180         eipdebuginfo_t debuginfo;
181         char buf[256];
182         uint32_t eip = (uint32_t)lock->call_site;
183
184         if (!eip) {
185                 printk("Lock %p: never locked\n", lock);
186                 return;
187         }
188         debuginfo_eip(eip, &debuginfo);
189         memset(buf, 0, 256);
190         strncpy(buf, debuginfo.eip_fn_name, MIN(debuginfo.eip_fn_namelen, 256));
191         buf[MIN(debuginfo.eip_fn_namelen, 255)] = 0;
192         printk("Lock %p: last locked at [<%p>] in %s(%p) on core %d\n", lock, eip, buf,
193                debuginfo.eip_fn_addr, lock->calling_core);
194 #endif
195 }
196