13#define CPU_INTERRUPT_NUM 256
18BOOLEAN InterruptState =
FALSE;
20BOOLEAN mIsFlushingGCD;
21BOOLEAN mIsAllocatingPageTable =
FALSE;
22UINT64 mValidMtrrAddressMask;
23UINT64 mValidMtrrBitsMask;
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;
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) {
317 EndValue - BeginValue,
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 (
485 if (EFI_ERROR (Status)) {
509 UINT8 PhysicalAddressBits;
513 if (RegEax >= 0x80000008) {
516 PhysicalAddressBits = (UINT8)RegEax;
518 PhysicalAddressBits = 36;
521 mValidMtrrBitsMask =
LShiftU64 (1, PhysicalAddressBits) - 1;
522 mValidMtrrAddressMask = mValidMtrrBitsMask & 0xfffffffffffff000ULL;
537 IN UINT8 MtrrAttributes
540 switch (MtrrAttributes) {
541 case MTRR_CACHE_UNCACHEABLE:
542 return EFI_MEMORY_UC;
543 case MTRR_CACHE_WRITE_COMBINING:
544 return EFI_MEMORY_WC;
545 case MTRR_CACHE_WRITE_THROUGH:
546 return EFI_MEMORY_WT;
547 case MTRR_CACHE_WRITE_PROTECTED:
548 return EFI_MEMORY_WP;
549 case MTRR_CACHE_WRITE_BACK:
550 return EFI_MEMORY_WB;
588 for (Index = 0; Index < NumberOfDescriptors; Index++) {
589 if ((BaseAddress >= MemorySpaceMap[Index].BaseAddress) &&
590 (BaseAddress < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length))
595 if ((BaseAddress + Length - 1 >= MemorySpaceMap[Index].BaseAddress) &&
596 (BaseAddress + Length - 1 < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length))
603 return EFI_NOT_FOUND;
649 if (EFI_ERROR (Status)) {
656 for (Index = StartIndex; Index <= EndIndex; Index++) {
664 if (BaseAddress >= MemorySpaceMap[Index].BaseAddress) {
665 RegionStart = BaseAddress;
667 RegionStart = MemorySpaceMap[Index].BaseAddress;
670 if (BaseAddress + Length - 1 < MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length) {
671 RegionLength = BaseAddress + Length - RegionStart;
673 RegionLength = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - RegionStart;
679 gDS->SetMemorySpaceAttributes (
682 (MemorySpaceMap[Index].Attributes & ~EFI_CACHE_ATTRIBUTE_MASK) | (MemorySpaceMap[Index].Capabilities & Attributes)
707 UINT64 CurrentAttributes;
709 UINTN NumberOfDescriptors;
711 UINT64 DefaultAttributes;
714 UINT32 FirmwareVariableMtrrCount;
715 UINT8 DefaultMemoryType;
718 ASSERT (FirmwareVariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
720 MemorySpaceMap =
NULL;
732 mValidMtrrAddressMask,
739 Status =
gDS->GetMemorySpaceMap (
740 &NumberOfDescriptors,
751 for (Index = 0; Index < NumberOfDescriptors; Index++) {
756 gDS->SetMemorySpaceAttributes (
757 MemorySpaceMap[Index].BaseAddress,
758 MemorySpaceMap[Index].Length,
759 (MemorySpaceMap[Index].Attributes & ~EFI_CACHE_ATTRIBUTE_MASK) |
760 (MemorySpaceMap[Index].Capabilities & DefaultAttributes)
767 for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {
768 if (VariableMtrr[Index].Valid &&
769 (VariableMtrr[Index].Type == MTRR_CACHE_WRITE_BACK))
774 VariableMtrr[Index].BaseAddress,
775 VariableMtrr[Index].Length,
784 for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {
785 if (VariableMtrr[Index].Valid &&
786 (VariableMtrr[Index].Type != MTRR_CACHE_WRITE_BACK) &&
787 (VariableMtrr[Index].Type != MTRR_CACHE_UNCACHEABLE))
793 VariableMtrr[Index].BaseAddress,
794 VariableMtrr[Index].Length,
803 for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {
804 if (VariableMtrr[Index].Valid &&
805 (VariableMtrr[Index].Type == MTRR_CACHE_UNCACHEABLE))
810 VariableMtrr[Index].BaseAddress,
811 VariableMtrr[Index].Length,
824 for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
825 RegValue = MtrrFixedSettings.Mtrr[Index];
829 for (SubIndex = 0; SubIndex < 8; SubIndex++) {
830 MtrrType = (UINT8)
RShiftU64 (RegValue, SubIndex * 8);
836 Attributes = CurrentAttributes;
841 if (CurrentAttributes != Attributes) {
849 BaseAddress = mFixedMtrrTable[Index].BaseAddress + mFixedMtrrTable[Index].Length * SubIndex;
851 Attributes = CurrentAttributes;
855 Length += mFixedMtrrTable[Index].Length;
873 if (MemorySpaceMap !=
NULL) {
892 return ((Cr0.Bits.PG != 0) && (Cr4.Bits.PAE != 0));
907 mIsFlushingGCD =
TRUE;
917 mIsFlushingGCD =
FALSE;
932 IA32_IDT_GATE_DESCRIPTOR *IdtTable;
933 IA32_DESCRIPTOR IdtDescriptor;
939 VectorInfo = VectorInfoList;
943 IdtEntryCount = (IdtDescriptor.Limit + 1) /
sizeof (IA32_IDT_GATE_DESCRIPTOR);
944 if (IdtEntryCount < CPU_INTERRUPT_NUM) {
948 IdtTable =
AllocateZeroPool (
sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM);
950 CopyMem (IdtTable, (VOID *)IdtDescriptor.Base, sizeof (IA32_IDT_GATE_DESCRIPTOR) * IdtEntryCount);
955 IdtDescriptor.Base = (
UINTN)IdtTable;
956 IdtDescriptor.Limit = (UINT16)(
sizeof (IA32_IDT_GATE_DESCRIPTOR) * CPU_INTERRUPT_NUM - 1);
1025 IN UINT64 Capabilities,
1029 UINT64 IntersectionBase;
1030 UINT64 IntersectionEnd;
1034 ((Descriptor->Capabilities & Capabilities) == Capabilities))
1039 IntersectionBase =
MAX (Base, Descriptor->BaseAddress);
1040 IntersectionEnd =
MIN (
1042 Descriptor->BaseAddress + Descriptor->Length
1044 if (IntersectionBase >= IntersectionEnd) {
1052 Status =
gDS->AddMemorySpace (
1055 IntersectionEnd - IntersectionBase,
1060 EFI_ERROR (Status) ? DEBUG_ERROR : DEBUG_VERBOSE,
1061 "%a: %a: add [%Lx, %Lx): %r\n",
1073 "%a: %a: desc [%Lx, %Lx) type %u cap %Lx conflicts "
1074 "with aperture [%Lx, %Lx) cap %Lx\n",
1077 Descriptor->BaseAddress,
1078 Descriptor->BaseAddress + Descriptor->Length,
1079 (UINT32)Descriptor->GcdMemoryType,
1080 Descriptor->Capabilities,
1085 return EFI_INVALID_PARAMETER;
1103 IN UINT64 Capabilities
1108 UINTN NumberOfDescriptors;
1111 Status =
gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
1112 if (EFI_ERROR (Status)) {
1115 "%a: %a: GetMemorySpaceMap(): %r\n",
1123 for (Index = 0; Index < NumberOfDescriptors; Index++) {
1128 &MemorySpaceMap[Index]
1130 if (EFI_ERROR (Status)) {
1131 goto FreeMemorySpaceMap;
1145 for (CheckBase = Base;
1146 CheckBase < Base + Length;
1149 CheckStatus =
gDS->GetMemorySpaceDescriptor (CheckBase, &Descriptor);
1186 Status =
gDS->AllocateMemorySpace (
1195 if (EFI_ERROR (Status)) {
1198 "%a: %a: AllocateMemorySpace() Status - %r\n",
1249 Status =
gBS->InstallMultipleProtocolInterfaces (
1251 &gEfiCpuArchProtocolGuid,
1270 Status =
gBS->CreateEventEx (
1275 &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)
#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)
EFI_STATUS EFIAPI InitializeCpuExceptionHandlers(IN EFI_VECTOR_HANDOFF_INFO *VectorInfo OPTIONAL)
EFI_STATUS EFIAPI RegisterCpuInterruptHandler(IN EFI_EXCEPTION_TYPE InterruptType, IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler)
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)
#define ASSERT(Expression)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID EFIAPI AsmInvd(VOID)
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_MTRR_FIX4K_D8000
#define MSR_IA32_MTRR_FIX4K_C0000
#define MSR_IA32_MTRR_FIX4K_F0000
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
VOID EFIAPI InitializeFloatingPointUnits(VOID)
EFI_STATUS EFIAPI CpuSetMemoryAttributes(IN EFI_CPU_ARCH_PROTOCOL *This, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
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