bool svm_available (void) { u32 a, b, c, d; u64 tmp; asm_cpuid (CPUID_EXT_0, 0, &a, &b, &c, &d); if (a < CPUID_EXT_1) { printf ("SVM is not available.\n"); return false; } asm_cpuid (CPUID_EXT_1, 0, &a, &b, &c, &d); if (!(c & CPUID_EXT_1_ECX_SVM_BIT)) { printf ("SVM is not available.\n"); return false; } asm_rdmsr64 (MSR_AMD_VM_CR, &tmp); if (!(tmp & MSR_AMD_VM_CR_SVMDIS_BIT)) return true; /* SVM is allowed */ asm_cpuid (CPUID_EXT_0, 0, &a, &b, &c, &d); if (a < CPUID_EXT_A) { printf ("SVM is disabled.\n"); return false; } asm_cpuid (CPUID_EXT_A, 0, &a, &b, &c, &d); if (!(d & CPUID_EXT_A_EDX_SVM_LOCK_BIT)) { printf ("SVM is disabled at BIOS.\n"); return false; } else { printf ("SVM is disabled with a key.\n"); return false; } }
static void time_init_pcpu (void) { u32 a, b, c, d; u32 tsc1_l, tsc1_h; u32 tsc2_l, tsc2_h; u64 tsc1, tsc2, count; asm_cpuid (1, 0, &a, &b, &c, &d); if (!(d & CPUID_1_EDX_TSC_BIT)) panic ("Processor %d does not support TSC", currentcpu->cpunum); sync_all_processors (); asm_rdtsc (&tsc1_l, &tsc1_h); if (currentcpu->cpunum == 0) usleep (1000000); sync_all_processors (); asm_rdtsc (&tsc2_l, &tsc2_h); conv32to64 (tsc1_l, tsc1_h, &tsc1); conv32to64 (tsc2_l, tsc2_h, &tsc2); count = tsc2 - tsc1; printf ("Processor %d %llu Hz\n", currentcpu->cpunum, count); currentcpu->tsc = tsc1; currentcpu->hz = count; currentcpu->timediff = 0; }
static u64 get_ia32_bios_sign_id (void) { u64 rev; u32 a, b, c, d; asm_wrmsr64 (MSR_IA32_BIOS_SIGN_ID, 0); asm_cpuid (1, 0, &a, &b, &c, &d); asm_rdmsr64 (MSR_IA32_BIOS_SIGN_ID, &rev); return rev; }
static u64 get_pte_addr_mask (void) { u32 a, b, c, d; unsigned int nbits; asm_cpuid (CPUID_EXT_0, 0, &a, &b, &c, &d); if (a < CPUID_EXT_8) return PTE_ADDR_MASK64; asm_cpuid (CPUID_EXT_8, 0, &a, &b, &c, &d); nbits = a & CPUID_EXT_8_EAX_PHYSADDRSIZE_MASK; if (nbits < 32) { printf ("Invalid PhysAddrSize %u. Assumed 32.\n", nbits); nbits = 32; } if (nbits > 52) { printf ("Invalid PhysAddrSize %u. Assumed 52.\n", nbits); nbits = 52; } return ~(PAGESIZE_MASK | ~0ULL << nbits); }
static void do_cpuid_pass (u32 ia, u32 ic, u32 *oa, u32 *ob, u32 *oc, u32 *od) { asm_cpuid (ia, ic, oa, ob, oc, od); if (ia == 1) { /* *ob &= ~CPUID_1_EBX_NUMOFLP_MASK; */ /* *ob |= ~CPUID_1_EBX_NUMOFLP_1; */ *oc &= ~CPUID_1_ECX_VMX_BIT; /* *od &= ~CPUID_1_EDX_PAE_BIT; */ /* *od &= ~CPUID_1_EDX_APIC_BIT; */ } else if (ia == 4) { /* *oa &= ~CPUID_4_EAX_NUMOFTHREADS_MASK; */ /* *oa &= ~CPUID_4_EAX_NUMOFCORES_MASK; */ } }
static bool sysenter_available (void) { u32 a, b, c, d; unsigned int family, model, stepping; asm_cpuid (1, 0, &a, &b, &c, &d); if (d & CPUID_1_EDX_SEP_BIT) { family = (a & 0xF00) >> 8; model = (a & 0xF0) >> 4; stepping = (a & 0xF); if (family == 6 && model < 3 && stepping < 3) return false; return true; }