9ns: mnt: Don't use a 'bogus' struct
[akaros.git] / kern / arch / x86 / cpuinfo.c
index b857ee2..0e16f75 100644 (file)
 #include <string.h>
 #include <cpu_feat.h>
 
+int x86_family, x86_model, x86_stepping;
+
 /* Check Intel's SDM 2a for Table 3-17 for the cpuid leaves */
 void print_cpuinfo(void)
 {
        uint32_t eax, ebx, ecx, edx;
-       uint32_t model, family;
+       uint32_t model, family, ext_model, ext_family;
        uint64_t msr_val;
        char vendor_id[13];
        int max_std_lvl, max_extd_lvl;
@@ -61,11 +63,20 @@ void print_cpuinfo(void)
        cprintf("Largest Extended Function Number Supported: 0x%08x\n", eax);
        max_extd_lvl = eax;
        cpuid(1, 0x0, &eax, &ebx, &ecx, &edx);
-       family = ((eax & 0x0FF00000) >> 20) + ((eax & 0x00000F00) >> 8);
-       model = ((eax & 0x000F0000) >> 12) + ((eax & 0x000000F0) >> 4);
-       cprintf("Family: %d\n", family);
-       cprintf("Model: %d\n", model);
-       cprintf("Stepping: %d\n", eax & 0x0000000F);
+       ext_family = (eax >> 20) & 0xff;
+       ext_model = (eax >> 16) & 0xf;
+       family = (eax >> 8) & 0xf;
+       model = (eax >> 4) & 0xf;
+       if ((family == 15) || (family == 6))
+               model += ext_model << 4;
+       if (family == 15)
+               family += ext_family;
+       x86_family = family;
+       x86_model = model;
+       x86_stepping = eax & 0xf;
+       printk("Family: %d\n", x86_family);
+       printk("Model: %d\n", x86_model);
+       printk("Stepping: %d\n", x86_stepping);
        // eventually can fill this out with SDM Vol3B App B info, or
        // better yet with stepping info.  or cpuid 8000_000{2,3,4}
        switch ( family << 8 | model ) {
@@ -91,7 +102,7 @@ void print_cpuinfo(void)
        if (ecx & 0x00200000)
                cprintf("x2APIC Detected\n");
        else
-               cprintf("x2APIC Not Detected\n");
+               panic("x2APIC Not Detected\n");
        /* Not sure how to detect AMD HW virt yet. */
        if ((ecx & 0x00000060) && cpu_has_feat(CPU_FEAT_X86_VENDOR_INTEL)) {
                msr_val = read_msr(IA32_FEATURE_CONTROL);
@@ -159,9 +170,8 @@ void print_cpuinfo(void)
        /* Regardless, make sure userspace can access rdtsc (and rdtscp) */
        lcr4(rcr4() & ~CR4_TSD);
        printk("1 GB Jumbo pages %ssupported\n", edx & (1 << 26) ? "" : "not ");
-       printk("FS/GS MSRs %ssupported\n", edx & (1 << 29) ? "" : "not ");
        if (!(edx & (1 << 29))) {
-               printk("Can't handle no FS/GS MSRs!\n");
+               printk("Not 64 bit, refusing to boot!\n");
                while (1)
                        asm volatile ("hlt");
        }
@@ -175,6 +185,8 @@ void print_cpuinfo(void)
        #define CPUID_FXSR_SUPPORT          (1 << 24)
        #define CPUID_XSAVE_SUPPORT         (1 << 26)
        #define CPUID_XSAVEOPT_SUPPORT      (1 << 0)
+       #define CPUID_MONITOR_MWAIT         (1 << 3)
+       #define CPUID_MWAIT_PWR_MGMT        (1 << 0)
 
        cpuid(0x01, 0x00, 0, 0, &ecx, &edx);
        if (CPUID_FXSR_SUPPORT & edx)
@@ -186,6 +198,12 @@ void print_cpuinfo(void)
        if (CPUID_XSAVEOPT_SUPPORT & eax)
                cpu_set_feat(CPU_FEAT_X86_XSAVEOPT);
 
+       cpuid(0x01, 0x00, 0, 0, &ecx, 0);
+       if (CPUID_MONITOR_MWAIT & ecx) {
+               cpuid(0x05, 0x00, 0, 0, &ecx, 0);
+               if (CPUID_MWAIT_PWR_MGMT & ecx)
+                       cpu_set_feat(CPU_FEAT_X86_MWAIT);
+       }
 }
 
 #define BIT_SPACING "        "
@@ -198,7 +216,7 @@ void show_mapping(pgdir_t pgdir, uintptr_t start, size_t size)
        page_t *page;
        uintptr_t i;
 
-       printk("   %sVirtual    %sPhysical  Ps Dr Ac CD WT U W P EPTE\n",
+       printk("   %sVirtual    %sPhysical  Ps Dr Ac CD WT U W P EPTE\n",
               BIT_SPACING, BIT_SPACING);
        printk("-------------------------------------------------%s\n", BIT_DASHES);
        for(i = 0; i < size; i += PGSIZE, start += PGSIZE) {
@@ -214,11 +232,12 @@ void show_mapping(pgdir_t pgdir, uintptr_t start, size_t size)
                         * UVPT mapping requires the U to see interior pages (but have W
                         * off). */
                        perm = get_va_perms(pgdir, (void*)start);
-                       printk("%p  %1d  %1d  %1d  %1d  %1d  %1d %1d %1d 0x%llx\n",
+                       printk("%p  %1d  %1d  %1d  %1d %1d  %1d  %1d %1d %1d 0x%llx\n",
                               pte_get_paddr(pte),
                               pte_is_jumbo(pte),
                               pte_is_dirty(pte),
                               pte_is_accessed(pte),
+                              (pte_print(pte) & PTE_G) / PTE_G,
                               (pte_print(pte) & __PTE_PCD) / __PTE_PCD,
                               (pte_print(pte) & __PTE_PWT) / __PTE_PWT,
                               (perm & PTE_U) / PTE_U,