13#define CPU_INTERRUPT_NUM 256
18BOOLEAN InterruptState =
FALSE;
20BOOLEAN mIsFlushingGCD;
21BOOLEAN mIsAllocatingPageTable =
FALSE;
22UINT64 mValidMtrrAddressMask;
23UINT64 mValidMtrrBitsMask;
24UINT64 mTimerPeriod = 0;
125 if (FlushType == EfiCpuFlushTypeWriteBackInvalidate) {
128 }
else if (FlushType == EfiCpuFlushTypeInvalidate) {
132 return EFI_UNSUPPORTED;
153 InterruptState =
TRUE;
174 InterruptState =
FALSE;
196 return EFI_INVALID_PARAMETER;
199 *State = InterruptState;
222 return EFI_UNSUPPORTED;
253 return RegisterCpuInterruptHandler (InterruptType, InterruptHandler);
283 IN UINT32 TimerIndex,
284 OUT UINT64 *TimerValue,
285 OUT UINT64 *TimerPeriod OPTIONAL
291 if (TimerValue ==
NULL) {
292 return EFI_INVALID_PARAMETER;
295 if (TimerIndex != 0) {
296 return EFI_INVALID_PARAMETER;
301 if (TimerPeriod !=
NULL) {
302 if (mTimerPeriod == 0) {
317 EndValue - BeginValue,
322 *TimerPeriod = mTimerPeriod;
378 RETURN_STATUS Status;
379 MTRR_MEMORY_CACHE_TYPE CacheType;
383 UINT64 CacheAttributes;
384 UINT64 MemoryAttributes;
385 MTRR_MEMORY_CACHE_TYPE CurrentCacheType;
393 if (mIsFlushingGCD) {
394 DEBUG ((DEBUG_VERBOSE,
" Flushing GCD\n"));
408 if (mIsAllocatingPageTable) {
409 DEBUG ((DEBUG_VERBOSE,
" Allocating page table memory\n"));
413 CacheAttributes = Attributes & EFI_CACHE_ATTRIBUTE_MASK;
414 MemoryAttributes = Attributes & EFI_MEMORY_ATTRIBUTE_MASK;
416 if (Attributes != (CacheAttributes | MemoryAttributes)) {
417 return EFI_INVALID_PARAMETER;
420 if (CacheAttributes != 0) {
422 return EFI_UNSUPPORTED;
425 switch (CacheAttributes) {
427 CacheType = CacheUncacheable;
431 CacheType = CacheWriteCombining;
435 CacheType = CacheWriteThrough;
439 CacheType = CacheWriteProtected;
443 CacheType = CacheWriteBack;
447 return EFI_INVALID_PARAMETER;
451 if (CurrentCacheType != CacheType) {
462 MpStatus =
gBS->LocateProtocol (
463 &gEfiMpServiceProtocolGuid,
470 if (!EFI_ERROR (MpStatus)) {
472 MpStatus = MpService->StartupAllAPs (
481 ASSERT (MpStatus ==
EFI_SUCCESS || MpStatus == EFI_NOT_STARTED);
485 if (EFI_ERROR (Status)) {
508 UINT32 MaxExtendedFunction;
516 if (MaxExtendedFunction >= CPUID_VIR_PHY_ADDRESS_SIZE) {
531 if (ExtendedFeatureFlagsEcx.
Bits.
TME_EN == 1) {
540 mValidMtrrAddressMask = mValidMtrrBitsMask & 0xfffffffffffff000ULL;
555 IN UINT8 MtrrAttributes
558 switch (MtrrAttributes) {
559 case MTRR_CACHE_UNCACHEABLE:
560 return EFI_MEMORY_UC;
561 case MTRR_CACHE_WRITE_COMBINING:
562 return EFI_MEMORY_WC;
563 case MTRR_CACHE_WRITE_THROUGH:
564 return EFI_MEMORY_WT;
565 case MTRR_CACHE_WRITE_PROTECTED:
566 return EFI_MEMORY_WP;
567 case MTRR_CACHE_WRITE_BACK:
568 return EFI_MEMORY_WB;
606 for (Index = 0; Index < NumberOfDescriptors; Index++) {
607 if ((BaseAddress >= MemorySpaceMap[Index].BaseAddress) &&
608 (BaseAddress < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length))
613 if ((BaseAddress + Length - 1 >= MemorySpaceMap[Index].BaseAddress) &&
614 (BaseAddress + Length - 1 < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length))
621 return EFI_NOT_FOUND;
667 if (EFI_ERROR (Status)) {
674 for (Index = StartIndex; Index <= EndIndex; Index++) {
682 if (BaseAddress >= MemorySpaceMap[Index].BaseAddress) {
683 RegionStart = BaseAddress;
685 RegionStart = MemorySpaceMap[Index].BaseAddress;
688 if (BaseAddress + Length - 1 < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {
689 RegionLength = BaseAddress + Length - RegionStart;
691 RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart;
697 gDS->SetMemorySpaceAttributes (
700 (MemorySpaceMap[Index].Attributes & ~EFI_CACHE_ATTRIBUTE_MASK) | (MemorySpaceMap[Index].Capabilities & Attributes)
725 UINT64 CurrentAttributes;
727 UINTN NumberOfDescriptors;
729 UINT64 DefaultAttributes;
732 UINT32 FirmwareVariableMtrrCount;
733 UINT8 DefaultMemoryType;
736 ASSERT (FirmwareVariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
738 MemorySpaceMap =
NULL;
750 mValidMtrrAddressMask,
757 Status =
gDS->GetMemorySpaceMap (
758 &NumberOfDescriptors,
769 for (Index = 0; Index < NumberOfDescriptors; Index++) {
774 gDS->SetMemorySpaceAttributes (
775 MemorySpaceMap[Index].BaseAddress,
776 MemorySpaceMap[Index].Length,
777 (MemorySpaceMap[Index].Attributes & ~EFI_CACHE_ATTRIBUTE_MASK) |
778 (MemorySpaceMap[Index].Capabilities & DefaultAttributes)
785 for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {
786 if (VariableMtrr[Index].Valid &&
787 (VariableMtrr[Index].Type == MTRR_CACHE_WRITE_BACK))
792 VariableMtrr[Index].BaseAddress,
793 VariableMtrr[Index].Length,
802 for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {
803 if (VariableMtrr[Index].Valid &&
804 (VariableMtrr[Index].Type != MTRR_CACHE_WRITE_BACK) &&
805 (VariableMtrr[Index].Type != MTRR_CACHE_UNCACHEABLE))
811 VariableMtrr[Index].BaseAddress,
812 VariableMtrr[Index].Length,
821 for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {
822 if (VariableMtrr[Index].Valid &&
823 (VariableMtrr[Index].Type == MTRR_CACHE_UNCACHEABLE))
828 VariableMtrr[Index].BaseAddress,
829 VariableMtrr[Index].Length,
842 for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
843 RegValue = MtrrFixedSettings.Mtrr[Index];
847 for (SubIndex = 0; SubIndex < 8; SubIndex++) {
848 MtrrType = (UINT8)
RShiftU64 (RegValue, SubIndex * 8);
854 Attributes = CurrentAttributes;
859 if (CurrentAttributes != Attributes) {
867 BaseAddress = mFixedMtrrTable[Index].BaseAddress + mFixedMtrrTable[Index].Length * SubIndex;
869 Attributes = CurrentAttributes;
873 Length += mFixedMtrrTable[Index].Length;
891 if (MemorySpaceMap !=
NULL) {
910 return ((Cr0.Bits.PG != 0) && (Cr4.Bits.PAE != 0));
925 mIsFlushingGCD =
TRUE;
935 mIsFlushingGCD =
FALSE;
950 IA32_IDT_GATE_DESCRIPTOR *IdtTable;
951 IA32_DESCRIPTOR IdtDescriptor;
957 VectorInfo = VectorInfoList;
961 IdtEntryCount = (IdtDescriptor.Limit + 1) /
sizeof (IA32_IDT_GATE_DESCRIPTOR);
962 if (IdtEntryCount < CPU_INTERRUPT_NUM) {
966 IdtTable =
AllocateZeroPool (
sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM);
967 ASSERT (IdtTable !=
NULL);
968 CopyMem (IdtTable, (VOID *)IdtDescriptor.Base, sizeof (IA32_IDT_GATE_DESCRIPTOR) * IdtEntryCount);
973 IdtDescriptor.Base = (
UINTN)IdtTable;
974 IdtDescriptor.Limit = (UINT16)(
sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM - 1);
978 Status = InitializeCpuExceptionHandlers (VectorInfo);
1043 IN UINT64 Capabilities,
1047 UINT64 IntersectionBase;
1048 UINT64 IntersectionEnd;
1052 ((Descriptor->Capabilities & Capabilities) == Capabilities))
1057 IntersectionBase =
MAX (Base, Descriptor->BaseAddress);
1058 IntersectionEnd =
MIN (
1060 Descriptor->BaseAddress + Descriptor->Length
1062 if (IntersectionBase >= IntersectionEnd) {
1070 Status =
gDS->AddMemorySpace (
1073 IntersectionEnd - IntersectionBase,
1078 EFI_ERROR (Status) ? DEBUG_ERROR : DEBUG_VERBOSE,
1079 "%a: %a: add [%Lx, %Lx): %r\n",
1091 "%a: %a: desc [%Lx, %Lx) type %u cap %Lx conflicts "
1092 "with aperture [%Lx, %Lx) cap %Lx\n",
1095 Descriptor->BaseAddress,
1096 Descriptor->BaseAddress + Descriptor->Length,
1097 (UINT32)Descriptor->GcdMemoryType,
1098 Descriptor->Capabilities,
1103 return EFI_INVALID_PARAMETER;
1121 IN UINT64 Capabilities
1126 UINTN NumberOfDescriptors;
1129 Status =
gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
1130 if (EFI_ERROR (Status)) {
1133 "%a: %a: GetMemorySpaceMap(): %r\n",
1141 for (Index = 0; Index < NumberOfDescriptors; Index++) {
1146 &MemorySpaceMap[Index]
1148 if (EFI_ERROR (Status)) {
1149 goto FreeMemorySpaceMap;
1163 for (CheckBase = Base;
1164 CheckBase < Base + Length;
1167 CheckStatus =
gDS->GetMemorySpaceDescriptor (CheckBase, &Descriptor);
1170 ASSERT ((Descriptor.
Capabilities & Capabilities) == Capabilities);
1204 Status =
gDS->AllocateMemorySpace (
1213 if (EFI_ERROR (Status)) {
1216 "%a: %a: AllocateMemorySpace() Status - %r\n",
1247 InitializeFloatingPointUnits ();
1267 Status =
gBS->InstallMultipleProtocolInterfaces (
1269 &gEfiCpuArchProtocolGuid,
1288 Status =
gBS->CreateEventEx (
1293 &gIdleLoopEventGuid,
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
EFI_STATUS EFIAPI CpuGetInterruptState(IN EFI_CPU_ARCH_PROTOCOL *This, OUT BOOLEAN *State)
VOID EFIAPI IdleLoopEventCallback(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS EFIAPI CpuRegisterInterruptHandler(IN EFI_CPU_ARCH_PROTOCOL *This, IN EFI_EXCEPTION_TYPE InterruptType, IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler)
EFI_STATUS EFIAPI CpuGetTimerValue(IN EFI_CPU_ARCH_PROTOCOL *This, IN UINT32 TimerIndex, OUT UINT64 *TimerValue, OUT UINT64 *TimerPeriod OPTIONAL)
EFI_STATUS EFIAPI CpuDisableInterrupt(IN EFI_CPU_ARCH_PROTOCOL *This)
EFI_STATUS EFIAPI CpuInit(IN EFI_CPU_ARCH_PROTOCOL *This, IN EFI_CPU_INIT_TYPE InitType)
EFI_STATUS EFIAPI CpuFlushCpuDataCache(IN EFI_CPU_ARCH_PROTOCOL *This, IN EFI_PHYSICAL_ADDRESS Start, IN UINT64 Length, IN EFI_CPU_FLUSH_TYPE FlushType)
EFI_STATUS EFIAPI CpuEnableInterrupt(IN EFI_CPU_ARCH_PROTOCOL *This)
EFI_STATUS EFIAPI CpuSetMemoryAttributes(IN EFI_CPU_ARCH_PROTOCOL *This, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
#define RETURN_ERROR(StatusCode)
UINT64 EFIAPI AsmReadTsc(VOID)
VOID EFIAPI EnableInterrupts(VOID)
VOID EFIAPI DisableInterrupts(VOID)
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
UINT64 EFIAPI DivU64x64Remainder(IN UINT64 Dividend, IN UINT64 Divisor, OUT UINT64 *Remainder OPTIONAL)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID(EFIAPI * EFI_CPU_INTERRUPT_HANDLER)(IN CONST EFI_EXCEPTION_TYPE InterruptType, IN CONST EFI_SYSTEM_CONTEXT SystemContext)
UINT32 EFIAPI AsmCpuidEx(IN UINT32 Index, IN UINT32 SubIndex, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
VOID EFIAPI CpuSleep(VOID)
VOID InitializeMpSupport(VOID)
VOID InitializePageTableLib(VOID)
RETURN_STATUS EFIAPI AssignMemoryPageAttributes(IN PAGE_TABLE_LIB_PAGING_CONTEXT *PagingContext OPTIONAL, IN PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes, IN PAGE_TABLE_LIB_ALLOCATE_PAGES AllocatePagesFunc OPTIONAL)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG_CODE_BEGIN()
#define DEBUG(Expression)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID EFIAPI AsmInvd(VOID)
UINT64 EFIAPI AsmReadMsr64(IN UINT32 Index)
VOID EFIAPI AsmWbinvd(VOID)
UINTN EFIAPI AsmReadCr0(VOID)
UINTN EFIAPI AsmReadCr4(VOID)
UINTN EFIAPI GetLocalApicBaseAddress(VOID)
#define MSR_IA32_MTRR_FIX4K_E0000
#define MSR_IA32_MTRR_FIX4K_C8000
#define MSR_IA32_MTRR_FIX4K_E8000
#define MSR_IA32_MTRR_FIX4K_F8000
#define MSR_IA32_MTRR_FIX16K_80000
#define MSR_IA32_MTRR_FIX16K_A0000
#define MSR_IA32_MTRR_FIX4K_D0000
#define MSR_IA32_MTRR_FIX64K_00000
#define MSR_IA32_TME_ACTIVATE
#define MSR_IA32_MTRR_FIX4K_D8000
#define MSR_IA32_MTRR_FIX4K_C0000
#define MSR_IA32_MTRR_FIX4K_F0000
#define CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
UINT32 EFIAPI MtrrGetMemoryAttributeInVariableMtrr(IN UINT64 MtrrValidBitsMask, IN UINT64 MtrrValidAddressMask, OUT VARIABLE_MTRR *VariableMtrr)
MTRR_MEMORY_CACHE_TYPE EFIAPI MtrrGetMemoryAttribute(IN PHYSICAL_ADDRESS Address)
MTRR_SETTINGS *EFIAPI MtrrSetAllMtrrs(IN MTRR_SETTINGS *MtrrSetting)
UINT32 EFIAPI GetFirmwareVariableMtrrCount(VOID)
BOOLEAN EFIAPI IsMtrrSupported(VOID)
RETURN_STATUS EFIAPI MtrrSetMemoryAttribute(IN PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN MTRR_MEMORY_CACHE_TYPE Attribute)
MTRR_FIXED_SETTINGS *EFIAPI MtrrGetFixedMtrr(OUT MTRR_FIXED_SETTINGS *FixedSettings)
MTRR_MEMORY_CACHE_TYPE EFIAPI MtrrGetDefaultMemoryType(VOID)
MTRR_SETTINGS *EFIAPI MtrrGetAllMtrrs(OUT MTRR_SETTINGS *MtrrSetting)
@ EfiGcdMemoryTypeNonExistent
@ EfiGcdMemoryTypeMemoryMappedIo
UINT64 EFI_PHYSICAL_ADDRESS
EFI_STATUS SetGcdMemorySpaceAttributes(IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap, IN UINTN NumberOfDescriptors, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
BOOLEAN IsPagingAndPageAddressExtensionsEnabled(VOID)
VOID InitInterruptDescriptorTable(VOID)
UINT64 GetMemorySpaceAttributeFromMtrrType(IN UINT8 MtrrAttributes)
EFI_STATUS EFIAPI InitializeCpu(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
VOID AddLocalApicMemorySpace(IN EFI_HANDLE ImageHandle)
VOID RefreshMemoryAttributesFromMtrr(VOID)
VOID EFIAPI SetMtrrsFromBuffer(IN VOID *Buffer)
EFI_STATUS SearchGcdMemorySpaces(IN EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap, IN UINTN NumberOfDescriptors, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, OUT UINTN *StartIndex, OUT UINTN *EndIndex)
VOID InitializeMtrrMask(VOID)
VOID RefreshGcdMemoryAttributes(VOID)
EFI_STATUS AddMemoryMappedIoSpace(IN UINT64 Base, IN UINT64 Length, IN UINT64 Capabilities)
EFI_STATUS IntersectMemoryDescriptor(IN UINT64 Base, IN UINT64 Length, IN UINT64 Capabilities, IN CONST EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor)
VOID RefreshGcdMemoryAttributesFromPaging(VOID)
VOID InitGlobalDescriptorTable(VOID)
EFI_STATUS EFIAPI EfiGetSystemConfigurationTable(IN EFI_GUID *TableGuid, OUT VOID **Table)
VOID EFIAPI AsmReadIdtr(OUT IA32_DESCRIPTOR *Idtr)
VOID EFIAPI AsmWriteIdtr(IN CONST IA32_DESCRIPTOR *Idtr)
EFI_GCD_MEMORY_TYPE GcdMemoryType
EFI_PHYSICAL_ADDRESS BaseAddress
struct CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX::@646 Bits
struct CPUID_VIR_PHY_ADDRESS_SIZE_EAX::@690 Bits
UINT32 PhysicalAddressBits
struct MSR_IA32_TME_ACTIVATE_REGISTER::@617 Bits