X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=UefiCpuPkg%2FCpuDxe%2FCpuDxe.c;h=c9df4e146ac37d9c1424e7a7e4becdb9381bc01a;hp=10ad86da7524d99006cbe5614cf01dd48a843a5c;hb=6022e28cf744a885c278dad256d50670741ea123;hpb=4ec21e8b50845e0a89a8d93f3909e4522ee6b434 diff --git a/UefiCpuPkg/CpuDxe/CpuDxe.c b/UefiCpuPkg/CpuDxe/CpuDxe.c index 10ad86da75..c9df4e146a 100644 --- a/UefiCpuPkg/CpuDxe/CpuDxe.c +++ b/UefiCpuPkg/CpuDxe/CpuDxe.c @@ -1,7 +1,7 @@ /** @file CPU DXE Module. - Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -13,17 +13,14 @@ **/ #include "CpuDxe.h" +#include "CpuMp.h" // // Global Variables // -IA32_IDT_GATE_DESCRIPTOR gIdtTable[INTERRUPT_VECTOR_NUMBER] = { 0 }; - -EFI_CPU_INTERRUPT_HANDLER ExternalVectorTable[0x100]; BOOLEAN InterruptState = FALSE; EFI_HANDLE mCpuHandle = NULL; BOOLEAN mIsFlushingGCD; -UINT8 mDefaultMemoryType = MTRR_CACHE_WRITE_BACK; UINT64 mValidMtrrAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS; UINT64 mValidMtrrBitsMask = MTRR_LIB_MSR_VALID_MASK; @@ -99,259 +96,10 @@ EFI_CPU_ARCH_PROTOCOL gCpu = { 4 // DmaBufferAlignment }; -// -// Error code flag indicating whether or not an error code will be -// pushed on the stack if an exception occurs. -// -// 1 means an error code will be pushed, otherwise 0 -// -// bit 0 - exception 0 -// bit 1 - exception 1 -// etc. -// -UINT32 mErrorCodeFlag = 0x00027d00; - -// -// Local function prototypes -// - -/** - Set Interrupt Descriptor Table Handler Address. - - @param Index The Index of the interrupt descriptor table handle. - @param Handler Handler address. - -**/ -VOID -SetInterruptDescriptorTableHandlerAddress ( - IN UINTN Index, - IN VOID *Handler OPTIONAL - ); - // // CPU Arch Protocol Functions // - -/** - Common exception handler. - - @param InterruptType Exception type - @param SystemContext EFI_SYSTEM_CONTEXT - -**/ -VOID -EFIAPI -CommonExceptionHandler ( - IN EFI_EXCEPTION_TYPE InterruptType, - IN EFI_SYSTEM_CONTEXT SystemContext - ) -{ -#if defined (MDE_CPU_IA32) - DEBUG (( - EFI_D_ERROR, - "!!!! IA32 Exception Type - %08x !!!!\n", - InterruptType - )); - if ((mErrorCodeFlag & (1 << InterruptType)) != 0) { - DEBUG (( - EFI_D_ERROR, - "ExceptionData - %08x\n", - SystemContext.SystemContextIa32->ExceptionData - )); - } - DEBUG (( - EFI_D_ERROR, - "CS - %04x, EIP - %08x, EFL - %08x, SS - %04x\n", - SystemContext.SystemContextIa32->Cs, - SystemContext.SystemContextIa32->Eip, - SystemContext.SystemContextIa32->Eflags, - SystemContext.SystemContextIa32->Ss - )); - DEBUG (( - EFI_D_ERROR, - "DS - %04x, ES - %04x, FS - %04x, GS - %04x\n", - SystemContext.SystemContextIa32->Ds, - SystemContext.SystemContextIa32->Es, - SystemContext.SystemContextIa32->Fs, - SystemContext.SystemContextIa32->Gs - )); - DEBUG (( - EFI_D_ERROR, - "EAX - %08x, EBX - %08x, ECX - %08x, EDX - %08x\n", - SystemContext.SystemContextIa32->Eax, - SystemContext.SystemContextIa32->Ebx, - SystemContext.SystemContextIa32->Ecx, - SystemContext.SystemContextIa32->Edx - )); - DEBUG (( - EFI_D_ERROR, - "ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n", - SystemContext.SystemContextIa32->Esp, - SystemContext.SystemContextIa32->Ebp, - SystemContext.SystemContextIa32->Esi, - SystemContext.SystemContextIa32->Edi - )); - DEBUG (( - EFI_D_ERROR, - "GDT - %08x LIM - %04x, IDT - %08x LIM - %04x\n", - SystemContext.SystemContextIa32->Gdtr[0], - SystemContext.SystemContextIa32->Gdtr[1], - SystemContext.SystemContextIa32->Idtr[0], - SystemContext.SystemContextIa32->Idtr[1] - )); - DEBUG (( - EFI_D_ERROR, - "LDT - %08x, TR - %08x\n", - SystemContext.SystemContextIa32->Ldtr, - SystemContext.SystemContextIa32->Tr - )); - DEBUG (( - EFI_D_ERROR, - "CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n", - SystemContext.SystemContextIa32->Cr0, - SystemContext.SystemContextIa32->Cr2, - SystemContext.SystemContextIa32->Cr3, - SystemContext.SystemContextIa32->Cr4 - )); - DEBUG (( - EFI_D_ERROR, - "DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n", - SystemContext.SystemContextIa32->Dr0, - SystemContext.SystemContextIa32->Dr1, - SystemContext.SystemContextIa32->Dr2, - SystemContext.SystemContextIa32->Dr3 - )); - DEBUG (( - EFI_D_ERROR, - "DR6 - %08x, DR7 - %08x\n", - SystemContext.SystemContextIa32->Dr6, - SystemContext.SystemContextIa32->Dr7 - )); -#elif defined (MDE_CPU_X64) - DEBUG (( - EFI_D_ERROR, - "!!!! X64 Exception Type - %016lx !!!!\n", - (UINT64)InterruptType - )); - if ((mErrorCodeFlag & (1 << InterruptType)) != 0) { - DEBUG (( - EFI_D_ERROR, - "ExceptionData - %016lx\n", - SystemContext.SystemContextX64->ExceptionData - )); - } - DEBUG (( - EFI_D_ERROR, - "RIP - %016lx, RFL - %016lx\n", - SystemContext.SystemContextX64->Rip, - SystemContext.SystemContextX64->Rflags - )); - DEBUG (( - EFI_D_ERROR, - "RAX - %016lx, RCX - %016lx, RDX - %016lx\n", - SystemContext.SystemContextX64->Rax, - SystemContext.SystemContextX64->Rcx, - SystemContext.SystemContextX64->Rdx - )); - DEBUG (( - EFI_D_ERROR, - "RBX - %016lx, RSP - %016lx, RBP - %016lx\n", - SystemContext.SystemContextX64->Rbx, - SystemContext.SystemContextX64->Rsp, - SystemContext.SystemContextX64->Rbp - )); - DEBUG (( - EFI_D_ERROR, - "RSI - %016lx, RDI - %016lx\n", - SystemContext.SystemContextX64->Rsi, - SystemContext.SystemContextX64->Rdi - )); - DEBUG (( - EFI_D_ERROR, - "R8 - %016lx, R9 - %016lx, R10 - %016lx\n", - SystemContext.SystemContextX64->R8, - SystemContext.SystemContextX64->R9, - SystemContext.SystemContextX64->R10 - )); - DEBUG (( - EFI_D_ERROR, - "R11 - %016lx, R12 - %016lx, R13 - %016lx\n", - SystemContext.SystemContextX64->R11, - SystemContext.SystemContextX64->R12, - SystemContext.SystemContextX64->R13 - )); - DEBUG (( - EFI_D_ERROR, - "R14 - %016lx, R15 - %016lx\n", - SystemContext.SystemContextX64->R14, - SystemContext.SystemContextX64->R15 - )); - DEBUG (( - EFI_D_ERROR, - "CS - %04lx, DS - %04lx, ES - %04lx, FS - %04lx, GS - %04lx, SS - %04lx\n", - SystemContext.SystemContextX64->Cs, - SystemContext.SystemContextX64->Ds, - SystemContext.SystemContextX64->Es, - SystemContext.SystemContextX64->Fs, - SystemContext.SystemContextX64->Gs, - SystemContext.SystemContextX64->Ss - )); - DEBUG (( - EFI_D_ERROR, - "GDT - %016lx; %04lx, IDT - %016lx; %04lx\n", - SystemContext.SystemContextX64->Gdtr[0], - SystemContext.SystemContextX64->Gdtr[1], - SystemContext.SystemContextX64->Idtr[0], - SystemContext.SystemContextX64->Idtr[1] - )); - DEBUG (( - EFI_D_ERROR, - "LDT - %016lx, TR - %016lx\n", - SystemContext.SystemContextX64->Ldtr, - SystemContext.SystemContextX64->Tr - )); - DEBUG (( - EFI_D_ERROR, - "CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n", - SystemContext.SystemContextX64->Cr0, - SystemContext.SystemContextX64->Cr2, - SystemContext.SystemContextX64->Cr3 - )); - DEBUG (( - EFI_D_ERROR, - "CR4 - %016lx, CR8 - %016lx\n", - SystemContext.SystemContextX64->Cr4, - SystemContext.SystemContextX64->Cr8 - )); - DEBUG (( - EFI_D_ERROR, - "DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n", - SystemContext.SystemContextX64->Dr0, - SystemContext.SystemContextX64->Dr1, - SystemContext.SystemContextX64->Dr2 - )); - DEBUG (( - EFI_D_ERROR, - "DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n", - SystemContext.SystemContextX64->Dr3, - SystemContext.SystemContextX64->Dr6, - SystemContext.SystemContextX64->Dr7 - )); -#else -#error CPU type not supported for exception information dump! -#endif - - // - // Hang the system with CpuSleep so the processor will enter a lower power - // state. - // - while (TRUE) { - CpuSleep (); - }; -} - - /** Flush CPU data cache. If the instruction cache is fully coherent with all DMA operations then function can just return EFI_SUCCESS. @@ -509,21 +257,7 @@ CpuRegisterInterruptHandler ( IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler ) { - if (InterruptType < 0 || InterruptType > 0xff) { - return EFI_UNSUPPORTED; - } - - if (InterruptHandler == NULL && ExternalVectorTable[InterruptType] == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (InterruptHandler != NULL && ExternalVectorTable[InterruptType] != NULL) { - return EFI_ALREADY_STARTED; - } - - SetInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType, NULL); - ExternalVectorTable[InterruptType] = InterruptHandler; - return EFI_SUCCESS; + return RegisterCpuInterruptHandler (InterruptType, InterruptHandler); } @@ -628,9 +362,9 @@ CpuSetMemoryAttributes ( // to avoid unnecessary computing. // if (mIsFlushingGCD) { - DEBUG((EFI_D_ERROR, " Flushing GCD\n")); - return EFI_SUCCESS; - } + DEBUG((EFI_D_INFO, " Flushing GCD\n")); + return EFI_SUCCESS; + } switch (Attributes) { case EFI_MEMORY_UC: @@ -887,6 +621,7 @@ RefreshGcdMemoryAttributes ( VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR]; MTRR_FIXED_SETTINGS MtrrFixedSettings; UINT32 FirmwareVariableMtrrCount; + UINT8 DefaultMemoryType; if (!IsMtrrSupported ()) { return; @@ -895,8 +630,7 @@ RefreshGcdMemoryAttributes ( FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount (); ASSERT (FirmwareVariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR); -// mIsFlushingGCD = TRUE; - mIsFlushingGCD = FALSE; + mIsFlushingGCD = TRUE; MemorySpaceMap = NULL; // @@ -922,7 +656,8 @@ RefreshGcdMemoryAttributes ( ); ASSERT_EFI_ERROR (Status); - DefaultAttributes = GetMemorySpaceAttributeFromMtrrType (mDefaultMemoryType); + DefaultMemoryType = (UINT8) MtrrGetDefaultMemoryType (); + DefaultAttributes = GetMemorySpaceAttributeFromMtrrType (DefaultMemoryType); // // Set default attributes to all spaces. @@ -954,12 +689,14 @@ RefreshGcdMemoryAttributes ( ); } } + // - // Go for variable MTRRs with Non-WB attribute + // Go for variable MTRRs with the attribute except for WB and UC attributes // for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) { if (VariableMtrr[Index].Valid && - VariableMtrr[Index].Type != MTRR_CACHE_WRITE_BACK) { + VariableMtrr[Index].Type != MTRR_CACHE_WRITE_BACK && + VariableMtrr[Index].Type != MTRR_CACHE_UNCACHEABLE) { Attributes = GetMemorySpaceAttributeFromMtrrType ((UINT8) VariableMtrr[Index].Type); SetGcdMemorySpaceAttributes ( MemorySpaceMap, @@ -971,6 +708,22 @@ RefreshGcdMemoryAttributes ( } } + // + // Go for variable MTRRs with UC attribute + // + for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) { + if (VariableMtrr[Index].Valid && + VariableMtrr[Index].Type == MTRR_CACHE_UNCACHEABLE) { + SetGcdMemorySpaceAttributes ( + MemorySpaceMap, + NumberOfDescriptors, + VariableMtrr[Index].BaseAddress, + VariableMtrr[Index].Length, + EFI_MEMORY_UC + ); + } + } + // // Go for fixed MTRRs // @@ -1033,124 +786,44 @@ RefreshGcdMemoryAttributes ( } /** - Set Interrupt Descriptor Table Handler Address. - - @param Index The Index of the interrupt descriptor table handle. - @param Handler Handler address. + Initialize Interrupt Descriptor Table for interrupt handling. **/ VOID -SetInterruptDescriptorTableHandlerAddress ( - IN UINTN Index, - IN VOID *Handler OPTIONAL +InitInterruptDescriptorTable ( + VOID ) { - UINTN UintnHandler; - - if (Handler != NULL) { - UintnHandler = (UINTN) Handler; - } else { - UintnHandler = ((UINTN) AsmIdtVector00) + (8 * Index); + EFI_STATUS Status; + EFI_VECTOR_HANDOFF_INFO *VectorInfoList; + EFI_VECTOR_HANDOFF_INFO *VectorInfo; + + VectorInfo = NULL; + Status = EfiGetSystemConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID **) &VectorInfoList); + if (Status == EFI_SUCCESS && VectorInfoList != NULL) { + VectorInfo = VectorInfoList; } - - gIdtTable[Index].Bits.OffsetLow = (UINT16)UintnHandler; - gIdtTable[Index].Bits.Reserved_0 = 0; - gIdtTable[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; - gIdtTable[Index].Bits.OffsetHigh = (UINT16)(UintnHandler >> 16); -#if defined (MDE_CPU_X64) - gIdtTable[Index].Bits.OffsetUpper = (UINT32)(UintnHandler >> 32); - gIdtTable[Index].Bits.Reserved_1 = 0; -#endif + Status = InitializeCpuInterruptHandlers (VectorInfo); + ASSERT_EFI_ERROR (Status); } /** - Initialize Interrupt Descriptor Table for interrupt handling. + Callback function for idle events. + + @param Event Event whose notification function is being invoked. + @param Context The pointer to the notification function's context, + which is implementation-dependent. **/ VOID -InitInterruptDescriptorTable ( - VOID +EFIAPI +IdleLoopEventCallback ( + IN EFI_EVENT Event, + IN VOID *Context ) { - EFI_STATUS Status; - IA32_DESCRIPTOR OldIdtPtr; - IA32_IDT_GATE_DESCRIPTOR *OldIdt; - UINTN OldIdtSize; - VOID *IdtPtrAlignmentBuffer; - IA32_DESCRIPTOR *IdtPtr; - UINTN Index; - UINT16 CurrentCs; - VOID *IntHandler; - - SetMem (ExternalVectorTable, sizeof(ExternalVectorTable), 0); - - // - // Get original IDT address and size. - // - AsmReadIdtr ((IA32_DESCRIPTOR *) &OldIdtPtr); - - if ((OldIdtPtr.Base != 0) && ((OldIdtPtr.Limit & 7) == 7)) { - OldIdt = (IA32_IDT_GATE_DESCRIPTOR*) OldIdtPtr.Base; - OldIdtSize = (OldIdtPtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR); - } else { - OldIdt = NULL; - OldIdtSize = 0; - } - - // - // Intialize IDT - // - CurrentCs = AsmReadCs(); - for (Index = 0; Index < INTERRUPT_VECTOR_NUMBER; Index ++) { - // - // If the old IDT had a handler for this interrupt, then - // preserve it. - // - if (Index < OldIdtSize) { - IntHandler = - (VOID*) ( - OldIdt[Index].Bits.OffsetLow + - (OldIdt[Index].Bits.OffsetHigh << 16) -#if defined (MDE_CPU_X64) - + (((UINTN) OldIdt[Index].Bits.OffsetUpper) << 32) -#endif - ); - } else { - IntHandler = NULL; - } - - gIdtTable[Index].Bits.Selector = CurrentCs; - gIdtTable[Index].Bits.Reserved_0 = 0; - gIdtTable[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; - SetInterruptDescriptorTableHandlerAddress (Index, IntHandler); - } - - // - // Load IDT Pointer - // - IdtPtrAlignmentBuffer = AllocatePool (sizeof (*IdtPtr) + 16); - IdtPtr = ALIGN_POINTER (IdtPtrAlignmentBuffer, 16); - IdtPtr->Base = (UINT32)(((UINTN)(VOID*) gIdtTable) & (BASE_4GB-1)); - IdtPtr->Limit = (UINT16) (sizeof (gIdtTable) - 1); - - AsmWriteIdtr (IdtPtr); - - FreePool (IdtPtrAlignmentBuffer); - - // - // Initialize Exception Handlers - // - for (Index = 0; Index < 32; Index++) { - Status = CpuRegisterInterruptHandler (&gCpu, Index, CommonExceptionHandler); - ASSERT_EFI_ERROR (Status); - } - - // - // Set the pointer to the array of C based exception handling routines. - // - InitializeExternalVectorTablePtr (ExternalVectorTable); - + CpuSleep (); } @@ -1173,6 +846,9 @@ InitializeCpu ( ) { EFI_STATUS Status; + EFI_EVENT IdleLoopEvent; + + InitializeFloatingPointUnits (); // // Make sure interrupts are disabled @@ -1189,6 +865,11 @@ InitializeCpu ( // InitInterruptDescriptorTable (); + // + // Enable the local APIC for Virtual Wire Mode. + // + ProgramVirtualWireMode (); + // // Install CPU Architectural Protocol // @@ -1204,6 +885,21 @@ InitializeCpu ( // RefreshGcdMemoryAttributes (); + // + // Setup a callback for idle events + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + IdleLoopEventCallback, + NULL, + &gIdleLoopEventGuid, + &IdleLoopEvent + ); + ASSERT_EFI_ERROR (Status); + + InitializeMpSupport (); + return Status; }