/** Display CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS for all supported sub-leafs. **/ VOID CpuidStructuredExtendedFeatureFlags ( VOID ) { UINT32 Eax; CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EBX Ebx; CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX Ecx; UINT32 SubLeaf; if (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS > gMaximumBasicFunction) { return; } AsmCpuidEx ( CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO, &Eax, NULL, NULL, NULL ); for (SubLeaf = 0; SubLeaf <= Eax; SubLeaf++) { AsmCpuidEx ( CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, SubLeaf, NULL, &Ebx.Uint32, &Ecx.Uint32, NULL ); if (Ebx.Uint32 != 0 || Ecx.Uint32 != 0) { Print (L"CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS (Leaf %08x, Sub-Leaf %08x)\n", CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, SubLeaf); Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx.Uint32, 0); PRINT_BIT_FIELD (Ebx, FSGSBASE); PRINT_BIT_FIELD (Ebx, IA32_TSC_ADJUST); PRINT_BIT_FIELD (Ebx, BMI1); PRINT_BIT_FIELD (Ebx, HLE); PRINT_BIT_FIELD (Ebx, AVX2); PRINT_BIT_FIELD (Ebx, FDP_EXCPTN_ONLY); PRINT_BIT_FIELD (Ebx, SMEP); PRINT_BIT_FIELD (Ebx, BMI2); PRINT_BIT_FIELD (Ebx, EnhancedRepMovsbStosb); PRINT_BIT_FIELD (Ebx, INVPCID); PRINT_BIT_FIELD (Ebx, RTM); PRINT_BIT_FIELD (Ebx, PQM); PRINT_BIT_FIELD (Ebx, DeprecateFpuCsDs); PRINT_BIT_FIELD (Ebx, MPX); PRINT_BIT_FIELD (Ebx, PQE); PRINT_BIT_FIELD (Ebx, RDSEED); PRINT_BIT_FIELD (Ebx, ADX); PRINT_BIT_FIELD (Ebx, SMAP); PRINT_BIT_FIELD (Ebx, CLFLUSHOPT); PRINT_BIT_FIELD (Ebx, IntelProcessorTrace); PRINT_BIT_FIELD (Ecx, PREFETCHWT1); PRINT_BIT_FIELD (Ecx, PKU); PRINT_BIT_FIELD (Ecx, OSPKE); } SubLeaf++; } while (SubLeaf <= Eax); }
/** Display CPUID_SOC_VENDOR sub-leafs that contain the SoC Vendor Brand String. Also display these sub-leafs as a single SoC Vendor Brand String. **/ VOID CpuidSocVendorBrandString ( VOID ) { CPUID_SOC_VENDOR_BRAND_STRING_DATA Eax; CPUID_SOC_VENDOR_BRAND_STRING_DATA Ebx; CPUID_SOC_VENDOR_BRAND_STRING_DATA Ecx; CPUID_SOC_VENDOR_BRAND_STRING_DATA Edx; // // Array to store brand string from 3 brand string leafs with // 4 32-bit brand string values per leaf and an extra value to // null terminate the string. // UINT32 BrandString[3 * 4 + 1]; AsmCpuidEx ( CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING1, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32 ); Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING1); Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); BrandString[0] = Eax.Uint32; BrandString[1] = Ebx.Uint32; BrandString[2] = Ecx.Uint32; BrandString[3] = Edx.Uint32; AsmCpuidEx ( CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING2, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32 ); Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING2); Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); BrandString[4] = Eax.Uint32; BrandString[5] = Ebx.Uint32; BrandString[6] = Ecx.Uint32; BrandString[7] = Edx.Uint32; AsmCpuidEx ( CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING3, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx.Uint32 ); Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_BRAND_STRING3); Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx.Uint32); BrandString[8] = Eax.Uint32; BrandString[9] = Ebx.Uint32; BrandString[10] = Ecx.Uint32; BrandString[11] = Edx.Uint32; BrandString[12] = 0; Print (L"Vendor Brand String = %a\n", (CHAR8 *)BrandString); }
/** Display CPUID_INTEL_PROCESSOR_TRACE main leaf and sub-leafs. **/ VOID CpuidIntelProcessorTraceMainLeaf ( VOID ) { UINT32 Eax; CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_EBX Ebx; CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF_ECX Ecx; if (CPUID_INTEL_PROCESSOR_TRACE > gMaximumBasicFunction) { return; } AsmCpuidEx ( CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF, &Eax, &Ebx.Uint32, &Ecx.Uint32, NULL ); Print (L"CPUID_INTEL_PROCESSOR_TRACE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_PROCESSOR_TRACE, CPUID_INTEL_PROCESSOR_TRACE_MAIN_LEAF); Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx.Uint32, 0); PRINT_VALUE (Eax, MaximumSubLeaf); PRINT_BIT_FIELD (Ebx, Cr3Filter); PRINT_BIT_FIELD (Ebx, ConfigurablePsb); PRINT_BIT_FIELD (Ebx, IpTraceStopFiltering); PRINT_BIT_FIELD (Ebx, Mtc); PRINT_BIT_FIELD (Ecx, RTIT); PRINT_BIT_FIELD (Ecx, ToPA); PRINT_BIT_FIELD (Ecx, SingleRangeOutput); PRINT_BIT_FIELD (Ecx, TraceTransportSubsystem); PRINT_BIT_FIELD (Ecx, LIP); CpuidIntelProcessorTraceSubLeaf (Eax); }
/** Display CPUID_EXTENDED_STATE main leaf and sub-leafs. **/ VOID CpuidExtendedStateMainLeaf ( VOID ) { CPUID_EXTENDED_STATE_MAIN_LEAF_EAX Eax; UINT32 Ebx; UINT32 Ecx; UINT32 Edx; if (CPUID_EXTENDED_STATE > gMaximumBasicFunction) { return; } AsmCpuidEx ( CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_MAIN_LEAF, &Eax.Uint32, &Ebx, &Ecx, &Edx ); Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_MAIN_LEAF); Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx, Edx); PRINT_BIT_FIELD (Eax, x87); PRINT_BIT_FIELD (Eax, SSE); PRINT_BIT_FIELD (Eax, AVX); PRINT_BIT_FIELD (Eax, MPX); PRINT_BIT_FIELD (Eax, AVX_512); PRINT_BIT_FIELD (Eax, IA32_XSS); PRINT_BIT_FIELD (Eax, PKRU); PRINT_VALUE (Ebx, EnabledSaveStateSize); PRINT_VALUE (Ecx, SupportedSaveStateSize); PRINT_VALUE (Edx, XCR0_Supported_32_63); CpuidExtendedStateSubLeaf (); CpuidExtendedStateSizeOffset (); }
/** Display CPUID_EXTENDED_STATE size and offset information sub-leaf. **/ VOID CpuidExtendedStateSizeOffset ( VOID ) { UINT32 Eax; UINT32 Ebx; CPUID_EXTENDED_STATE_SIZE_OFFSET_ECX Ecx; UINT32 Edx; UINT32 SubLeaf; for (SubLeaf = CPUID_EXTENDED_STATE_SIZE_OFFSET; SubLeaf < 32; SubLeaf++) { AsmCpuidEx ( CPUID_EXTENDED_STATE, SubLeaf, &Eax, &Ebx, &Ecx.Uint32, &Edx ); if (Edx != 0) { Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, SubLeaf); Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx, Ecx.Uint32, Edx); PRINT_VALUE (Eax, FeatureSaveStateSize); PRINT_VALUE (Ebx, FeatureSaveStateOffset); PRINT_BIT_FIELD (Ecx, XSS); PRINT_BIT_FIELD (Ecx, Compacted); } } }
/** Display CPUID_EXTENDED_STATE sub-leaf. **/ VOID CpuidExtendedStateSubLeaf ( VOID ) { CPUID_EXTENDED_STATE_SUB_LEAF_EAX Eax; UINT32 Ebx; CPUID_EXTENDED_STATE_SUB_LEAF_ECX Ecx; UINT32 Edx; AsmCpuidEx ( CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF, &Eax.Uint32, &Ebx, &Ecx.Uint32, &Edx ); Print (L"CPUID_EXTENDED_STATE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_STATE, CPUID_EXTENDED_STATE_SUB_LEAF); Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx.Uint32, Edx); PRINT_BIT_FIELD (Eax, XSAVEOPT); PRINT_BIT_FIELD (Eax, XSAVEC); PRINT_BIT_FIELD (Eax, XGETBV); PRINT_BIT_FIELD (Eax, XSAVES); PRINT_VALUE (Ebx, EnabledSaveStateSize_XCR0_IA32_XSS); PRINT_BIT_FIELD (Ecx, XCR0); PRINT_BIT_FIELD (Ecx, PT); PRINT_BIT_FIELD (Ecx, XCR0_1); PRINT_VALUE (Edx, IA32_XSS_Supported_32_63); }
/** Display CPUID_EXTENDED_TOPOLOGY leafs for all supported levels. **/ VOID CpuidExtendedTopology ( VOID ) { CPUID_EXTENDED_TOPOLOGY_EAX Eax; CPUID_EXTENDED_TOPOLOGY_EBX Ebx; CPUID_EXTENDED_TOPOLOGY_ECX Ecx; UINT32 Edx; UINT32 LevelNumber; if (CPUID_EXTENDED_TOPOLOGY > gMaximumBasicFunction) { return; } LevelNumber = 0; do { AsmCpuidEx ( CPUID_EXTENDED_TOPOLOGY, LevelNumber, &Eax.Uint32, &Ebx.Uint32, &Ecx.Uint32, &Edx ); if (Eax.Bits.ApicIdShift != 0) { Print (L"CPUID_EXTENDED_TOPOLOGY (Leaf %08x, Sub-Leaf %08x)\n", CPUID_EXTENDED_TOPOLOGY, LevelNumber); Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx.Uint32, Edx); PRINT_BIT_FIELD (Eax, ApicIdShift); PRINT_BIT_FIELD (Ebx, LogicalProcessors); PRINT_BIT_FIELD (Ecx, LevelNumber); PRINT_BIT_FIELD (Ecx, LevelType); PRINT_VALUE (Edx, x2APIC_ID); } LevelNumber++; } while (Eax.Bits.ApicIdShift != 0); }
/** Display CPUID_SOC_VENDOR main leaf and sub-leafs. **/ VOID CpuidSocVendor ( VOID ) { UINT32 Eax; CPUID_SOC_VENDOR_MAIN_LEAF_EBX Ebx; UINT32 Ecx; UINT32 Edx; if (CPUID_SOC_VENDOR > gMaximumBasicFunction) { return; } AsmCpuidEx ( CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_MAIN_LEAF, &Eax, &Ebx.Uint32, &Ecx, &Edx ); Print (L"CPUID_SOC_VENDOR (Leaf %08x, Sub-Leaf %08x)\n", CPUID_SOC_VENDOR, CPUID_SOC_VENDOR_MAIN_LEAF); Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax, Ebx.Uint32, Ecx, Edx); if (Eax < 3) { Print (L" Not Supported\n"); return; } PRINT_VALUE (Eax, MaxSOCID_Index); PRINT_BIT_FIELD (Ebx, SocVendorId); PRINT_BIT_FIELD (Ebx, IsVendorScheme); PRINT_VALUE (Ecx, ProjectID); PRINT_VALUE (Edx, SteppingID); CpuidSocVendorBrandString (); }
/** Display CPUID_CACHE_PARAMS for all supported sub-leafs. **/ VOID CpuidCacheParams ( VOID ) { UINT32 CacheLevel; CPUID_CACHE_PARAMS_EAX Eax; CPUID_CACHE_PARAMS_EBX Ebx; UINT32 Ecx; CPUID_CACHE_PARAMS_EDX Edx; if (CPUID_CACHE_PARAMS > gMaximumBasicFunction) { return; } CacheLevel = 0; do { AsmCpuidEx ( CPUID_CACHE_PARAMS, CacheLevel, &Eax.Uint32, &Ebx.Uint32, &Ecx, &Edx.Uint32 ); if (Eax.Bits.CacheType != CPUID_CACHE_PARAMS_CACHE_TYPE_NULL) { Print (L"CPUID_CACHE_PARAMS (Leaf %08x, Sub-Leaf %08x)\n", CPUID_CACHE_PARAMS, CacheLevel); Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, Ecx, Edx.Uint32); PRINT_BIT_FIELD (Eax, CacheType); PRINT_BIT_FIELD (Eax, CacheLevel); PRINT_BIT_FIELD (Eax, SelfInitializingCache); PRINT_BIT_FIELD (Eax, FullyAssociativeCache); PRINT_BIT_FIELD (Eax, MaximumAddressableIdsForLogicalProcessors); PRINT_BIT_FIELD (Eax, MaximumAddressableIdsForProcessorCores); PRINT_BIT_FIELD (Ebx, LineSize); PRINT_BIT_FIELD (Ebx, LinePartitions); PRINT_BIT_FIELD (Ebx, Ways); PRINT_VALUE (Ecx, NumberOfSets); PRINT_BIT_FIELD (Edx, Invalidate); PRINT_BIT_FIELD (Edx, CacheInclusiveness); PRINT_BIT_FIELD (Edx, ComplexCacheIndexing); } CacheLevel++; } while (Eax.Bits.CacheType != CPUID_CACHE_PARAMS_CACHE_TYPE_NULL); }
/** Display CPUID_PLATFORM_QOS_ENFORCEMENT main leaf and sub-leaf. **/ VOID CpuidPlatformQosEnforcementMainLeaf ( VOID ) { CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF_EBX Ebx; if (CPUID_PLATFORM_QOS_ENFORCEMENT > gMaximumBasicFunction) { return; } AsmCpuidEx ( CPUID_PLATFORM_QOS_ENFORCEMENT, CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF, NULL, &Ebx.Uint32, NULL, NULL ); Print (L"CPUID_PLATFORM_QOS_ENFORCEMENT (Leaf %08x, Sub-Leaf %08x)\n", CPUID_PLATFORM_QOS_ENFORCEMENT, CPUID_PLATFORM_QOS_ENFORCEMENT_MAIN_LEAF); Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx.Uint32, 0, 0); PRINT_BIT_FIELD (Ebx, L3CacheQosEnforcement); CpuidPlatformQosEnforcementResidSubLeaf (); }
/** Display CPUID_PLATFORM_QOS_MONITORING enumeration sub-leaf. **/ VOID CpuidPlatformQosMonitoringEnumerationSubLeaf ( VOID ) { UINT32 Ebx; CPUID_PLATFORM_QOS_MONITORING_ENUMERATION_SUB_LEAF_EDX Edx; if (CPUID_PLATFORM_QOS_MONITORING > gMaximumBasicFunction) { return; } AsmCpuidEx ( CPUID_PLATFORM_QOS_MONITORING, CPUID_PLATFORM_QOS_MONITORING_ENUMERATION_SUB_LEAF, NULL, &Ebx, NULL, &Edx.Uint32 ); Print (L"CPUID_PLATFORM_QOS_MONITORING (Leaf %08x, Sub-Leaf %08x)\n", CPUID_PLATFORM_QOS_MONITORING, CPUID_PLATFORM_QOS_MONITORING_ENUMERATION_SUB_LEAF); Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx, 0, Edx.Uint32); PRINT_VALUE (Ebx, Maximum_RMID_Range); PRINT_BIT_FIELD (Edx, L3CacheQosEnforcement); }
/** Display CPUID_INTEL_PROCESSOR_TRACE sub-leafs. @param[in] MaximumSubLeaf Maximum sub-leaf index for CPUID_INTEL_PROCESSOR_TRACE. **/ VOID CpuidIntelProcessorTraceSubLeaf ( UINT32 MaximumSubLeaf ) { UINT32 SubLeaf; CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EAX Eax; CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF_EBX Ebx; for (SubLeaf = CPUID_INTEL_PROCESSOR_TRACE_SUB_LEAF; SubLeaf <= MaximumSubLeaf; SubLeaf++) { AsmCpuidEx ( CPUID_INTEL_PROCESSOR_TRACE, SubLeaf, &Eax.Uint32, &Ebx.Uint32, NULL, NULL ); Print (L"CPUID_INTEL_PROCESSOR_TRACE (Leaf %08x, Sub-Leaf %08x)\n", CPUID_INTEL_PROCESSOR_TRACE, SubLeaf); Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx.Uint32, 0, 0); PRINT_BIT_FIELD (Eax, ConfigurableAddressRanges); PRINT_BIT_FIELD (Eax, MtcPeriodEncodings); PRINT_BIT_FIELD (Ebx, CycleThresholdEncodings); PRINT_BIT_FIELD (Ebx, PsbFrequencyEncodings); } }
/** Display CPUID_PLATFORM_QOS_ENFORCEMENT sub-leaf. **/ VOID CpuidPlatformQosEnforcementResidSubLeaf ( VOID ) { CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_EAX Eax; UINT32 Ebx; CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_ECX Ecx; CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF_EDX Edx; AsmCpuidEx ( CPUID_PLATFORM_QOS_ENFORCEMENT, CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF, &Eax.Uint32, &Ebx, &Ecx.Uint32, &Edx.Uint32 ); Print (L"CPUID_PLATFORM_QOS_ENFORCEMENT (Leaf %08x, Sub-Leaf %08x)\n", CPUID_PLATFORM_QOS_ENFORCEMENT, CPUID_PLATFORM_QOS_ENFORCEMENT_RESID_SUB_LEAF); Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", Eax.Uint32, Ebx, Ecx.Uint32, Edx.Uint32); PRINT_BIT_FIELD (Eax, CapacityLength); PRINT_VALUE (Ebx, AllocationUnitBitMap); PRINT_BIT_FIELD (Ecx, CosUpdatesInfrequent); PRINT_BIT_FIELD (Ecx, CodeDataPrioritization); PRINT_BIT_FIELD (Edx, HighestCosNumber); }
/** Display CPUID_PLATFORM_QOS_MONITORING capability sub-leaf. **/ VOID CpuidPlatformQosMonitoringCapabilitySubLeaf ( VOID ) { UINT32 Ebx; UINT32 Ecx; CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_SUB_LEAF_EDX Edx; if (CPUID_PLATFORM_QOS_MONITORING > gMaximumBasicFunction) { return; } AsmCpuidEx ( CPUID_PLATFORM_QOS_MONITORING, CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_SUB_LEAF, NULL, &Ebx, &Ecx, &Edx.Uint32 ); Print (L"CPUID_PLATFORM_QOS_MONITORING (Leaf %08x, Sub-Leaf %08x)\n", CPUID_PLATFORM_QOS_MONITORING, CPUID_PLATFORM_QOS_MONITORING_CAPABILITY_SUB_LEAF); Print (L" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n", 0, Ebx, Ecx, Edx.Uint32); PRINT_VALUE (Ebx, OccupancyConversionFactor); PRINT_VALUE (Ecx, Maximum_RMID_Range); PRINT_BIT_FIELD (Edx, L3CacheOccupancyMonitoring); }
/** This function set VMCS guest AP wakeup field. @param Index CPU index @param Vector AP wakeup vector **/ VOID SetVmcsGuestApWakeupField ( IN UINT32 Index, IN UINT8 Vector ) { VM_ENTRY_CONTROLS VmEntryControls; // // AP state: // eax: 0 // ebx: 0 // ecx: 0 // edx: CPUID_EAX (1) // esi: 0 // edi: 0 // ebp: 0 // esp: 0 // esp: 0 // cr0: 00000010 // cr2: 00000000 // cr3: 00000000 // cr4: 00000000 // dr0: 00000000 // dr1: 00000000 // dr2: 00000000 // dr3: 00000000 // dr6: ffff0ff0 // dr7: 00000400 // // eip: 0 // eflags: 00010002 // // idtbase: 00000000 // gdtbase: 00000000 // ldtbase: 00000000 // tssbase: 00000000 // idtlim: 0000ffff // gdtlim: 0000ffff // ldtlim: 0000ffff // tsslim: 0000ffff // ldtar: 0082 // tssar: 008b // ldtr: 0000 // tr: 0000 // // csbase: vector << 12 // dsbase: 0 // ssbase: 0 // esbase: 0 // fsbase: 0 // gsbase: 0 // cslim: 0000ffff // dslim: 0000ffff // sslim: 0000ffff // eslim: 0000ffff // fslim: 0000ffff // gslim: 0000ffff // csar: 0093 // dsar: 0093 // ssar: 0093 // esar: 0093 // fsar: 0093 // gsar: 0093 // cs: vector << 8 // ds: 0 // ss: 0 // es: 0 // fs: 0 // gs: 0 // VmWrite32 (VMCS_32_GUEST_ACTIVITY_STATE_INDEX, GUEST_ACTIVITY_STATE_ACTIVE); VmWrite16 (VMCS_16_GUEST_CS_INDEX, (UINT16)Vector << 8); VmWriteN (VMCS_N_GUEST_CS_BASE_INDEX, (UINTN)Vector << 12); VmWriteN (VMCS_N_GUEST_RIP_INDEX, 0); VmWriteN (VMCS_N_GUEST_SS_BASE_INDEX, 0); VmWriteN (VMCS_N_GUEST_RSP_INDEX, 0); VmWriteN (VMCS_N_GUEST_RFLAGS_INDEX, 0x00010002); VmWrite16 (VMCS_16_GUEST_ES_INDEX, 0); VmWrite16 (VMCS_16_GUEST_SS_INDEX, 0); VmWrite16 (VMCS_16_GUEST_DS_INDEX, 0); VmWrite16 (VMCS_16_GUEST_FS_INDEX, 0); VmWrite16 (VMCS_16_GUEST_GS_INDEX, 0); VmWrite16 (VMCS_16_GUEST_TR_INDEX, 0); VmWriteN (VMCS_N_GUEST_ES_BASE_INDEX, 0); VmWriteN (VMCS_N_GUEST_DS_BASE_INDEX, 0); VmWriteN (VMCS_N_GUEST_FS_BASE_INDEX, 0); VmWriteN (VMCS_N_GUEST_GS_BASE_INDEX, 0); VmWrite32 (VMCS_32_GUEST_ES_ACCESS_RIGHT_INDEX, 0x0093); VmWrite32 (VMCS_32_GUEST_CS_ACCESS_RIGHT_INDEX, 0x0093); VmWrite32 (VMCS_32_GUEST_SS_ACCESS_RIGHT_INDEX, 0x0093); VmWrite32 (VMCS_32_GUEST_DS_ACCESS_RIGHT_INDEX, 0x0093); VmWrite32 (VMCS_32_GUEST_FS_ACCESS_RIGHT_INDEX, 0x0093); VmWrite32 (VMCS_32_GUEST_GS_ACCESS_RIGHT_INDEX, 0x0093); VmWrite32 (VMCS_32_GUEST_ES_LIMIT_INDEX, 0x0000ffff); VmWrite32 (VMCS_32_GUEST_CS_LIMIT_INDEX, 0x0000ffff); VmWrite32 (VMCS_32_GUEST_SS_LIMIT_INDEX, 0x0000ffff); VmWrite32 (VMCS_32_GUEST_DS_LIMIT_INDEX, 0x0000ffff); VmWrite32 (VMCS_32_GUEST_FS_LIMIT_INDEX, 0x0000ffff); VmWrite32 (VMCS_32_GUEST_GS_LIMIT_INDEX, 0x0000ffff); VmWriteN (VMCS_N_GUEST_DR7_INDEX, 0x00000400); VmWriteN (VMCS_N_GUEST_LDTR_BASE_INDEX, 0); VmWriteN (VMCS_N_GUEST_TR_BASE_INDEX, 0); VmWriteN (VMCS_N_GUEST_GDTR_BASE_INDEX, 0); VmWriteN (VMCS_N_GUEST_IDTR_BASE_INDEX, 0); VmWrite32 (VMCS_32_GUEST_LDTR_LIMIT_INDEX, 0x0000ffff); VmWrite32 (VMCS_32_GUEST_TR_LIMIT_INDEX, 0x0000ffff); VmWrite32 (VMCS_32_GUEST_GDTR_LIMIT_INDEX, 0x0000ffff); VmWrite32 (VMCS_32_GUEST_IDTR_LIMIT_INDEX, 0x0000ffff); VmWrite32 (VMCS_32_GUEST_LDTR_ACCESS_RIGHT_INDEX, 0x0082); VmWrite32 (VMCS_32_GUEST_TR_ACCESS_RIGHT_INDEX, 0x008b); VmWrite32 (VMCS_32_GUEST_INTERRUPTIBILITY_STATE_INDEX, 0); VmEntryControls.Uint32 = VmRead32 (VMCS_32_CONTROL_VMENTRY_CONTROLS_INDEX); VmEntryControls.Bits.Ia32eGuest = 0; VmWrite32 (VMCS_32_CONTROL_VMENTRY_CONTROLS_INDEX, VmEntryControls.Uint32); mGuestContextCommon.GuestContextPerCpu[Index].Cr0 = (UINTN)(AsmReadMsr64 (IA32_VMX_CR0_FIXED0_MSR_INDEX) & AsmReadMsr64 (IA32_VMX_CR0_FIXED1_MSR_INDEX) & ~CR0_PE & ~CR0_PG); mGuestContextCommon.GuestContextPerCpu[Index].Cr4 = (UINTN)(AsmReadMsr64 (IA32_VMX_CR4_FIXED0_MSR_INDEX) & AsmReadMsr64 (IA32_VMX_CR4_FIXED1_MSR_INDEX)); mGuestContextCommon.GuestContextPerCpu[Index].EFER = 0; VmWrite64 (VMCS_64_GUEST_IA32_EFER_INDEX, 0); VmWriteN (VMCS_N_GUEST_CR0_INDEX, mGuestContextCommon.GuestContextPerCpu[Index].Cr0); VmWriteN (VMCS_N_GUEST_CR4_INDEX, mGuestContextCommon.GuestContextPerCpu[Index].Cr4); VmWriteN (VMCS_N_GUEST_CR3_INDEX, 0); VmWriteN (VMCS_N_CONTROL_CR0_READ_SHADOW_INDEX, mGuestContextCommon.GuestContextPerCpu[Index].Cr0); VmWriteN (VMCS_N_CONTROL_CR4_READ_SHADOW_INDEX, mGuestContextCommon.GuestContextPerCpu[Index].Cr4 & ~CR4_VMXE & ~CR4_SMXE); VmWrite64 (VMCS_64_GUEST_IA32_EFER_INDEX, mGuestContextCommon.GuestContextPerCpu[Index].EFER); ZeroMem (&mGuestContextCommon.GuestContextPerCpu[Index].Register, sizeof(X86_REGISTER)); AsmCpuidEx ( CPUID_FEATURE_INFORMATION, 0, (UINT32 *)&mGuestContextCommon.GuestContextPerCpu[Index].Register.Rax, (UINT32 *)&mGuestContextCommon.GuestContextPerCpu[Index].Register.Rbx, (UINT32 *)&mGuestContextCommon.GuestContextPerCpu[Index].Register.Rcx, (UINT32 *)&mGuestContextCommon.GuestContextPerCpu[Index].Register.Rdx ); mGuestContextCommon.GuestContextPerCpu[Index].Register.Rdx = mGuestContextCommon.GuestContextPerCpu[Index].Register.Rax; mGuestContextCommon.GuestContextPerCpu[Index].Register.Rax = 0; mGuestContextCommon.GuestContextPerCpu[Index].Register.Rbx = 0; mGuestContextCommon.GuestContextPerCpu[Index].Register.Rcx = 0; if (!mGuestContextCommon.GuestContextPerCpu[Index].UnrestrictedGuest) { mGuestContextCommon.GuestContextPerCpu[Index].Cr0 |= CR0_PE | CR0_PG; VmWriteN (VMCS_N_GUEST_CR0_INDEX, mGuestContextCommon.GuestContextPerCpu[Index].Cr0); VmWriteN (VMCS_N_CONTROL_CR0_READ_SHADOW_INDEX, mGuestContextCommon.GuestContextPerCpu[Index].Cr0); // BUGBUG: Start emulator... CpuDeadLoop (); } }